@oktis-works/admin 0.20.0 → 0.23.2

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 (114) hide show
  1. package/dist/client/_astro/{ActivityWidget.DtG_8-bC.js → ActivityWidget.Dzoi-bq3.js} +1 -1
  2. package/dist/client/_astro/{AdminBar.DWgISuE1.js → AdminBar.eT1ch_B6.js} +1 -1
  3. package/dist/client/_astro/{ApiKeysManager.9WL8yofB.js → ApiKeysManager.kbTE1CPk.js} +1 -1
  4. package/dist/client/_astro/{AtGlanceWidget.B5byv-Z6.js → AtGlanceWidget.w23IIv06.js} +1 -1
  5. package/dist/client/_astro/{BaseLayout.Dw2OoSEv.css → BaseLayout.Rpr86VwM.css} +1 -1
  6. package/dist/client/_astro/{CommentsManager.C5gleTZN.js → CommentsManager.BN7i1RHa.js} +1 -1
  7. package/dist/client/_astro/ContentEditor.BlsJ2bwD.js +1 -0
  8. package/dist/client/_astro/{ContentTypeWorkspace.wFn1FHsk.js → ContentTypeWorkspace.BPVuQgzA.js} +1 -1
  9. package/dist/client/_astro/{DashboardHome.CoVmaWtV.js → DashboardHome.DXzu_IXZ.js} +1 -1
  10. package/dist/client/_astro/{DashboardLayout.astro_astro_type_script_index_0_lang.BEDbOjeH.js → DashboardLayout.astro_astro_type_script_index_0_lang.DmNSzErX.js} +1 -1
  11. package/dist/client/_astro/{FieldGroupEditor.DixyIeAD.js → FieldGroupEditor.DsqphEgt.js} +1 -1
  12. package/dist/client/_astro/{FieldGroupList.KCRsCtjN.js → FieldGroupList.pW2Um9om.js} +1 -1
  13. package/dist/client/_astro/FieldRenderer.AYtSBfHZ.js +3 -0
  14. package/dist/client/_astro/{Footer.Bis7kk52.js → Footer.5Lcn2VXz.js} +1 -1
  15. package/dist/client/_astro/{GeneralSettings.DWUL4EPc.js → GeneralSettings.B-H8Rzy7.js} +1 -1
  16. package/dist/client/_astro/{LogsManager.wobqWCrD.js → LogsManager.Crd8q2te.js} +1 -1
  17. package/dist/client/_astro/{MediaLibrary.B_DxFMQi.js → MediaLibrary.Cv6Ry3u9.js} +1 -1
  18. package/dist/client/_astro/{MenuManager.CB6j6yQw.js → MenuManager.D25ika09.js} +1 -1
  19. package/dist/client/_astro/{Modal.eJIvbMT2.js → Modal.572hmVvb.js} +1 -1
  20. package/dist/client/_astro/{PluginManager.CT-7t4Wz.js → PluginManager.DLfgQFPF.js} +1 -1
  21. package/dist/client/_astro/{PostTypesManager.LW5RMORG.js → PostTypesManager.C3RbmOZT.js} +1 -1
  22. package/dist/client/_astro/{QuickDraftWidget.zabr8JfM.js → QuickDraftWidget.BtSGzhKq.js} +1 -1
  23. package/dist/client/_astro/{ReadingSettings.BiSPyKOf.js → ReadingSettings.ZFDaeo5U.js} +1 -1
  24. package/dist/client/_astro/{ResourceHubs.CmV4Mz6z.js → ResourceHubs.Cx9fbCv1.js} +1 -1
  25. package/dist/client/_astro/{TaxonomiesManager.BzFfeZEj.js → TaxonomiesManager.BLsvmjaL.js} +1 -1
  26. package/dist/client/_astro/TaxonomyTermsManager.C_xEh8Ab.js +1 -0
  27. package/dist/client/_astro/ThemeCustomizer.BrDHVXLk.js +577 -0
  28. package/dist/client/_astro/{ThemeManager.BVqp2Bk3.js → ThemeManager.BpS3m7Qc.js} +2 -2
  29. package/dist/client/_astro/{UserCreateForm.D2dkK0S5.js → UserCreateForm.BYwgAqKk.js} +1 -1
  30. package/dist/client/_astro/{UsersManager.CUU4ncDR.js → UsersManager.DODMr48D.js} +1 -1
  31. package/dist/client/_astro/{WebhooksManager.DV2TWIOt.js → WebhooksManager.DmWIW272.js} +1 -1
  32. package/dist/client/_astro/ar.BCtMLfbL.js +1 -0
  33. package/dist/client/_astro/clone.oDfZEkVn.js +1 -0
  34. package/dist/client/_astro/es-ES.BfYd3kCv.js +1 -0
  35. package/dist/client/_astro/he.pQFPO6hc.js +1 -0
  36. package/dist/client/_astro/{i18n.BFBHzd3w.js → i18n.A82w5XQu.js} +1 -1
  37. package/dist/client/_astro/it.ZpeUogpB.js +1 -0
  38. package/dist/client/_astro/ja.Ch5X4gaR.js +1 -0
  39. package/dist/client/_astro/pl.DDgkAPXr.js +1 -0
  40. package/dist/client/_astro/{pt-BR.DB_qjzov.js → pt-BR.zZcF2v3X.js} +1 -1
  41. package/dist/client/_astro/ru.CAjJz8Cj.js +1 -0
  42. package/dist/client/_astro/sw.CehAEkRN.js +1 -0
  43. package/dist/client/_astro/tr.Sf1XkPHa.js +1 -0
  44. package/dist/client/_astro/uk.-2u2eOOq.js +1 -0
  45. package/dist/client/_astro/yo.os9m69tq.js +1 -0
  46. package/dist/client/_astro/zh-CN.Bt1lpQQu.js +1 -0
  47. package/dist/server/chunks/{404_BMps-rRP.mjs → 404_BAOD9OCa.mjs} +1 -1
  48. package/dist/server/chunks/{BaseLayout_eq-iwg5V.mjs → BaseLayout_BE8O-LS4.mjs} +2 -2
  49. package/dist/server/chunks/{ContentEditor_CD80dY0I.mjs → ContentEditor_DPy3I4HM.mjs} +4 -3
  50. package/dist/server/chunks/{DashboardLayout_CrO_yWkB.mjs → DashboardLayout_D6zphdT0.mjs} +2 -2
  51. package/dist/server/chunks/{FieldRenderer_BSvrsqN8.mjs → FieldRenderer_D4dcZjgt.mjs} +3 -61
  52. package/dist/server/chunks/{MediaLibrary_BGZEgsua.mjs → MediaLibrary_DGmYSSZH.mjs} +2 -2
  53. package/dist/server/chunks/{Modal_QxIjzTdp.mjs → Modal_BmuvdwoB.mjs} +1 -1
  54. package/dist/server/chunks/{_id__BIPcYNtN.mjs → _id__XEnJ5nS2.mjs} +2 -2
  55. package/dist/server/chunks/{_slug__XNFTP0Q1.mjs → _slug__BkXrukGe.mjs} +1 -1
  56. package/dist/server/chunks/{access_D-_mBK3K.mjs → access_B5npG273.mjs} +3 -3
  57. package/dist/server/chunks/{api-keys_z4-GVRaL.mjs → api-keys_Bs6zIXYm.mjs} +3 -3
  58. package/dist/server/chunks/{ar_DObFFdrO.mjs → ar_Cgz1nkYN.mjs} +30 -3
  59. package/dist/server/chunks/clone_FT3Zf-Bf.mjs +59 -0
  60. package/dist/server/chunks/{comments_qCxr0Y8w.mjs → comments_zJrnFEjl.mjs} +2 -2
  61. package/dist/server/chunks/{custom-fields_Dp3OiD0S.mjs → custom-fields_C5EBkR02.mjs} +2 -2
  62. package/dist/server/chunks/customize_CKqMX14y.mjs +1629 -0
  63. package/dist/server/chunks/{edit_BxXS3NT6.mjs → edit_QKBYgFkJ.mjs} +2 -2
  64. package/dist/server/chunks/{es-ES_D6jd6T7H.mjs → es-ES_Bw0g3h9x.mjs} +30 -3
  65. package/dist/server/chunks/{he_DwGJwonL.mjs → he_BcJYW2q8.mjs} +30 -3
  66. package/dist/server/chunks/{i18n_jhv_lr6z.mjs → i18n_C-sgJSi1.mjs} +14 -13
  67. package/dist/server/chunks/{index_tQk65WtE.mjs → index_BM_-WBYo.mjs} +2 -2
  68. package/dist/server/chunks/{index_aa5_ET2K.mjs → index_BletZ9T6.mjs} +3 -3
  69. package/dist/server/chunks/{index_BuUzsa32.mjs → index_Btvmuytk.mjs} +2 -2
  70. package/dist/server/chunks/{index_CaR204jg.mjs → index_CDwohy44.mjs} +2 -2
  71. package/dist/server/chunks/{index_DVQd057F.mjs → index_DenKi4a3.mjs} +2 -2
  72. package/dist/server/chunks/{it_CMLpQyoj.mjs → it_CgOxhoxy.mjs} +30 -3
  73. package/dist/server/chunks/{ja_CYRz0pHv.mjs → ja_0swn1wUm.mjs} +30 -3
  74. package/dist/server/chunks/{login_JwlFuBYd.mjs → login_CtIWLqC2.mjs} +1 -1
  75. package/dist/server/chunks/{logs_td2w_HCW.mjs → logs_DlTldv5b.mjs} +2 -2
  76. package/dist/server/chunks/{menus_Brbqh27T.mjs → menus_z2d_K44p.mjs} +2 -2
  77. package/dist/server/chunks/{new_aklFjYkE.mjs → new_CYvLScge.mjs} +2 -2
  78. package/dist/server/chunks/{new_M5jNG81S.mjs → new_Cxp8Mdw4.mjs} +2 -2
  79. package/dist/server/chunks/{pl_BuXVPvU1.mjs → pl_eLBKfEwP.mjs} +30 -3
  80. package/dist/server/chunks/{plugins_KhcXhLHj.mjs → plugins_4g6EEkCb.mjs} +2 -2
  81. package/dist/server/chunks/{post-types_DD3nerIE.mjs → post-types_7cW4BLBV.mjs} +2 -2
  82. package/dist/server/chunks/{pt-BR_Barbcx-V.mjs → pt-BR_AVNE88MZ.mjs} +1 -0
  83. package/dist/server/chunks/{reading_ghF5feXj.mjs → reading_2DqfBhj_.mjs} +2 -2
  84. package/dist/server/chunks/{ru_C56ltukG.mjs → ru_Dt3fMzac.mjs} +30 -3
  85. package/dist/server/chunks/{sw_Dhw0GAgD.mjs → sw_oPyQwKSK.mjs} +30 -3
  86. package/dist/server/chunks/{taxonomies_CsUEhmvC.mjs → taxonomies_D7mMKpNX.mjs} +2 -2
  87. package/dist/server/chunks/{taxonomy_BfNm0HUh.mjs → taxonomy_64ggDTF9.mjs} +4 -3
  88. package/dist/server/chunks/{themes_DnFB-Bio.mjs → themes_Dscq-5uk.mjs} +6 -4
  89. package/dist/server/chunks/{tr_zELRy7A-.mjs → tr_DG1ipiJ0.mjs} +30 -3
  90. package/dist/server/chunks/{uk_DVOqp1x6.mjs → uk_DCWgX6k4.mjs} +30 -3
  91. package/dist/server/chunks/{upload_D5xS-Nri.mjs → upload_B-DdqpaQ.mjs} +2 -2
  92. package/dist/server/chunks/{webhooks_B_6eHrir.mjs → webhooks_D05B4_Rs.mjs} +2 -2
  93. package/dist/server/chunks/{yo_BqgZcoxs.mjs → yo_DsFzhH21.mjs} +30 -3
  94. package/dist/server/chunks/{zh-CN_Dz2D1XUc.mjs → zh-CN_OaG8XYVK.mjs} +30 -3
  95. package/dist/server/entry.mjs +28 -28
  96. package/dist/server/virtual_astro_middleware.mjs +1 -1
  97. package/package.json +2 -2
  98. package/dist/client/_astro/ContentEditor.C0RpyhzW.js +0 -1
  99. package/dist/client/_astro/FieldRenderer.BjnbGFPe.js +0 -3
  100. package/dist/client/_astro/TaxonomyTermsManager.CvCxMf0u.js +0 -1
  101. package/dist/client/_astro/ThemeCustomizer.BIct4Scf.js +0 -49
  102. package/dist/client/_astro/ar.BeEmOTlL.js +0 -1
  103. package/dist/client/_astro/es-ES.C0DI0CK6.js +0 -1
  104. package/dist/client/_astro/he.RF4swhtn.js +0 -1
  105. package/dist/client/_astro/it.DhCR9YsW.js +0 -1
  106. package/dist/client/_astro/ja.DPrxHQvU.js +0 -1
  107. package/dist/client/_astro/pl.6VCoPa7y.js +0 -1
  108. package/dist/client/_astro/ru.Cv0Z6X2y.js +0 -1
  109. package/dist/client/_astro/sw.BBMIgY-Y.js +0 -1
  110. package/dist/client/_astro/tr.BWEmWhCE.js +0 -1
  111. package/dist/client/_astro/uk.DDXJXOmn.js +0 -1
  112. package/dist/client/_astro/yo.DNoEBLJd.js +0 -1
  113. package/dist/client/_astro/zh-CN.CVKBB6Ky.js +0 -1
  114. package/dist/server/chunks/customize_zTqT6Yj2.mjs +0 -233
@@ -0,0 +1,1629 @@
1
+ import { r as __exportAll } from "./rolldown-runtime_BMI-E3GI.mjs";
2
+ import { S as createAstro, i as renderComponent, u as renderTemplate } from "./server_B5N27szj.mjs";
3
+ import { t as createComponent$1 } from "./compiler_O7J1rlsi.mjs";
4
+ import { n as useTranslation, r as apiClient } from "./i18n_C-sgJSi1.mjs";
5
+ import { t as $$DashboardLayout } from "./DashboardLayout_D6zphdT0.mjs";
6
+ import { n as isFieldVisible } from "./FieldRenderer_D4dcZjgt.mjs";
7
+ import { t as PageHeader } from "./PageHeader_CBOioOjo.mjs";
8
+ import { createComponent, escape, memo, ssr, ssrAttribute, ssrHydrationKey, ssrStyleProperty } from "solid-js/web";
9
+ import { For, Show, createMemo, createSignal, onMount } from "solid-js";
10
+ //#region src/components/shared/DateTimeCustomizer.tsx
11
+ var _tmpl$$11 = [
12
+ "<div",
13
+ " class=\"datetime-customizer\"><label class=\"datetime-customizer__label\">",
14
+ "</label><input",
15
+ " class=\"input datetime-customizer__input\"",
16
+ "><style>\n .datetime-customizer { display: flex; flex-direction: column; gap: 0.5rem; }\n .datetime-customizer__label { font-size: 0.75rem; font-weight: 600; color: var(--color-text); }\n .datetime-customizer__input { width: 100%; max-width: 280px; }\n </style></div>"
17
+ ];
18
+ function DateTimeCustomizer(props) {
19
+ const { t } = useTranslation();
20
+ const { value, onChange, type, placeholder, label, min, max, step } = props;
21
+ const [currentValue, setCurrentValue] = createSignal(value || "");
22
+ const typeLabels = {
23
+ date: t("customizer.fieldTypes.date.label"),
24
+ "datetime-local": t("customizer.fieldTypes.datetime.label"),
25
+ time: t("customizer.fieldTypes.time.label")
26
+ };
27
+ return ssr(_tmpl$$11, ssrHydrationKey(), escape(label || typeLabels[type]), ssrAttribute("type", escape(type, true), false), ssrAttribute("value", escape(currentValue(), true), false) + ssrAttribute("placeholder", escape(placeholder || t(`customizer.fieldTypes.${type}.placeholder`), true), false) + ssrAttribute("min", escape(min, true), false) + ssrAttribute("max", escape(max, true), false) + ssrAttribute("step", escape(step, true), false));
28
+ }
29
+ //#endregion
30
+ //#region src/components/shared/EntitySelectorCustomizer.tsx
31
+ var _tmpl$$10 = [
32
+ "<div",
33
+ " class=\"entity-selector__pagination\"><button class=\"btn btn-secondary\"",
34
+ ">← Anterior</button><span>P\\u00e1gina <!--$-->",
35
+ "<!--/--> de <!--$-->",
36
+ "<!--/--></span><button class=\"btn btn-secondary\"",
37
+ ">Pr\\u00f3xima →</button></div>"
38
+ ];
39
+ var _tmpl$2$9 = [
40
+ "<div",
41
+ " class=\"entity-selector__dropdown\"><div class=\"entity-selector__search\"><input type=\"text\" class=\"input\"",
42
+ " autofocus><button class=\"btn btn-secondary\"",
43
+ ">",
44
+ "</button></div><div class=\"entity-selector__list\"><!--$-->",
45
+ "<!--/--><!--$-->",
46
+ "<!--/--></div><!--$-->",
47
+ "<!--/--></div>"
48
+ ];
49
+ var _tmpl$3$9 = [
50
+ "<div",
51
+ " class=\"entity-selector-customizer\"><label class=\"entity-selector__label\">",
52
+ "</label><div class=\"entity-selector__trigger\"><div class=\"entity-selector__selected\">",
53
+ "</div><span class=\"entity-selector__arrow\">",
54
+ "</span></div><!--$-->",
55
+ "<!--/--><style>\n .entity-selector-customizer { position: relative; }\n .entity-selector__label { display: block; font-size: 0.75rem; font-weight: 600; color: var(--color-text); margin-bottom: 0.25rem; }\n .entity-selector__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n cursor: pointer;\n min-height: 42px;\n transition: border-color 0.15s;\n }\n .entity-selector__trigger:hover { border-color: var(--color-primary); }\n .entity-selector__selected { display: flex; flex-wrap: wrap; gap: 0.25rem; flex: 1; min-height: 24px; }\n .entity-selector__chip {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n background: var(--color-primary-soft);\n color: var(--color-primary);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n }\n .entity-selector__chip-remove {\n background: none;\n border: none;\n color: var(--color-primary);\n cursor: pointer;\n padding: 0;\n font-size: 0.75rem;\n line-height: 1;\n }\n .entity-selector__placeholder { color: var(--color-muted); font-size: 0.875rem; }\n .entity-selector__arrow { font-size: 0.75rem; color: var(--color-muted); transition: transform 0.15s; }\n .entity-selector__dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--color-white);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-lg);\n margin-top: 0.25rem;\n z-index: 100;\n max-height: 500px;\n display: flex;\n flex-direction: column;\n }\n .entity-selector__search {\n display: flex;\n gap: 0.5rem;\n padding: 0.75rem;\n border-bottom: 1px solid var(--color-border);\n }\n .entity-selector__search input { flex: 1; }\n .entity-selector__list {\n max-height: 300px;\n overflow-y: auto;\n }\n .entity-selector__item {\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n border-bottom: 1px solid var(--color-border);\n transition: background 0.1s;\n }\n .entity-selector__item:hover { background: var(--color-primary-soft); }\n .entity-selector__item.selected { background: var(--color-primary-soft); border-left: 3px solid var(--color-primary); }\n .entity-selector__empty { padding: 1rem; text-align: center; color: var(--color-muted); }\n .entity-selector__pagination { display: flex; align-items: center; justify-content: center; gap: 1rem; padding: 0.75rem; border-top: 1px solid var(--color-border); font-size: 0.8125rem; }\n </style></div>"
56
+ ];
57
+ var _tmpl$4$9 = [
58
+ "<span",
59
+ " class=\"entity-selector__chip\"><!--$-->",
60
+ "<!--/--><button type=\"button\" class=\"entity-selector__chip-remove\">✕</button></span>"
61
+ ];
62
+ var _tmpl$5$9 = [
63
+ "<span",
64
+ " class=\"entity-selector__placeholder\">",
65
+ "</span>"
66
+ ];
67
+ var _tmpl$6$6 = [
68
+ "<div",
69
+ " class=\"",
70
+ "\"><span>",
71
+ "</span><!--$-->",
72
+ "<!--/--></div>"
73
+ ];
74
+ var _tmpl$7$5 = [
75
+ "<span",
76
+ " class=\"entity-selector__item-slug\">",
77
+ "</span>"
78
+ ];
79
+ var _tmpl$8$4 = ["<div", " class=\"entity-selector__empty\">Nenhum resultado encontrado</div>"];
80
+ function EntitySelectorCustomizer(props) {
81
+ const { value, onChange, entityType, taxonomy, multiple = false, placeholder = "Buscar...", label } = props;
82
+ const [items, setItems] = createSignal([]);
83
+ const [total, setTotal] = createSignal(0);
84
+ const [page, setPage] = createSignal(1);
85
+ const [search, setSearch] = createSignal("");
86
+ const [loading, setLoading] = createSignal(false);
87
+ const [showDropdown, setShowDropdown] = createSignal(false);
88
+ const [selectedIds, setSelectedIds] = createSignal([]);
89
+ const currentIds = Array.isArray(value) ? value : value ? [value] : [];
90
+ onMount(() => {
91
+ setSelectedIds(currentIds);
92
+ });
93
+ return ssr(_tmpl$3$9, ssrHydrationKey(), escape(label || (entityType === "taxonomy" ? "Taxonomia" : "Usuário")), selectedIds().length > 0 ? escape(createComponent(For, {
94
+ get each() {
95
+ return selectedIds();
96
+ },
97
+ children: (id) => {
98
+ const item = items().find((i) => i.id === id);
99
+ return ssr(_tmpl$4$9, ssrHydrationKey(), item ? escape(item.name || item.slug || item.id) : escape(id));
100
+ }
101
+ })) : ssr(_tmpl$5$9, ssrHydrationKey(), escape(placeholder)), showDropdown() ? "▲" : "▼", escape(createComponent(Show, {
102
+ get when() {
103
+ return showDropdown();
104
+ },
105
+ get children() {
106
+ return ssr(_tmpl$2$9, ssrHydrationKey(), ssrAttribute("placeholder", escape(placeholder, true), false) + ssrAttribute("value", escape(search(), true), false), ssrAttribute("disabled", loading(), true), loading() ? "Carregando..." : "Buscar", escape(createComponent(For, {
107
+ get each() {
108
+ return items();
109
+ },
110
+ children: (item) => ssr(_tmpl$6$6, ssrHydrationKey(), `entity-selector__item ${selectedIds().includes(item.id) ? "selected" : ""}`, escape(item.name || item.slug || item.id), item.slug && ssr(_tmpl$7$5, ssrHydrationKey(), escape(item.slug)))
111
+ })), items().length === 0 && !loading() && _tmpl$8$4[0] + ssrHydrationKey() + _tmpl$8$4[1], escape(createComponent(Show, {
112
+ get when() {
113
+ return total() > 10;
114
+ },
115
+ get children() {
116
+ return ssr(_tmpl$$10, ssrHydrationKey(), ssrAttribute("disabled", page() <= 1, true), escape(page()), escape(Math.ceil(total() / 10)), ssrAttribute("disabled", page() >= Math.ceil(total() / 10), true));
117
+ }
118
+ })));
119
+ }
120
+ })));
121
+ }
122
+ //#endregion
123
+ //#region src/components/shared/FlexibleContentCustomizer.tsx
124
+ var _tmpl$$9 = [
125
+ "<div",
126
+ " class=\"flexible-content-customizer\"><label class=\"flexible-content-customizer__label\">",
127
+ "</label><div class=\"flexible-content-customizer__rows\"><!--$-->",
128
+ "<!--/--><!--$-->",
129
+ "<!--/--></div><div class=\"flexible-content-customizer__layout-picker\"><span class=\"flexible-content-customizer__picker-label\">Add layout:</span><div class=\"flexible-content-customizer__layout-buttons\">",
130
+ "</div></div><style>\n .flexible-content-customizer {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n .flexible-content-customizer__label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--color-text);\n margin-bottom: 0.25rem;\n }\n .flexible-content-customizer__rows {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n .flexible-content-customizer__row {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n overflow: hidden;\n }\n .flexible-content-customizer__row-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: #f5f5f5;\n border-bottom: 1px solid var(--color-border);\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n .flexible-content-customizer__row-label {\n font-weight: 500;\n font-size: 0.875rem;\n }\n .flexible-content-customizer__layout-badge {\n font-size: 0.625rem;\n padding: 0.125rem 0.375rem;\n background: var(--color-primary-soft);\n color: var(--color-primary);\n border-radius: var(--radius-full);\n text-transform: uppercase;\n }\n .flexible-content-customizer__row-actions {\n display: flex;\n gap: 0.25rem;\n }\n .flexible-content-customizer__row-actions .btn-icon {\n padding: 0.25rem 0.5rem;\n font-size: 0.75rem;\n min-width: auto;\n }\n .flexible-content-customizer__fields {\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n }\n .flexible-content-customizer__field {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n .flexible-content-customizer__empty {\n padding: 2rem;\n text-align: center;\n color: var(--color-muted);\n }\n .flexible-content-customizer__layout-picker {\n margin-top: 1rem;\n padding-top: 1rem;\n border-top: 1px solid var(--color-border);\n }\n .flexible-content-customizer__picker-label {\n display: block;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--color-text);\n margin-bottom: 0.5rem;\n }\n .flexible-content-customizer__layout-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n .flexible-content-customizer__layout-btn {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n }\n </style></div>"
131
+ ];
132
+ var _tmpl$2$8 = [
133
+ "<div",
134
+ " class=\"flexible-content-customizer__fields\">",
135
+ "</div>"
136
+ ];
137
+ var _tmpl$3$8 = [
138
+ "<div",
139
+ " class=\"",
140
+ "\"><div class=\"flexible-content-customizer__row-header\"><span class=\"flexible-content-customizer__row-label\">",
141
+ "</span><span class=\"flexible-content-customizer__layout-badge\">",
142
+ "</span><div class=\"flexible-content-customizer__row-actions\"><button type=\"button\" class=\"btn btn-icon\"",
143
+ ">",
144
+ "</button><button type=\"button\" class=\"btn btn-icon\"",
145
+ " aria-label=\"Move up\">↑</button><button type=\"button\" class=\"btn btn-icon\"",
146
+ " aria-label=\"Move down\">↓</button><button type=\"button\" class=\"btn btn-icon btn-danger\"",
147
+ " aria-label=\"Remove layout\">✕</button></div></div><!--$-->",
148
+ "<!--/--></div>"
149
+ ];
150
+ var _tmpl$4$8 = [
151
+ "<div",
152
+ " class=\"flexible-content-customizer__field\">",
153
+ "</div>"
154
+ ];
155
+ var _tmpl$5$8 = ["<div", " class=\"flexible-content-customizer__empty\">No layouts added. Choose a layout below to start.</div>"];
156
+ var _tmpl$6$5 = [
157
+ "<button",
158
+ " type=\"button\" class=\"btn btn-secondary flexible-content-customizer__layout-btn\"",
159
+ ">",
160
+ "</button>"
161
+ ];
162
+ function FlexibleContentCustomizer(props) {
163
+ const { value, onChange, layouts, label, minRows = 0, maxRows } = props;
164
+ const [rows, setRows] = createSignal(value || []);
165
+ const [expanded, setExpanded] = createSignal(/* @__PURE__ */ new Set([0]));
166
+ const getLayout = (layoutName) => layouts.find((layout) => layout.name === layoutName);
167
+ const handleFieldChange = (rowIndex, fieldName, fieldValue) => {
168
+ const next = [...rows()];
169
+ const row = next[rowIndex];
170
+ if (row) next[rowIndex] = {
171
+ ...row,
172
+ [fieldName]: fieldValue
173
+ };
174
+ setRows(next);
175
+ onChange(next);
176
+ };
177
+ const getRowLabel = (row, index) => {
178
+ const layoutName = row["fc_layout"];
179
+ return getLayout(layoutName)?.label || layoutName || `Layout ${index + 1}`;
180
+ };
181
+ return ssr(_tmpl$$9, ssrHydrationKey(), escape(label || "Flexible Content"), escape(createComponent(For, {
182
+ get each() {
183
+ return rows();
184
+ },
185
+ children: (row, index) => {
186
+ const layout = getLayout(row.fc_layout);
187
+ return ssr(_tmpl$3$8, ssrHydrationKey(), `flexible-content-customizer__row ${expanded().has(index()) ? "expanded" : ""}`, escape(getRowLabel(row, index())), escape(row.fc_layout), ssrAttribute("aria-label", expanded().has(index()) ? "Collapse" : "Expand", false), expanded().has(index()) ? "▲" : "▼", ssrAttribute("disabled", index() === 0, true), ssrAttribute("disabled", index() === rows().length - 1, true), ssrAttribute("disabled", rows().length <= minRows, true), escape(createComponent(Show, {
188
+ get when() {
189
+ return expanded().has(index());
190
+ },
191
+ get children() {
192
+ return ssr(_tmpl$2$8, ssrHydrationKey(), escape(createComponent(For, {
193
+ get each() {
194
+ return layout?.subFields ?? [];
195
+ },
196
+ children: (field) => ssr(_tmpl$4$8, ssrHydrationKey(), escape(createComponent(FieldRendererFactory, {
197
+ get field() {
198
+ return {
199
+ ...field,
200
+ name: field.name
201
+ };
202
+ },
203
+ get value() {
204
+ return row[field.name];
205
+ },
206
+ onChange: (val) => handleFieldChange(index(), field.name, val),
207
+ get subFields() {
208
+ return field.subFields;
209
+ },
210
+ get layouts() {
211
+ return field.layouts;
212
+ }
213
+ })))
214
+ })));
215
+ }
216
+ })));
217
+ }
218
+ })), rows().length === 0 && _tmpl$5$8[0] + ssrHydrationKey() + _tmpl$5$8[1], escape(createComponent(For, {
219
+ each: layouts,
220
+ children: (layout) => ssr(_tmpl$6$5, ssrHydrationKey(), ssrAttribute("disabled", maxRows !== void 0 && rows().length >= maxRows, true), escape(layout.label || layout.name))
221
+ })));
222
+ }
223
+ //#endregion
224
+ //#region src/components/shared/GoogleMapCustomizer.tsx
225
+ var _tmpl$$8 = [
226
+ "<ul",
227
+ " id=\"googlemap-suggestions\" class=\"googlemap-customizer__suggestions\">",
228
+ "</ul>"
229
+ ];
230
+ var _tmpl$2$7 = [
231
+ "<a",
232
+ " class=\"btn btn-secondary\" href=\"",
233
+ "\" target=\"_blank\" rel=\"noopener noreferrer\">Ver no Google Maps</a>"
234
+ ];
235
+ var _tmpl$3$7 = [
236
+ "<div",
237
+ " class=\"google-map-customizer\"><label class=\"googlemap-customizer__label\">",
238
+ "</label><div class=\"googlemap-customizer__fields\"><div class=\"googlemap-customizer__address-wrapper\"><input type=\"text\" class=\"input googlemap-customizer__address\"",
239
+ " autocomplete=\"off\" aria-autocomplete=\"list\" aria-controls=\"googlemap-suggestions\"><!--$-->",
240
+ "<!--/--><!--$-->",
241
+ "<!--/--></div><div class=\"googlemap-customizer__coords\"><input type=\"number\" class=\"input googlemap-customizer__coord\" placeholder=\"Lat (-90 a 90)\" step=\"any\" min=\"-90\" max=\"90\"",
242
+ "><input type=\"number\" class=\"input googlemap-customizer__coord\" placeholder=\"Lng (-180 a 180)\" step=\"any\" min=\"-180\" max=\"180\"",
243
+ "></div></div><div class=\"googlemap-customizer__actions\"><button type=\"button\" class=\"btn btn-secondary\">Limpar</button><!--$-->",
244
+ "<!--/--></div><style>\n .google-map-customizer { display: flex; flex-direction: column; gap: 0.75rem; }\n .googlemap-customizer__label { font-size: 0.75rem; font-weight: 600; color: var(--color-text); margin-bottom: 0.25rem; }\n .googlemap-customizer__fields { display: flex; flex-direction: column; gap: 0.5rem; }\n .googlemap-customizer__address-wrapper { position: relative; }\n .googlemap-customizer__address { padding-right: 2.5rem; }\n .googlemap-customizer__loading { position: absolute; right: 0.75rem; top: 50%; transform: translateY(-50%); }\n .googlemap-customizer__suggestions {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--color-white);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-md);\n list-style: none;\n margin: 0.25rem 0 0;\n padding: 0.25rem;\n max-height: 200px;\n overflow-y: auto;\n z-index: 100;\n }\n .googlemap-customizer__suggestion {\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n font-size: 0.875rem;\n }\n .googlemap-customizer__suggestion:hover { background: var(--color-primary-soft); }\n .googlemap-customizer__coords { display: flex; gap: 0.5rem; }\n .googlemap-customizer__coord { flex: 1; }\n </style></div>"
245
+ ];
246
+ var _tmpl$4$7 = ["<span", " class=\"googlemap-customizer__loading\">🔍</span>"];
247
+ var _tmpl$5$7 = [
248
+ "<li",
249
+ " class=\"googlemap-customizer__suggestion\">",
250
+ "</li>"
251
+ ];
252
+ function GoogleMapCustomizer(props) {
253
+ const { value, onChange, placeholder = "Digite um endereço...", label, apiKey } = props;
254
+ const [address, setAddress] = createSignal(value?.address || "");
255
+ const [lat, setLat] = createSignal(value?.lat);
256
+ const [lng, setLng] = createSignal(value?.lng);
257
+ const [searching, setSearching] = createSignal(false);
258
+ const [suggestions, setSuggestions] = createSignal([]);
259
+ const [showSuggestions, setShowSuggestions] = createSignal(false);
260
+ return ssr(_tmpl$3$7, ssrHydrationKey(), escape(label || "Localização"), ssrAttribute("placeholder", escape(placeholder, true), false) + ssrAttribute("value", escape(address(), true), false), searching() && _tmpl$4$7[0] + ssrHydrationKey() + _tmpl$4$7[1], escape(createComponent(Show, {
261
+ get when() {
262
+ return memo(() => !!showSuggestions())() && suggestions().length > 0;
263
+ },
264
+ get children() {
265
+ return ssr(_tmpl$$8, ssrHydrationKey(), escape(createComponent(For, {
266
+ get each() {
267
+ return suggestions();
268
+ },
269
+ children: (suggestion) => ssr(_tmpl$5$7, ssrHydrationKey(), escape(suggestion.display_name))
270
+ })));
271
+ }
272
+ })), ssrAttribute("value", escape(lat() ?? "", true), false), ssrAttribute("value", escape(lng() ?? "", true), false), escape(createComponent(Show, {
273
+ get when() {
274
+ return memo(() => lat() !== void 0)() && lng() !== void 0;
275
+ },
276
+ get children() {
277
+ return ssr(_tmpl$2$7, ssrHydrationKey(), `https://www.google.com/maps/search/?api=1&amp;query=${escape(lat(), true)},${escape(lng(), true)}`);
278
+ }
279
+ })));
280
+ }
281
+ //#endregion
282
+ //#region src/components/shared/LinkCustomizer.tsx
283
+ var _tmpl$$7 = [
284
+ "<div",
285
+ " class=\"link-customizer\"><label class=\"link-customizer__label\">",
286
+ "</label><div class=\"link-customizer__fields\"><input type=\"url\" class=\"input link-customizer__url\"",
287
+ "><select class=\"input link-customizer__target\"",
288
+ "><option value=\"_self\">",
289
+ "</option><option value=\"_blank\">",
290
+ "</option></select></div><style>\n .link-customizer { display: flex; flex-direction: column; gap: 0.5rem; }\n .link-customizer__label { font-size: 0.75rem; font-weight: 600; color: var(--color-text); }\n .link-customizer__fields { display: flex; gap: 0.5rem; }\n .link-customizer__url { flex: 1; }\n .link-customizer__target { width: 140px; flex-shrink: 0; }\n </style></div>"
291
+ ];
292
+ function LinkCustomizer(props) {
293
+ const { t } = useTranslation();
294
+ const { value, onChange, placeholder = "https:// ou /caminho", label } = props;
295
+ const [url, setUrl] = createSignal(value?.url || "");
296
+ const [target, setTarget] = createSignal(value?.target || "_self");
297
+ return ssr(_tmpl$$7, ssrHydrationKey(), escape(label || t("customizer.fieldTypes.link.label")), ssrAttribute("placeholder", escape(placeholder, true), false) + ssrAttribute("value", escape(url(), true), false), ssrAttribute("value", escape(target(), true), false), escape(t("customizer.fieldTypes.link.targetSelf")), escape(t("customizer.fieldTypes.link.targetBlank")));
298
+ }
299
+ //#endregion
300
+ //#region src/components/shared/MediaPickerCustomizer.tsx
301
+ var _tmpl$$6 = [
302
+ "<option",
303
+ " value>",
304
+ "</option>"
305
+ ];
306
+ var _tmpl$2$6 = [
307
+ "<option",
308
+ " value=\"image/\">",
309
+ "</option>"
310
+ ];
311
+ var _tmpl$3$6 = [
312
+ "<option",
313
+ " value=\"video/\">",
314
+ "</option>"
315
+ ];
316
+ var _tmpl$4$6 = [
317
+ "<option",
318
+ " value=\"audio/\">",
319
+ "</option>"
320
+ ];
321
+ var _tmpl$5$6 = [
322
+ "<option",
323
+ " value=\"application/pdf\">",
324
+ "</option>"
325
+ ];
326
+ var _tmpl$6$4 = [
327
+ "<div",
328
+ " class=\"media-picker-customizer__pagination\"><button class=\"btn btn-secondary\"",
329
+ ">← <!--$-->",
330
+ "<!--/--></button><span>",
331
+ "</span><button class=\"btn btn-secondary\"",
332
+ "><!--$-->",
333
+ "<!--/--> →</button></div>"
334
+ ];
335
+ var _tmpl$7$4 = [
336
+ "<div",
337
+ " class=\"media-picker-customizer__modal-overlay\"><div class=\"media-picker-customizer__modal\"><div class=\"media-picker-customizer__modal-header\"><h3>",
338
+ "</h3><div class=\"media-picker-customizer__modal-actions\"><label class=\"media-picker-customizer__upload-btn\"><input type=\"file\"",
339
+ " style=\"",
340
+ "\"><span class=\"btn btn-primary\">",
341
+ "</span></label><button class=\"btn btn-secondary\">",
342
+ "</button><button class=\"btn btn-primary\"",
343
+ ">",
344
+ "</button></div></div><div class=\"media-picker-customizer__toolbar\"><input type=\"text\" class=\"input\"",
345
+ "><button class=\"btn btn-secondary\">",
346
+ "</button><!--$-->",
347
+ "<!--/--></div><div class=\"",
348
+ "\"><span class=\"media-picker-customizer__dropzone-text\">",
349
+ "</span><input type=\"file\"",
350
+ " style=\"",
351
+ "\"><label for=\"media-picker-file-input\" class=\"btn btn-secondary\">",
352
+ "</label></div><div class=\"media-picker-customizer__grid\"><!--$-->",
353
+ "<!--/--><!--$-->",
354
+ "<!--/--></div><!--$-->",
355
+ "<!--/--></div></div>"
356
+ ];
357
+ var _tmpl$8$3 = [
358
+ "<div",
359
+ " class=\"media-picker-customizer\"><label class=\"media-picker-customizer__trigger\"><span class=\"media-picker-customizer__icon\">🖼️</span><span class=\"media-picker-customizer__text\">",
360
+ "</span><!--$-->",
361
+ "<!--/--></label><!--$-->",
362
+ "<!--/--><!--$-->",
363
+ "<!--/--><style>\n .media-picker-customizer { position: relative; }\n .media-picker-customizer__trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n color: var(--color-text);\n cursor: pointer;\n transition: all 0.15s ease;\n min-width: 200px;\n }\n .media-picker-customizer__trigger:hover {\n border-color: var(--color-primary);\n }\n .media-picker-customizer__icon { font-size: 1.25rem; }\n .media-picker-customizer__text { flex: 1; font-size: 0.875rem; }\n .media-picker-customizer__label { font-size: 0.75rem; color: var(--color-muted); }\n .media-picker-customizer__error { color: var(--color-error); font-size: 0.75rem; margin-top: 0.25rem; }\n .media-picker-customizer__modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n }\n .media-picker-customizer__modal {\n background: var(--color-white);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-xl);\n width: 100%;\n max-width: 900px;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .media-picker-customizer__modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid var(--color-border);\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n .media-picker-customizer__modal-header h3 { margin: 0; font-size: 1rem; }\n .media-picker-customizer__modal-actions { display: flex; gap: 0.5rem; }\n .media-picker-customizer__upload-btn { position: relative; }\n .media-picker-customizer__upload-btn input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }\n .media-picker-customizer__toolbar {\n display: flex;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--color-border);\n flex-wrap: wrap;\n align-items: center;\n }\n .media-picker-customizer__toolbar input[type=\"text\"] { flex: 1; min-width: 200px; }\n .media-picker-customizer__dropzone {\n padding: 2rem;\n border: 2px dashed var(--color-border);\n border-radius: var(--radius-md);\n margin: 1rem;\n text-align: center;\n transition: all 0.15s ease;\n }\n .media-picker-customizer__dropzone.drag-over {\n border-color: var(--color-primary);\n background: var(--color-primary-soft);\n }\n .media-picker-customizer__dropzone input[type=\"file\"] { display: none; }\n .media-picker-customizer__dropzone-text { color: var(--color-muted); font-size: 0.875rem; }\n .media-picker-customizer__grid {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));\n gap: 0.75rem;\n }\n .media-picker-customizer__item {\n border: 2px solid var(--color-border);\n border-radius: var(--radius-md);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.15s ease;\n background: var(--color-white);\n }\n .media-picker-customizer__item:hover { border-color: var(--color-primary); }\n .media-picker-customizer__item.selected {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 2px var(--color-primary);\n }\n .media-picker-customizer__preview {\n aspect-ratio: 16/9;\n background: #f5f5f5;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n }\n .media-picker-customizer__preview img { width: 100%; height: 100%; object-fit: cover; }\n .media-picker-customizer__icon-large { font-size: 3rem; color: var(--color-muted); }\n .media-picker-customizer__checkmark {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n background: var(--color-primary);\n color: white;\n width: 1.5rem;\n height: 1.5rem;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n }\n .media-picker-customizer__info { padding: 0.5rem; }\n .media-picker-customizer__name { display: block; font-size: 0.75rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .media-picker-customizer__meta { display: block; font-size: 0.625rem; color: var(--color-muted); margin-top: 0.125rem; }\n .media-picker-customizer__empty { grid-column: 1 / -1; padding: 3rem; text-align: center; color: var(--color-muted); }\n .media-picker-customizer__pagination { display: flex; align-items: center; justify-content: center; gap: 1rem; padding: 1rem; border-top: 1px solid var(--color-border); font-size: 0.8125rem; color: var(--color-muted); }\n </style></div>"
364
+ ];
365
+ var _tmpl$9$3 = [
366
+ "<span",
367
+ " class=\"media-picker-customizer__label\">",
368
+ "</span>"
369
+ ];
370
+ var _tmpl$0$3 = [
371
+ "<div",
372
+ " class=\"media-picker-customizer__error\">",
373
+ "</div>"
374
+ ];
375
+ var _tmpl$1$3 = [
376
+ "<div",
377
+ " class=\"",
378
+ "\"><div class=\"media-picker-customizer__preview\"><!--$-->",
379
+ "<!--/--><!--$-->",
380
+ "<!--/--></div><div class=\"media-picker-customizer__info\"><span class=\"media-picker-customizer__name\">",
381
+ "</span><span class=\"media-picker-customizer__meta\"><!--$-->",
382
+ "<!--/--> · <!--$-->",
383
+ "<!--/--></span></div></div>"
384
+ ];
385
+ var _tmpl$10$2 = ["<img", " alt loading=\"lazy\">"];
386
+ var _tmpl$11$2 = [
387
+ "<div",
388
+ " class=\"media-picker-customizer__icon-large\">",
389
+ "</div>"
390
+ ];
391
+ var _tmpl$12$2 = ["<div", " class=\"media-picker-customizer__checkmark\">✓</div>"];
392
+ var _tmpl$13$1 = [
393
+ "<div",
394
+ " class=\"media-picker-customizer__empty\">",
395
+ "</div>"
396
+ ];
397
+ var _tmpl$14$1 = [
398
+ "<select",
399
+ " class=\"input\"",
400
+ ">",
401
+ "</select>"
402
+ ];
403
+ function formatSize(bytes) {
404
+ if (!Number.isFinite(bytes)) return "—";
405
+ if (bytes < 1024) return `${bytes} B`;
406
+ if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
407
+ return `${(bytes / 1048576).toFixed(1)} MB`;
408
+ }
409
+ function isImage(media) {
410
+ return media.mime_type.startsWith("image/");
411
+ }
412
+ function isVideo(media) {
413
+ return media.mime_type.startsWith("video/");
414
+ }
415
+ function isAudio(media) {
416
+ return media.mime_type.startsWith("audio/");
417
+ }
418
+ function isPdf(media) {
419
+ return media.mime_type === "application/pdf";
420
+ }
421
+ function getMediaIcon(media) {
422
+ if (isImage(media)) return "🖼️";
423
+ if (isVideo(media)) return "🎬";
424
+ if (isAudio(media)) return "🎵";
425
+ if (isPdf(media)) return "📄";
426
+ return "📎";
427
+ }
428
+ function mediaUrl(media) {
429
+ return apiClient.mediaUrl(media.url);
430
+ }
431
+ function MediaPickerCustomizer(props) {
432
+ const { t } = useTranslation();
433
+ const { value, onChange, multiple = false, accept, label, placeholder = "Clique para selecionar mídia" } = props;
434
+ const [items, setItems] = createSignal([]);
435
+ const [total, setTotal] = createSignal(0);
436
+ const [page, setPage] = createSignal(1);
437
+ const [search, setSearch] = createSignal("");
438
+ const [mimeTypeFilter, setMimeTypeFilter] = createSignal("");
439
+ const [error, setError] = createSignal("");
440
+ const [uploading, setUploading] = createSignal(false);
441
+ const [showModal, setShowModal] = createSignal(false);
442
+ const [dragOver, setDragOver] = createSignal(false);
443
+ const [selectedIds, setSelectedIds] = createSignal([]);
444
+ const limit = 20;
445
+ const currentIds = Array.isArray(value) ? value : value ? [value] : [];
446
+ onMount(() => {
447
+ setSelectedIds(currentIds);
448
+ load();
449
+ });
450
+ const load = async () => {
451
+ try {
452
+ setError("");
453
+ const result = await apiClient.listMedia({
454
+ page: page(),
455
+ limit,
456
+ search: search() || void 0,
457
+ mimeType: mimeTypeFilter() || void 0
458
+ });
459
+ setItems(result.data ?? []);
460
+ setTotal(result.total ?? 0);
461
+ } catch (err) {
462
+ setError(err instanceof Error ? err.message : String(err));
463
+ }
464
+ };
465
+ const isSelected = (mediaId) => selectedIds().includes(mediaId);
466
+ return ssr(_tmpl$8$3, ssrHydrationKey(), selectedIds().length > 0 ? `${escape(selectedIds().length)} mídia(s) selecionada(s)` : escape(placeholder), label && ssr(_tmpl$9$3, ssrHydrationKey(), escape(label)), error() && ssr(_tmpl$0$3, ssrHydrationKey(), escape(error())), escape(createComponent(Show, {
467
+ get when() {
468
+ return showModal();
469
+ },
470
+ get children() {
471
+ return ssr(_tmpl$7$4, ssrHydrationKey(), escape(t("media.picker.title")), ssrAttribute("multiple", multiple, true) + ssrAttribute("accept", escape(accept, true), false), ssrStyleProperty("display:", "none"), uploading() ? "Enviando..." : escape(t("media.picker.upload")), escape(t("media.picker.clear")), ssrAttribute("disabled", selectedIds().length === 0, true), escape(t("media.picker.confirm")), ssrAttribute("placeholder", escape(t("media.picker.search"), true), false) + ssrAttribute("value", escape(search(), true), false), escape(t("media.picker.search")), escape(createComponent(Select, {
472
+ get value() {
473
+ return mimeTypeFilter();
474
+ },
475
+ onChange: (e) => {
476
+ setMimeTypeFilter(e.currentTarget.value);
477
+ setPage(1);
478
+ load();
479
+ },
480
+ get children() {
481
+ return [
482
+ ssr(_tmpl$$6, ssrHydrationKey(), escape(t("media.picker.allTypes"))),
483
+ ssr(_tmpl$2$6, ssrHydrationKey(), escape(t("media.picker.images"))),
484
+ ssr(_tmpl$3$6, ssrHydrationKey(), escape(t("media.picker.videos"))),
485
+ ssr(_tmpl$4$6, ssrHydrationKey(), escape(t("media.picker.audio"))),
486
+ ssr(_tmpl$5$6, ssrHydrationKey(), escape(t("media.picker.pdfs")))
487
+ ];
488
+ }
489
+ })), `media-picker-customizer__dropzone ${dragOver() ? "drag-over" : ""}`, escape(t("media.picker.dropzone")), ssrAttribute("multiple", multiple, true) + ssrAttribute("accept", escape(accept, true), false), ssrStyleProperty("display:", "none"), escape(t("media.picker.selectFiles")), escape(createComponent(For, {
490
+ get each() {
491
+ return items();
492
+ },
493
+ children: (media) => ssr(_tmpl$1$3, ssrHydrationKey(), `media-picker-customizer__item ${isSelected(media.id) ? "selected" : ""}`, isImage(media) ? ssr(_tmpl$10$2, ssrHydrationKey() + ssrAttribute("src", escape(mediaUrl(media), true), false)) : ssr(_tmpl$11$2, ssrHydrationKey(), escape(getMediaIcon(media))), isSelected(media.id) && _tmpl$12$2[0] + ssrHydrationKey() + _tmpl$12$2[1], escape(media.title || media.filename), escape(formatSize(media.size)), escape(media.mime_type))
494
+ })), items().length === 0 && ssr(_tmpl$13$1, ssrHydrationKey(), total() === 0 ? escape(t("media.picker.empty")) : escape(t("media.picker.noResults"))), escape(createComponent(Show, {
495
+ get when() {
496
+ return total() > limit;
497
+ },
498
+ get children() {
499
+ return ssr(_tmpl$6$4, ssrHydrationKey(), ssrAttribute("disabled", page() <= 1, true), escape(t("media.picker.prev")), escape(t("media.picker.page", {
500
+ current: page(),
501
+ total: Math.ceil(total() / limit)
502
+ })), ssrAttribute("disabled", page() >= Math.ceil(total() / limit), true), escape(t("media.picker.next")));
503
+ }
504
+ })));
505
+ }
506
+ })));
507
+ }
508
+ function Select(props) {
509
+ return ssr(_tmpl$14$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value, true), false), escape(props.children));
510
+ }
511
+ //#endregion
512
+ //#region src/components/shared/RelationshipCustomizer.tsx
513
+ var _tmpl$$5 = [
514
+ "<div",
515
+ " class=\"relationship-customizer__pagination\"><button class=\"btn btn-secondary\"",
516
+ ">← Anterior</button><span>Página <!--$-->",
517
+ "<!--/--> de <!--$-->",
518
+ "<!--/--></span><button class=\"btn btn-secondary\"",
519
+ ">Próxima →</button></div>"
520
+ ];
521
+ var _tmpl$2$5 = [
522
+ "<div",
523
+ " class=\"relationship-customizer__dropdown\"><div class=\"relationship-customizer__search\"><input type=\"text\" class=\"input\"",
524
+ " autofocus><button class=\"btn btn-secondary\"",
525
+ ">",
526
+ "</button></div><div class=\"relationship-customizer__list\"><!--$-->",
527
+ "<!--/--><!--$-->",
528
+ "<!--/--></div><!--$-->",
529
+ "<!--/--></div>"
530
+ ];
531
+ var _tmpl$3$5 = [
532
+ "<div",
533
+ " class=\"relationship-customizer\"><label class=\"relationship-customizer__label\">",
534
+ "</label><div class=\"relationship-customizer__trigger\"><div class=\"relationship-customizer__selected\">",
535
+ "</div><span class=\"relationship-customizer__arrow\">",
536
+ "</span></div><!--$-->",
537
+ "<!--/--><style>\n .relationship-customizer { position: relative; }\n .relationship-customizer__label { display: block; font-size: 0.75rem; font-weight: 600; color: var(--color-text); margin-bottom: 0.25rem; }\n .relationship-customizer__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 0.75rem;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n cursor: pointer;\n min-height: 42px;\n transition: border-color 0.15s;\n }\n .relationship-customizer__trigger:hover { border-color: var(--color-primary); }\n .relationship-customizer__selected { display: flex; flex-wrap: wrap; gap: 0.25rem; flex: 1; min-height: 24px; }\n .relationship-customizer__chip {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n background: var(--color-primary-soft);\n color: var(--color-primary);\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n }\n .relationship-customizer__chip-remove {\n background: none;\n border: none;\n color: var(--color-primary);\n cursor: pointer;\n padding: 0;\n font-size: 0.75rem;\n line-height: 1;\n }\n .relationship-customizer__placeholder { color: var(--color-muted); font-size: 0.875rem; }\n .relationship-customizer__arrow { font-size: 0.75rem; color: var(--color-muted); transition: transform 0.15s; }\n .relationship-customizer__dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--color-white);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-lg);\n margin-top: 0.25rem;\n z-index: 100;\n max-height: 500px;\n display: flex;\n flex-direction: column;\n }\n .relationship-customizer__search {\n display: flex;\n gap: 0.5rem;\n padding: 0.75rem;\n border-bottom: 1px solid var(--color-border);\n }\n .relationship-customizer__search input { flex: 1; }\n .relationship-customizer__list {\n max-height: 300px;\n overflow-y: auto;\n }\n .relationship-customizer__item {\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n border-bottom: 1px solid var(--color-border);\n transition: background 0.1s;\n }\n .relationship-customizer__item:hover { background: var(--color-primary-soft); }\n .relationship-customizer__item.selected { background: var(--color-primary-soft); border-left: 3px solid var(--color-primary); }\n .relationship-customizer__item-title { font-weight: 500; font-size: 0.875rem; }\n .relationship-customizer__item-meta { font-size: 0.75rem; color: var(--color-muted); margin-top: 0.125rem; }\n .relationship-customizer__empty { padding: 1rem; text-align: center; color: var(--color-muted); }\n .relationship-customizer__pagination { display: flex; align-items: center; justify-content: center; gap: 1rem; padding: 0.75rem; border-top: 1px solid var(--color-border); font-size: 0.8125rem; }\n </style></div>"
538
+ ];
539
+ var _tmpl$4$5 = [
540
+ "<span",
541
+ " class=\"relationship-customizer__chip\"><!--$-->",
542
+ "<!--/--><button type=\"button\" class=\"relationship-customizer__chip-remove\">✕</button></span>"
543
+ ];
544
+ var _tmpl$5$5 = [
545
+ "<span",
546
+ " class=\"relationship-customizer__placeholder\">",
547
+ "</span>"
548
+ ];
549
+ var _tmpl$6$3 = [
550
+ "<div",
551
+ " class=\"",
552
+ "\"><div class=\"relationship-customizer__item-title\">",
553
+ "</div><div class=\"relationship-customizer__item-meta\"><!--$-->",
554
+ "<!--/--> · <!--$-->",
555
+ "<!--/--> · <!--$-->",
556
+ "<!--/--></div></div>"
557
+ ];
558
+ var _tmpl$7$3 = [
559
+ "<div",
560
+ " class=\"relationship-customizer__empty\">",
561
+ "</div>"
562
+ ];
563
+ function RelationshipCustomizer(props) {
564
+ const { t } = useTranslation();
565
+ const { value, onChange, postType, multiple = false, placeholder = "Buscar conteúdo...", label } = props;
566
+ const [items, setItems] = createSignal([]);
567
+ const [total, setTotal] = createSignal(0);
568
+ const [page, setPage] = createSignal(1);
569
+ const [search, setSearch] = createSignal("");
570
+ const [loading, setLoading] = createSignal(false);
571
+ const [showDropdown, setShowDropdown] = createSignal(false);
572
+ const [selectedIds, setSelectedIds] = createSignal([]);
573
+ const currentIds = Array.isArray(value) ? value : value ? [value] : [];
574
+ onMount(() => {
575
+ setSelectedIds(currentIds);
576
+ });
577
+ const isSelected = (id) => selectedIds().includes(id);
578
+ return ssr(_tmpl$3$5, ssrHydrationKey(), escape(label || t("customizer.fieldTypes.relationship.label")), selectedIds().length > 0 ? escape(createComponent(For, {
579
+ get each() {
580
+ return selectedIds();
581
+ },
582
+ children: (id) => {
583
+ const item = items().find((i) => i.id === id);
584
+ return ssr(_tmpl$4$5, ssrHydrationKey(), escape(item?.title || id));
585
+ }
586
+ })) : ssr(_tmpl$5$5, ssrHydrationKey(), escape(placeholder)), showDropdown() ? "▲" : "▼", escape(createComponent(Show, {
587
+ get when() {
588
+ return showDropdown();
589
+ },
590
+ get children() {
591
+ return ssr(_tmpl$2$5, ssrHydrationKey(), ssrAttribute("placeholder", escape(placeholder, true), false) + ssrAttribute("value", escape(search(), true), false), ssrAttribute("disabled", loading(), true), loading() ? "Carregando..." : "Buscar", escape(createComponent(For, {
592
+ get each() {
593
+ return items();
594
+ },
595
+ children: (item) => ssr(_tmpl$6$3, ssrHydrationKey(), `relationship-customizer__item ${isSelected(item.id) ? "selected" : ""}`, escape(item.title), escape(item.type), escape(item.status), escape(item.slug))
596
+ })), items().length === 0 && !loading() && ssr(_tmpl$7$3, ssrHydrationKey(), total() === 0 ? "Nenhum conteúdo encontrado" : "Nenhum resultado para a busca"), escape(createComponent(Show, {
597
+ get when() {
598
+ return total() > 10;
599
+ },
600
+ get children() {
601
+ return ssr(_tmpl$$5, ssrHydrationKey(), ssrAttribute("disabled", page() <= 1, true), escape(page()), escape(Math.ceil(total() / 10)), ssrAttribute("disabled", page() >= Math.ceil(total() / 10), true));
602
+ }
603
+ })));
604
+ }
605
+ })));
606
+ }
607
+ //#endregion
608
+ //#region src/components/shared/RepeaterCustomizer.tsx
609
+ var _tmpl$$4 = [
610
+ "<div",
611
+ " class=\"repeater-customizer\"><label class=\"repeater-customizer__label\">",
612
+ "</label><div class=\"repeater-customizer__rows\"><!--$-->",
613
+ "<!--/--><!--$-->",
614
+ "<!--/--></div><div class=\"repeater-customizer__actions\"><button type=\"button\" class=\"btn btn-primary\">+ <!--$-->",
615
+ "<!--/--></button></div><style>\n .repeater-customizer { display: flex; flex-direction: column; gap: 0.5rem; }\n .repeater-customizer__label { font-size: 0.75rem; font-weight: 600; color: var(--color-text); margin-bottom: 0.25rem; }\n .repeater-customizer__rows { display: flex; flex-direction: column; gap: 0.5rem; }\n .repeater-customizer__row {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n overflow: hidden;\n }\n .repeater-customizer__row-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: #f5f5f5;\n border-bottom: 1px solid var(--color-border);\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n .repeater-customizer__row-label { font-weight: 500; font-size: 0.875rem; }\n .repeater-customizer__row-actions { display: flex; gap: 0.25rem; }\n .repeater-customizer__row-actions .btn-icon {\n padding: 0.25rem 0.5rem;\n font-size: 0.75rem;\n min-width: auto;\n }\n .repeater-customizer__fields { padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }\n .repeater-customizer__field { display: flex; flex-direction: column; gap: 0.5rem; }\n .repeater-customizer__empty { padding: 2rem; text-align: center; color: var(--color-muted); }\n .repeater-customizer__actions { display: flex; justify-content: flex-end; margin-top: 0.5rem; }\n </style></div>"
616
+ ];
617
+ var _tmpl$2$4 = [
618
+ "<div",
619
+ " class=\"repeater-customizer__fields\">",
620
+ "</div>"
621
+ ];
622
+ var _tmpl$3$4 = [
623
+ "<div",
624
+ " class=\"",
625
+ "\"><div class=\"repeater-customizer__row-header\"><span class=\"repeater-customizer__row-label\">",
626
+ "</span><div class=\"repeater-customizer__row-actions\"><button type=\"button\" class=\"btn btn-icon\"",
627
+ ">",
628
+ "</button><button type=\"button\" class=\"btn btn-icon\"",
629
+ " aria-label=\"Mover para cima\">↑</button><button type=\"button\" class=\"btn btn-icon\"",
630
+ " aria-label=\"Mover para baixo\">↓</button><button type=\"button\" class=\"btn btn-icon btn-danger\"",
631
+ " aria-label=\"Remover linha\">✕</button></div></div><!--$-->",
632
+ "<!--/--></div>"
633
+ ];
634
+ var _tmpl$4$4 = [
635
+ "<div",
636
+ " class=\"repeater-customizer__field\">",
637
+ "</div>"
638
+ ];
639
+ var _tmpl$5$4 = ["<div", " class=\"repeater-customizer__empty\">Nenhuma linha adicionada. Clique em \"Adicionar linha\" para começar.</div>"];
640
+ function RepeaterCustomizer(props) {
641
+ const { t } = useTranslation();
642
+ const { value, onChange, subFields, label, itemLabel = "title", minRows = 0, maxRows } = props;
643
+ const [rows, setRows] = createSignal(value || []);
644
+ const [expanded, setExpanded] = createSignal(/* @__PURE__ */ new Set([0]));
645
+ const handleFieldChange = (rowIndex, fieldName, fieldValue) => {
646
+ const next = [...rows()];
647
+ next[rowIndex] = {
648
+ ...next[rowIndex],
649
+ [fieldName]: fieldValue
650
+ };
651
+ setRows(next);
652
+ onChange(next);
653
+ };
654
+ const getRowLabel = (row, index) => {
655
+ const labelValue = row[itemLabel];
656
+ if (labelValue && typeof labelValue === "string" && labelValue.trim()) return labelValue.trim();
657
+ return `Item ${index + 1}`;
658
+ };
659
+ const isExpanded = (index) => expanded().has(index);
660
+ return ssr(_tmpl$$4, ssrHydrationKey(), escape(label || "Repetidor"), escape(createComponent(For, {
661
+ get each() {
662
+ return rows();
663
+ },
664
+ children: (row, index) => ssr(_tmpl$3$4, ssrHydrationKey(), `repeater-customizer__row ${isExpanded(index()) ? "expanded" : ""}`, escape(getRowLabel(row, index())), ssrAttribute("aria-label", isExpanded(index()) ? "Colapsar" : "Expandir", false), isExpanded(index()) ? "▲" : "▼", ssrAttribute("disabled", index() === 0, true), ssrAttribute("disabled", index() === rows().length - 1, true), ssrAttribute("disabled", rows().length <= minRows, true), escape(createComponent(Show, {
665
+ get when() {
666
+ return isExpanded(index());
667
+ },
668
+ get children() {
669
+ return ssr(_tmpl$2$4, ssrHydrationKey(), escape(createComponent(For, {
670
+ each: subFields,
671
+ children: (field) => ssr(_tmpl$4$4, ssrHydrationKey(), escape(createComponent(FieldRendererFactory, {
672
+ get field() {
673
+ return {
674
+ ...field,
675
+ name: field.name
676
+ };
677
+ },
678
+ get value() {
679
+ return row[field.name];
680
+ },
681
+ onChange: (val) => handleFieldChange(index(), field.name, val),
682
+ get subFields() {
683
+ return field.subFields;
684
+ },
685
+ get layouts() {
686
+ return field.layouts;
687
+ }
688
+ })))
689
+ })));
690
+ }
691
+ })))
692
+ })), rows().length === 0 && _tmpl$5$4[0] + ssrHydrationKey() + _tmpl$5$4[1], escape(t("customizer.fieldTypes.repeater.addRow", { default: "Adicionar linha" })));
693
+ }
694
+ //#endregion
695
+ //#region src/components/shared/RichTextEditor.tsx
696
+ var _tmpl$$3 = [
697
+ "<div",
698
+ " class=\"rich-text-editor\" data-rich-text-editor><div class=\"rich-text-editor__toolbar\" role=\"toolbar\"",
699
+ "><!--$-->",
700
+ "<!--/--><!--$-->",
701
+ "<!--/--><!--$-->",
702
+ "<!--/--><!--$-->",
703
+ "<!--/--><!--$-->",
704
+ "<!--/--><!--$-->",
705
+ "<!--/--><!--$-->",
706
+ "<!--/--><!--$-->",
707
+ "<!--/--><!--$-->",
708
+ "<!--/--><!--$-->",
709
+ "<!--/--><!--$-->",
710
+ "<!--/--><!--$-->",
711
+ "<!--/--><!--$-->",
712
+ "<!--/--><!--$-->",
713
+ "<!--/--><!--$-->",
714
+ "<!--/--><!--$-->",
715
+ "<!--/--><!--$-->",
716
+ "<!--/--><!--$-->",
717
+ "<!--/--><!--$-->",
718
+ "<!--/--></div><div class=\"rich-text-editor__body\"",
719
+ " role=\"textbox\" aria-multiline=\"true\"",
720
+ " spellcheck=\"true\">",
721
+ "</div><style>\n .rich-text-editor {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n overflow: hidden;\n }\n .rich-text-editor__toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.25rem;\n background: #f5f5f5;\n border-bottom: 1px solid var(--color-border);\n padding: 0.5rem;\n }\n .rich-text-editor__toolbar select.input {\n max-width: 160px;\n padding: 0.25rem 0.45rem;\n }\n .rich-text-editor__divider { width: 1px; height: 1.5rem; background: var(--color-border); margin: 0 0.25rem; }\n .rich-text-editor__toolbar button {\n min-width: 2rem;\n min-height: 2rem;\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--color-text);\n padding: 0.25rem 0.45rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n }\n .rich-text-editor__toolbar button:hover:not(:disabled) { border-color: var(--color-border); background: var(--color-white); }\n .rich-text-editor__toolbar button:disabled { opacity: 0.4; cursor: not-allowed; }\n .rich-text-editor__divider { width: 1px; height: 1.5rem; background: var(--color-border); margin: 0 0.25rem; }\n .rich-text-editor__body {\n min-height: 200px;\n border: 1px solid var(--color-border);\n border-top: 0;\n background: var(--color-white);\n color: var(--color-text);\n font-size: 0.9375rem;\n line-height: 1.6;\n padding: 0.75rem;\n outline: none;\n border-radius: 0 0 var(--radius-sm) var(--radius-sm);\n }\n .rich-text-editor__body:focus { border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); }\n .rich-text-editor__body:empty::before { content: attr(data-placeholder); color: var(--color-muted); }\n .rich-text-editor__body blockquote { border-left: 3px solid var(--color-primary); margin: 1rem 0; padding-left: 1rem; color: var(--color-muted); }\n .rich-text-editor__body pre { background: #f5f5f5; padding: 0.5rem; border-radius: var(--radius-sm); overflow-x: auto; }\n .rich-text-editor__divider { width: 1px; height: 1.5rem; background: var(--color-border); margin: 0 0.25rem; }\n .rich-text-editor__btn {\n min-width: 2rem;\n min-height: 2rem;\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--color-text);\n padding: 0.25rem 0.45rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n transition: all 0.15s ease;\n }\n .rich-text-editor__btn:hover:not(:disabled) { border-color: var(--color-border); background: var(--color-white); }\n .rich-text-editor__btn:disabled { opacity: 0.4; cursor: not-allowed; }\n .rich-text-editor__body pre { background: #f5f5f5; padding: 0.5rem; border-radius: var(--radius-sm); overflow-x: auto; }\n </style></div>"
722
+ ];
723
+ var _tmpl$2$3 = [
724
+ "<select",
725
+ " class=\"rich-text-editor__select\"",
726
+ " value",
727
+ ">",
728
+ "</select>"
729
+ ];
730
+ var _tmpl$3$3 = [
731
+ "<option",
732
+ ">",
733
+ "</option>"
734
+ ];
735
+ var _tmpl$4$3 = ["<span", " class=\"rich-text-editor__divider\"></span>"];
736
+ var _tmpl$5$3 = [
737
+ "<button",
738
+ " type=\"button\"",
739
+ " aria-label=\"Negrito (Ctrl+B)\"><strong>B</strong></button>"
740
+ ];
741
+ var _tmpl$6$2 = [
742
+ "<button",
743
+ " type=\"button\"",
744
+ " aria-label=\"Itálico (Ctrl+I)\"><em>I</em></button>"
745
+ ];
746
+ var _tmpl$7$2 = [
747
+ "<button",
748
+ " type=\"button\"",
749
+ " aria-label=\"Sublinhado (Ctrl+U)\"><u>U</u></button>"
750
+ ];
751
+ var _tmpl$8$2 = [
752
+ "<button",
753
+ " type=\"button\"",
754
+ " aria-label=\"Tachado\"><s>S</s></button>"
755
+ ];
756
+ var _tmpl$9$2 = [
757
+ "<button",
758
+ " type=\"button\"",
759
+ " aria-label=\"Bloco de citação\">❝</button>"
760
+ ];
761
+ var _tmpl$0$2 = [
762
+ "<button",
763
+ " type=\"button\"",
764
+ " aria-label=\"Código\">&lt;pre></button>"
765
+ ];
766
+ var _tmpl$1$2 = [
767
+ "<button",
768
+ " type=\"button\"",
769
+ " aria-label=\"Lista com marcadores\">• Lista</button>"
770
+ ];
771
+ var _tmpl$10$1 = [
772
+ "<button",
773
+ " type=\"button\"",
774
+ " aria-label=\"Lista numerada\">1. Lista</button>"
775
+ ];
776
+ var _tmpl$11$1 = [
777
+ "<button",
778
+ " type=\"button\"",
779
+ " aria-label=\"Inserir link (Ctrl+K)\">🔗</button>"
780
+ ];
781
+ var _tmpl$12$1 = [
782
+ "<button",
783
+ " type=\"button\"",
784
+ " aria-label=\"Remover link\">🔗✕</button>"
785
+ ];
786
+ var _tmpl$13 = [
787
+ "<button",
788
+ " type=\"button\"",
789
+ " aria-label=\"Desfazer (Ctrl+Z)\">↶</button>"
790
+ ];
791
+ var _tmpl$14 = [
792
+ "<button",
793
+ " type=\"button\"",
794
+ " aria-label=\"Refazer (Ctrl+Y)\">↷</button>"
795
+ ];
796
+ var _tmpl$15 = [
797
+ "<button",
798
+ " type=\"button\"",
799
+ " aria-label=\"Limpar formatação\">𝑥</button>"
800
+ ];
801
+ var DEFAULT_TOOLBAR = {
802
+ formatBlock: true,
803
+ bold: true,
804
+ italic: true,
805
+ underline: true,
806
+ strikeThrough: true,
807
+ blockquote: true,
808
+ code: true,
809
+ unorderedList: true,
810
+ orderedList: true,
811
+ link: true,
812
+ unlink: true,
813
+ undo: true,
814
+ redo: true,
815
+ removeFormat: true
816
+ };
817
+ var FORMAT_BLOCK_OPTIONS = [
818
+ {
819
+ value: "",
820
+ label: "Parágrafo"
821
+ },
822
+ {
823
+ value: "<h1>",
824
+ label: "Título 1"
825
+ },
826
+ {
827
+ value: "<h2>",
828
+ label: "Título 2"
829
+ },
830
+ {
831
+ value: "<h3>",
832
+ label: "Título 3"
833
+ },
834
+ {
835
+ value: "<h4>",
836
+ label: "Título 4"
837
+ },
838
+ {
839
+ value: "<blockquote>",
840
+ label: "Bloco de citação"
841
+ },
842
+ {
843
+ value: "<pre>",
844
+ label: "Código"
845
+ }
846
+ ];
847
+ function RichTextEditor(props) {
848
+ const { value, onChange, placeholder = "Comece a escrever...", disabled = false, toolbarConfig = {} } = props;
849
+ const toolbar = {
850
+ ...DEFAULT_TOOLBAR,
851
+ ...toolbarConfig
852
+ };
853
+ const [editorRef, setEditorRef] = createSignal(null);
854
+ const [isComposing, setIsComposing] = createSignal(false);
855
+ onMount(() => {
856
+ const editor = editorRef();
857
+ if (editor && editor.innerHTML !== value) editor.innerHTML = value;
858
+ });
859
+ return ssr(_tmpl$$3, ssrHydrationKey(), ssrAttribute("aria-label", toolbar.formatBlock ? "Editor de texto rico" : "", false), toolbar.formatBlock && ssr(_tmpl$2$3, ssrHydrationKey(), ssrAttribute("aria-label", toolbar.formatBlock ? "Formato de bloco" : "", false), ssrAttribute("disabled", disabled, true), escape(FORMAT_BLOCK_OPTIONS.map((opt) => ssr(_tmpl$3$3, ssrHydrationKey() + ssrAttribute("value", escape(opt.value, true), false), escape(opt.label))))), toolbar.formatBlock && _tmpl$4$3[0] + ssrHydrationKey() + _tmpl$4$3[1], toolbar.bold && ssr(_tmpl$5$3, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.italic && ssr(_tmpl$6$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.underline && ssr(_tmpl$7$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.strikeThrough && ssr(_tmpl$8$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), (toolbar.bold || toolbar.italic || toolbar.underline || toolbar.strikeThrough) && _tmpl$4$3[0] + ssrHydrationKey() + _tmpl$4$3[1], toolbar.blockquote && ssr(_tmpl$9$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.code && ssr(_tmpl$0$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), (toolbar.blockquote || toolbar.code) && _tmpl$4$3[0] + ssrHydrationKey() + _tmpl$4$3[1], toolbar.unorderedList && ssr(_tmpl$1$2, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.orderedList && ssr(_tmpl$10$1, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), (toolbar.unorderedList || toolbar.orderedList) && _tmpl$4$3[0] + ssrHydrationKey() + _tmpl$4$3[1], toolbar.link && ssr(_tmpl$11$1, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.unlink && ssr(_tmpl$12$1, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), (toolbar.link || toolbar.unlink) && _tmpl$4$3[0] + ssrHydrationKey() + _tmpl$4$3[1], toolbar.undo && ssr(_tmpl$13, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.redo && ssr(_tmpl$14, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), toolbar.removeFormat && ssr(_tmpl$15, ssrHydrationKey(), ssrAttribute("disabled", disabled, true)), ssrAttribute("contenteditable", !disabled, false), ssrAttribute("aria-label", escape(placeholder, true), false) + ssrAttribute("data-placeholder", escape(placeholder, true), false), value);
860
+ }
861
+ //#endregion
862
+ //#region src/components/shared/GroupCustomizer.tsx
863
+ var _tmpl$$2 = [
864
+ "<div",
865
+ " class=\"group-customizer__fields\">",
866
+ "</div>"
867
+ ];
868
+ var _tmpl$2$2 = [
869
+ "<div",
870
+ " class=\"group-customizer\"><div class=\"group-customizer__header\"><label class=\"group-customizer__label\">",
871
+ "</label><!--$-->",
872
+ "<!--/--></div><!--$-->",
873
+ "<!--/--><!--$-->",
874
+ "<!--/--><style>\n .group-customizer { border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-white); overflow: hidden; }\n .group-customizer__header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem; background: #f5f5f5; border-bottom: 1px solid var(--color-border); }\n .group-customizer__label { font-weight: 600; font-size: 0.875rem; color: var(--color-text); margin: 0; }\n .group-customizer__toggle { background: none; border: none; font-size: 1rem; cursor: pointer; color: var(--color-muted); padding: 0.25rem; border-radius: var(--radius-sm); transition: color 0.15s; }\n .group-customizer__toggle:hover { color: var(--color-primary); }\n .group-customizer__description { padding: 0.5rem 1rem; margin: 0; font-size: 0.8125rem; color: var(--color-muted); border-bottom: 1px solid var(--color-border); }\n .group-customizer__fields { padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }\n .group-customizer__field { display: flex; flex-direction: column; gap: 0.5rem; }\n </style></div>"
875
+ ];
876
+ var _tmpl$3$2 = [
877
+ "<button",
878
+ " type=\"button\" class=\"group-customizer__toggle\"",
879
+ ">",
880
+ "</button>"
881
+ ];
882
+ var _tmpl$4$2 = [
883
+ "<p",
884
+ " class=\"group-customizer__description\">",
885
+ "</p>"
886
+ ];
887
+ var _tmpl$5$2 = [
888
+ "<div",
889
+ " class=\"group-customizer__field\">",
890
+ "</div>"
891
+ ];
892
+ function GroupCustomizer(props) {
893
+ const { t } = useTranslation();
894
+ const { value, onChange, subFields, label, collapsible = true, defaultExpanded = true, description } = props;
895
+ const [expanded, setExpanded] = createSignal(defaultExpanded);
896
+ const [data, setData] = createSignal(value || {});
897
+ return ssr(_tmpl$2$2, ssrHydrationKey(), escape(label || "Grupo"), collapsible && ssr(_tmpl$3$2, ssrHydrationKey(), ssrAttribute("aria-label", expanded() ? "Colapsar" : "Expandir", false) + ssrAttribute("aria-expanded", escape(expanded(), true), false), expanded() ? "▲" : "▼"), description && ssr(_tmpl$4$2, ssrHydrationKey(), escape(description)), escape(createComponent(Show, {
898
+ get when() {
899
+ return expanded() || !collapsible;
900
+ },
901
+ get children() {
902
+ return ssr(_tmpl$$2, ssrHydrationKey(), escape(createComponent(For, {
903
+ each: subFields,
904
+ children: (field) => ssr(_tmpl$5$2, ssrHydrationKey(), escape(createComponent(FieldRendererFactory, {
905
+ get field() {
906
+ return {
907
+ ...field,
908
+ name: field.name
909
+ };
910
+ },
911
+ get value() {
912
+ return data()[field.name];
913
+ },
914
+ onChange: (val) => {
915
+ const next = {
916
+ ...data(),
917
+ [field.name]: val
918
+ };
919
+ setData(next);
920
+ onChange(next);
921
+ },
922
+ get subFields() {
923
+ return field.subFields;
924
+ },
925
+ get layouts() {
926
+ return field.layouts;
927
+ }
928
+ })))
929
+ })));
930
+ }
931
+ })));
932
+ }
933
+ //#endregion
934
+ //#region src/components/shared/FieldRendererFactory.tsx
935
+ var _tmpl$$1 = [
936
+ "<input",
937
+ " type=\"text\" class=\"input\"",
938
+ ">"
939
+ ];
940
+ var _tmpl$2$1 = [
941
+ "<textarea",
942
+ " class=\"input\" rows=\"4\"",
943
+ "></textarea>"
944
+ ];
945
+ var _tmpl$3$1 = [
946
+ "<input",
947
+ " type=\"number\" class=\"input\"",
948
+ ">"
949
+ ];
950
+ var _tmpl$4$1 = [
951
+ "<input",
952
+ " type=\"email\" class=\"input\"",
953
+ ">"
954
+ ];
955
+ var _tmpl$5$1 = [
956
+ "<input",
957
+ " type=\"url\" class=\"input\"",
958
+ ">"
959
+ ];
960
+ var _tmpl$6$1 = [
961
+ "<input",
962
+ " type=\"password\" class=\"input\"",
963
+ ">"
964
+ ];
965
+ var _tmpl$7$1 = [
966
+ "<input",
967
+ " type=\"color\" class=\"input\"",
968
+ ">"
969
+ ];
970
+ var _tmpl$8$1 = [
971
+ "<select",
972
+ " class=\"input\"",
973
+ "><option value>Select an option</option><!--$-->",
974
+ "<!--/--></select>"
975
+ ];
976
+ var _tmpl$9$1 = [
977
+ "<option",
978
+ ">",
979
+ "</option>"
980
+ ];
981
+ var _tmpl$0$1 = [
982
+ "<label",
983
+ " class=\"checkbox-label\"><input type=\"checkbox\"",
984
+ "> Enabled</label>"
985
+ ];
986
+ var _tmpl$1$1 = [
987
+ "<div",
988
+ " class=\"field-renderer__fallback\"><span>Unsupported field type: <!--$-->",
989
+ "<!--/--></span><!--$-->",
990
+ "<!--/--></div>"
991
+ ];
992
+ function SimpleInput(props) {
993
+ return ssr(_tmpl$$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value || "", true), false) + ssrAttribute("placeholder", escape(props.placeholder, true), false));
994
+ }
995
+ function TextareaInput(props) {
996
+ return ssr(_tmpl$2$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value || "", true), false) + ssrAttribute("placeholder", escape(props.field.placeholder, true), false));
997
+ }
998
+ function NumberInput(props) {
999
+ return ssr(_tmpl$3$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value || "", true), false) + ssrAttribute("min", escape(props.field.min, true), false) + ssrAttribute("max", escape(props.field.max, true), false) + ssrAttribute("step", escape(props.field.step, true), false));
1000
+ }
1001
+ function EmailInput(props) {
1002
+ return ssr(_tmpl$4$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value || "", true), false) + ssrAttribute("placeholder", escape(props.field.placeholder, true), false));
1003
+ }
1004
+ function UrlInput(props) {
1005
+ return ssr(_tmpl$5$1, ssrHydrationKey(), ssrAttribute("placeholder", escape(props.field.placeholder, true), false) + ssrAttribute("value", escape(props.value, true), false));
1006
+ }
1007
+ function PasswordInput(props) {
1008
+ return ssr(_tmpl$6$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value, true), false));
1009
+ }
1010
+ function SlugInput(props) {
1011
+ return ssr(_tmpl$$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value, true), false) + ssrAttribute("placeholder", escape(props.placeholder, true), false));
1012
+ }
1013
+ function ColorInput(props) {
1014
+ return ssr(_tmpl$7$1, ssrHydrationKey(), ssrAttribute("value", escape(props.value, true), false));
1015
+ }
1016
+ function SelectInput(props) {
1017
+ return ssr(_tmpl$8$1, ssrHydrationKey(), ssrAttribute("value", escape(String(props.value ?? ""), true), false), escape((props.field.options ?? []).map((option) => {
1018
+ const value = typeof option === "string" ? option : option.value;
1019
+ const label = typeof option === "string" ? option : option.label;
1020
+ return ssr(_tmpl$9$1, ssrHydrationKey() + ssrAttribute("value", escape(value, true), false), escape(label));
1021
+ })));
1022
+ }
1023
+ function CheckboxInput(props) {
1024
+ return ssr(_tmpl$0$1, ssrHydrationKey(), ssrAttribute("checked", props.value === true, true));
1025
+ }
1026
+ function FieldRendererFactory(props) {
1027
+ const { field, value, onChange } = props;
1028
+ const type = field.type;
1029
+ switch (type) {
1030
+ case "text": return createComponent(SimpleInput, {
1031
+ value: value || "",
1032
+ onChange,
1033
+ get placeholder() {
1034
+ return field.placeholder;
1035
+ }
1036
+ });
1037
+ case "textarea": return createComponent(TextareaInput, {
1038
+ field,
1039
+ value: value || "",
1040
+ onChange
1041
+ });
1042
+ case "number":
1043
+ case "range": return createComponent(NumberInput, {
1044
+ field,
1045
+ value: value || "",
1046
+ onChange
1047
+ });
1048
+ case "email": return createComponent(EmailInput, {
1049
+ field,
1050
+ value,
1051
+ onChange
1052
+ });
1053
+ case "url": return createComponent(UrlInput, {
1054
+ field,
1055
+ value,
1056
+ onChange
1057
+ });
1058
+ case "password": return createComponent(PasswordInput, {
1059
+ field,
1060
+ value,
1061
+ onChange
1062
+ });
1063
+ case "slug": return createComponent(SlugInput, {
1064
+ field,
1065
+ value,
1066
+ onChange,
1067
+ get placeholder() {
1068
+ return field.placeholder;
1069
+ }
1070
+ });
1071
+ case "select": return createComponent(SelectInput, {
1072
+ field,
1073
+ value,
1074
+ onChange
1075
+ });
1076
+ case "checkbox":
1077
+ case "toggle": return createComponent(CheckboxInput, {
1078
+ value,
1079
+ onChange
1080
+ });
1081
+ case "color":
1082
+ case "color_picker": return createComponent(ColorInput, {
1083
+ value,
1084
+ onChange
1085
+ });
1086
+ case "wysiwyg": return createComponent(RichTextEditor, {
1087
+ value,
1088
+ onChange,
1089
+ get placeholder() {
1090
+ return field.placeholder;
1091
+ },
1092
+ disabled: false
1093
+ });
1094
+ case "date_picker":
1095
+ case "date_time_picker":
1096
+ case "time_picker": return createComponent(DateTimeCustomizer, {
1097
+ type,
1098
+ value,
1099
+ onChange,
1100
+ get placeholder() {
1101
+ return field.placeholder;
1102
+ },
1103
+ get label() {
1104
+ return field.label;
1105
+ },
1106
+ get min() {
1107
+ return memo(() => field.min != null)() ? `${field.min}` : void 0;
1108
+ },
1109
+ get max() {
1110
+ return memo(() => field.max != null)() ? `${field.max}` : void 0;
1111
+ },
1112
+ get step() {
1113
+ return memo(() => field.step != null)() ? String(field.step) : void 0;
1114
+ }
1115
+ });
1116
+ case "google_map": return createComponent(GoogleMapCustomizer, {
1117
+ value,
1118
+ onChange,
1119
+ get placeholder() {
1120
+ return field.placeholder;
1121
+ },
1122
+ get label() {
1123
+ return field.label;
1124
+ }
1125
+ });
1126
+ case "link": return createComponent(LinkCustomizer, {
1127
+ value,
1128
+ onChange,
1129
+ get placeholder() {
1130
+ return field.placeholder;
1131
+ },
1132
+ get label() {
1133
+ return field.label;
1134
+ }
1135
+ });
1136
+ case "relationship":
1137
+ case "post_object": return createComponent(RelationshipCustomizer, {
1138
+ value,
1139
+ onChange,
1140
+ get postType() {
1141
+ return field.postType;
1142
+ },
1143
+ get multiple() {
1144
+ return field.multiple !== false;
1145
+ },
1146
+ get placeholder() {
1147
+ return field.placeholder;
1148
+ },
1149
+ get label() {
1150
+ return field.label;
1151
+ }
1152
+ });
1153
+ case "image":
1154
+ case "file":
1155
+ case "media": return createComponent(MediaPickerCustomizer, {
1156
+ value,
1157
+ onChange,
1158
+ get multiple() {
1159
+ return field.multiple;
1160
+ },
1161
+ get accept() {
1162
+ return field.accept;
1163
+ },
1164
+ get label() {
1165
+ return field.label;
1166
+ },
1167
+ get placeholder() {
1168
+ return field.placeholder;
1169
+ }
1170
+ });
1171
+ case "gallery": return createComponent(MediaPickerCustomizer, {
1172
+ value,
1173
+ onChange,
1174
+ multiple: true,
1175
+ get accept() {
1176
+ return field.accept;
1177
+ },
1178
+ get label() {
1179
+ return field.label;
1180
+ },
1181
+ get placeholder() {
1182
+ return field.placeholder;
1183
+ }
1184
+ });
1185
+ case "group": return createComponent(GroupCustomizer, {
1186
+ value,
1187
+ onChange,
1188
+ get subFields() {
1189
+ return field.subFields;
1190
+ },
1191
+ get label() {
1192
+ return field.label;
1193
+ },
1194
+ get collapsible() {
1195
+ return field.collapsible;
1196
+ },
1197
+ get defaultExpanded() {
1198
+ return field.defaultExpanded;
1199
+ }
1200
+ });
1201
+ case "taxonomy":
1202
+ case "user": return createComponent(EntitySelectorCustomizer, {
1203
+ get entityType() {
1204
+ return field.entityType ?? type;
1205
+ },
1206
+ value,
1207
+ onChange,
1208
+ get taxonomy() {
1209
+ return field.taxonomy;
1210
+ },
1211
+ get multiple() {
1212
+ return field.multiple !== false;
1213
+ },
1214
+ get placeholder() {
1215
+ return field.placeholder;
1216
+ },
1217
+ get label() {
1218
+ return field.label;
1219
+ }
1220
+ });
1221
+ case "repeater": return createComponent(RepeaterCustomizer, {
1222
+ get subFields() {
1223
+ return field.subFields;
1224
+ },
1225
+ value,
1226
+ onChange,
1227
+ get label() {
1228
+ return field.label;
1229
+ },
1230
+ get itemLabel() {
1231
+ return field.itemLabel;
1232
+ },
1233
+ get minRows() {
1234
+ return field.minRows;
1235
+ },
1236
+ get maxRows() {
1237
+ return field.maxRows;
1238
+ }
1239
+ });
1240
+ case "flexible_content": return createComponent(FlexibleContentCustomizer, {
1241
+ get layouts() {
1242
+ return field.layouts;
1243
+ },
1244
+ value,
1245
+ onChange,
1246
+ get label() {
1247
+ return field.label;
1248
+ },
1249
+ get minRows() {
1250
+ return field.minRows;
1251
+ },
1252
+ get maxRows() {
1253
+ return field.maxRows;
1254
+ }
1255
+ });
1256
+ default: return ssr(_tmpl$1$1, ssrHydrationKey(), escape(type), escape(createComponent(SimpleInput, {
1257
+ value: value || "",
1258
+ onChange,
1259
+ get placeholder() {
1260
+ return field.placeholder;
1261
+ }
1262
+ })));
1263
+ }
1264
+ }
1265
+ //#endregion
1266
+ //#region src/components/apps/themes/ThemeCustomizer.tsx
1267
+ var _tmpl$ = [
1268
+ "<div",
1269
+ " class=\"customizer__tab-panel\" role=\"tabpanel\">",
1270
+ "</div>"
1271
+ ];
1272
+ var _tmpl$2 = [
1273
+ "<div",
1274
+ "><div class=\"customizer__tabs\" role=\"tablist\">",
1275
+ "</div><div class=\"customizer__tab-panels\"><!--$-->",
1276
+ "<!--/--><!--$-->",
1277
+ "<!--/--></div></div>"
1278
+ ];
1279
+ var _tmpl$3 = [
1280
+ "<button",
1281
+ " class=\"",
1282
+ "\" role=\"tab\"",
1283
+ ">",
1284
+ "</button>"
1285
+ ];
1286
+ var _tmpl$4 = [
1287
+ "<div",
1288
+ " class=\"customizer__tab-panel\" role=\"tabpanel\"",
1289
+ ">",
1290
+ "</div>"
1291
+ ];
1292
+ var _tmpl$5 = [
1293
+ "<div",
1294
+ " class=\"customizer__field\"><label for=\"",
1295
+ "\">",
1296
+ "</label><!--$-->",
1297
+ "<!--/--></div>"
1298
+ ];
1299
+ var _tmpl$6 = [
1300
+ "<div",
1301
+ "><!--$-->",
1302
+ "<!--/--><!--$-->",
1303
+ "<!--/--></div>"
1304
+ ];
1305
+ var _tmpl$7 = [
1306
+ "<div",
1307
+ " class=\"customizer__accordion\">",
1308
+ "</div>"
1309
+ ];
1310
+ var _tmpl$8 = [
1311
+ "<p",
1312
+ " class=\"muted\">",
1313
+ "</p>"
1314
+ ];
1315
+ var _tmpl$9 = [
1316
+ "<span",
1317
+ " class=\"customizer__saved\">",
1318
+ "</span>"
1319
+ ];
1320
+ var _tmpl$0 = [
1321
+ "<div",
1322
+ " class=\"alert alert-error\">",
1323
+ "</div>"
1324
+ ];
1325
+ var _tmpl$1 = [
1326
+ "<div",
1327
+ " class=\"customizer__layout\"><aside class=\"customizer__panel\"><h3><!--$-->",
1328
+ "<!--/--> · <!--$-->",
1329
+ "<!--/--></h3><!--$-->",
1330
+ "<!--/--><!--$-->",
1331
+ "<!--/--><div class=\"customizer__actions\"><button class=\"btn btn-primary\"",
1332
+ ">",
1333
+ "</button><button class=\"btn btn-secondary\"",
1334
+ ">",
1335
+ "</button><button class=\"btn btn-secondary\">",
1336
+ "</button></div><!--$-->",
1337
+ "<!--/--><!--$-->",
1338
+ "<!--/--><p class=\"muted customizer__hint\">",
1339
+ "</p></aside><section class=\"customizer__preview\"><div class=\"customizer__preview-bar\"><input class=\"input\"",
1340
+ " placeholder=\"/\"",
1341
+ "></div><iframe class=\"customizer__frame\"",
1342
+ "></iframe></section></div>"
1343
+ ];
1344
+ var _tmpl$10 = [
1345
+ "<div",
1346
+ " class=\"customizer\"><!--$-->",
1347
+ "<!--/--><style>\n .customizer__layout {\n display: grid;\n grid-template-columns: minmax(280px, 340px) 1fr;\n gap: 1.25rem;\n align-items: start;\n }\n .customizer__panel {\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 1.25rem;\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n position: sticky;\n top: 1rem;\n }\n .customizer__panel h3 { margin: 0; font-size: 1rem; }\n .customizer__field { display: flex; flex-direction: column; gap: 0.3rem; }\n .customizer__field label { font-size: 0.75rem; font-weight: 600; color: var(--color-text); }\n .customizer__color { height: 2.25rem; padding: 0.15rem; }\n .customizer__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n .customizer__saved { font-size: 0.75rem; color: var(--color-success); }\n .customizer__hint { font-size: 0.75rem; margin: 0; }\n .customizer__preview {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n min-width: 0;\n }\n .customizer__preview-bar { display: flex; gap: 0.5rem; }\n .customizer__frame {\n width: 100%;\n height: min(72vh, 780px);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-white);\n }\n .alert-error {\n background: var(--color-error-soft);\n color: var(--color-error);\n border: 1px solid var(--color-error);\n padding: 0.75rem 1rem;\n border-radius: var(--radius-md);\n }\n .empty-state { padding: 3rem; text-align: center; color: var(--color-muted); }\n .skeleton { padding: 2rem; text-align: center; color: var(--color-muted); }\n </style></div>"
1348
+ ];
1349
+ var _tmpl$11 = ["<div", " class=\"skeleton\">Loading...</div>"];
1350
+ var _tmpl$12 = [
1351
+ "<div",
1352
+ " class=\"empty-state\"><!--$-->",
1353
+ "<!--/--> <a class=\"btn btn-secondary\" href=\"/themes\">",
1354
+ "</a></div>"
1355
+ ];
1356
+ var PREVIEW_DEBOUNCE_MS = 800;
1357
+ function defaultForField(field) {
1358
+ if (field.default !== void 0) return field.default;
1359
+ if (field.type === "checkbox") return false;
1360
+ if (field.type === "number") return 0;
1361
+ return "";
1362
+ }
1363
+ /** Convert a theme setting field to the factory configuration shape. */
1364
+ function toCustomFieldConfig(field) {
1365
+ const f = field;
1366
+ return {
1367
+ name: field.name,
1368
+ type: field.type ?? "text",
1369
+ label: field.label,
1370
+ default: field.default,
1371
+ options: field.options,
1372
+ required: field.required,
1373
+ placeholder: field.placeholder,
1374
+ min: field.min,
1375
+ max: field.max,
1376
+ step: field.step,
1377
+ minLength: field.minLength,
1378
+ maxLength: field.maxLength,
1379
+ pattern: field.pattern,
1380
+ postType: f.postType,
1381
+ multiple: f.multiple,
1382
+ accept: f.accept,
1383
+ entityType: f.entityType,
1384
+ taxonomy: f.taxonomy,
1385
+ itemLabel: f.itemLabel,
1386
+ minRows: f.minRows,
1387
+ maxRows: f.maxRows,
1388
+ collapsible: f.collapsible,
1389
+ defaultExpanded: f.defaultExpanded,
1390
+ subFields: field.subFields?.map(toCustomFieldConfig),
1391
+ layouts: field.layouts?.map((l) => ({
1392
+ name: l.name,
1393
+ label: l.label,
1394
+ subFields: l.subFields?.map(toCustomFieldConfig) || []
1395
+ }))
1396
+ };
1397
+ }
1398
+ /** Extract the theme ID from the `?theme=<id>` query string. */
1399
+ function getThemeIdFromQuery() {
1400
+ if (typeof window === "undefined") return null;
1401
+ return new URLSearchParams(window.location.search).get("theme");
1402
+ }
1403
+ function ThemeCustomizer() {
1404
+ const { t } = useTranslation();
1405
+ const [themes, setThemes] = createSignal([]);
1406
+ const [loading, setLoading] = createSignal(true);
1407
+ const [error, setError] = createSignal(null);
1408
+ const [draft, setDraft] = createSignal({});
1409
+ const [savedConfig, setSavedConfig] = createSignal({});
1410
+ const [saving, setSaving] = createSignal(false);
1411
+ const [saved, setSaved] = createSignal(false);
1412
+ const [previewPath, setPreviewPath] = createSignal("/");
1413
+ const [previewNonce, setPreviewNonce] = createSignal(0);
1414
+ const [selectedThemeId, setSelectedThemeId] = createSignal(null);
1415
+ const [activeTab, setActiveTab] = createSignal(null);
1416
+ let debounceHandle = null;
1417
+ const selectedTheme = createMemo(() => {
1418
+ const id = selectedThemeId();
1419
+ if (id) return themes().find((t) => t.id === id) ?? null;
1420
+ return themes().find((theme) => theme.status === "ACTIVE") ?? null;
1421
+ });
1422
+ const fields = createMemo(() => (selectedTheme()?.manifest?.settings ?? []).filter((field) => Boolean(field) && typeof field.name === "string").filter((field) => isFieldVisible(field, draft())));
1423
+ const fieldGroups = createMemo(() => {
1424
+ const groups = /* @__PURE__ */ new Map();
1425
+ const ungrouped = [];
1426
+ for (const field of fields()) {
1427
+ const group = field.group;
1428
+ if (group) {
1429
+ if (!groups.has(group)) groups.set(group, []);
1430
+ groups.get(group).push(field);
1431
+ } else ungrouped.push(field);
1432
+ }
1433
+ return {
1434
+ groups: Array.from(groups.entries()).sort((a, b) => {
1435
+ return (a[1][0].groupOrder ?? 0) - (b[1][0].groupOrder ?? 0);
1436
+ }),
1437
+ ungrouped
1438
+ };
1439
+ });
1440
+ const dirty = createMemo(() => JSON.stringify(draft()) !== JSON.stringify(savedConfig()));
1441
+ onMount(async () => {
1442
+ const queryThemeId = getThemeIdFromQuery();
1443
+ if (queryThemeId) setSelectedThemeId(queryThemeId);
1444
+ await load();
1445
+ });
1446
+ async function load() {
1447
+ setError(null);
1448
+ try {
1449
+ setLoading(true);
1450
+ const data = await apiClient.getThemes();
1451
+ setThemes(data);
1452
+ let targetTheme = data.find((t) => t.id === selectedThemeId()) ?? null;
1453
+ if (!targetTheme) targetTheme = data.find((theme) => theme.status === "ACTIVE") ?? null;
1454
+ if (!targetTheme) {
1455
+ setError(t("customizer.noTheme"));
1456
+ return;
1457
+ }
1458
+ setSelectedThemeId(targetTheme.id);
1459
+ const firstGroup = targetTheme.manifest?.settings?.find((f) => f.group);
1460
+ if (firstGroup && firstGroup.group) setActiveTab(firstGroup.group);
1461
+ const config = targetTheme.config ?? {};
1462
+ setSavedConfig(config);
1463
+ const initial = {};
1464
+ for (const field of targetTheme.manifest?.settings ?? []) initial[field.name] = config[field.name] !== void 0 ? config[field.name] : defaultForField(field);
1465
+ setDraft(initial);
1466
+ } catch {
1467
+ setError(t("customizer.loadError"));
1468
+ } finally {
1469
+ setLoading(false);
1470
+ }
1471
+ }
1472
+ function setDraftValue(name, value) {
1473
+ setDraft({
1474
+ ...draft(),
1475
+ [name]: value
1476
+ });
1477
+ setSaved(false);
1478
+ schedulePreview();
1479
+ }
1480
+ /** Debounced iframe reload — typing re-renders the preview without spamming. */
1481
+ function schedulePreview() {
1482
+ if (debounceHandle) clearTimeout(debounceHandle);
1483
+ debounceHandle = setTimeout(() => setPreviewNonce((nonce) => nonce + 1), PREVIEW_DEBOUNCE_MS);
1484
+ }
1485
+ const previewUrl = () => {
1486
+ const base = previewPath() || "/";
1487
+ const encoded = encodeURIComponent(JSON.stringify(draft()));
1488
+ const separator = base.includes("?") ? "&" : "?";
1489
+ const themeName = selectedTheme()?.name;
1490
+ return `${base}${separator}preview_settings=${encoded}${themeName ? `&preview_theme=${encodeURIComponent(themeName)}` : ""}&_=${previewNonce()}`;
1491
+ };
1492
+ const settingsPanel = createMemo(() => {
1493
+ const groups = fieldGroups();
1494
+ if (groups.groups.length > 0) return ssr(_tmpl$2, ssrHydrationKey(), escape(groups.groups.map(([groupName]) => ssr(_tmpl$3, ssrHydrationKey(), `customizer__tab ${activeTab() === groupName ? "active" : ""}`, ssrAttribute("aria-selected", escape(activeTab(), true) === escape(groupName, true), false), escape(groupName)))), escape(groups.groups.map(([groupName, groupFields]) => ssr(_tmpl$4, ssrHydrationKey(), ssrAttribute("hidden", activeTab() !== groupName, true), escape(createComponent(For, {
1495
+ each: groupFields,
1496
+ children: (field) => {
1497
+ const config = toCustomFieldConfig(field);
1498
+ return ssr(_tmpl$5, ssrHydrationKey(), `customizer-${escape(field.name, true)}`, escape(field.label || field.name), escape(createComponent(FieldRendererFactory, {
1499
+ field: config,
1500
+ get value() {
1501
+ return draft()[field.name];
1502
+ },
1503
+ onChange: (val) => setDraftValue(field.name, val)
1504
+ })));
1505
+ }
1506
+ }))))), escape(createComponent(Show, {
1507
+ get when() {
1508
+ return groups.ungrouped.length > 0;
1509
+ },
1510
+ get children() {
1511
+ return ssr(_tmpl$, ssrHydrationKey(), escape(createComponent(For, {
1512
+ get each() {
1513
+ return groups.ungrouped;
1514
+ },
1515
+ children: (field) => {
1516
+ const config = toCustomFieldConfig(field);
1517
+ return ssr(_tmpl$5, ssrHydrationKey(), `customizer-${escape(field.name, true)}`, escape(field.label || field.name), escape(createComponent(FieldRendererFactory, {
1518
+ field: config,
1519
+ get value() {
1520
+ return draft()[field.name];
1521
+ },
1522
+ onChange: (val) => setDraftValue(field.name, val)
1523
+ })));
1524
+ }
1525
+ })));
1526
+ }
1527
+ })));
1528
+ return ssr(_tmpl$6, ssrHydrationKey(), groups.groups.length === 1 && groups.groups[0] && ssr(_tmpl$7, ssrHydrationKey(), escape(createComponent(For, {
1529
+ get each() {
1530
+ return groups.groups[0][1];
1531
+ },
1532
+ children: (field) => {
1533
+ const config = toCustomFieldConfig(field);
1534
+ return ssr(_tmpl$5, ssrHydrationKey(), `customizer-${escape(field.name, true)}`, escape(field.label || field.name), escape(createComponent(FieldRendererFactory, {
1535
+ field: config,
1536
+ get value() {
1537
+ return draft()[field.name];
1538
+ },
1539
+ onChange: (val) => setDraftValue(field.name, val)
1540
+ })));
1541
+ }
1542
+ }))), groups.ungrouped.length > 0 && escape(createComponent(For, {
1543
+ get each() {
1544
+ return groups.ungrouped;
1545
+ },
1546
+ children: (field) => {
1547
+ const config = toCustomFieldConfig(field);
1548
+ return ssr(_tmpl$5, ssrHydrationKey(), `customizer-${escape(field.name, true)}`, escape(field.label || field.name), escape(createComponent(FieldRendererFactory, {
1549
+ field: config,
1550
+ get value() {
1551
+ return draft()[field.name];
1552
+ },
1553
+ onChange: (val) => setDraftValue(field.name, val)
1554
+ })));
1555
+ }
1556
+ })));
1557
+ });
1558
+ return ssr(_tmpl$10, ssrHydrationKey(), escape(createComponent(Show, {
1559
+ get when() {
1560
+ return !loading();
1561
+ },
1562
+ get fallback() {
1563
+ return ssr(_tmpl$11, ssrHydrationKey());
1564
+ },
1565
+ get children() {
1566
+ return createComponent(Show, {
1567
+ get when() {
1568
+ return selectedTheme();
1569
+ },
1570
+ get fallback() {
1571
+ return ssr(_tmpl$12, ssrHydrationKey(), escape(t("customizer.noTheme")), escape(t("customizer.goToThemes")));
1572
+ },
1573
+ get children() {
1574
+ return ssr(_tmpl$1, ssrHydrationKey(), escape(selectedTheme().name), escape(t("customizer.title")), escape(createComponent(Show, {
1575
+ get when() {
1576
+ return fields().length === 0;
1577
+ },
1578
+ get children() {
1579
+ return ssr(_tmpl$8, ssrHydrationKey(), escape(t("customizer.noSettings")));
1580
+ }
1581
+ })), escape(settingsPanel()), ssrAttribute("disabled", saving() || !dirty(), true), saving() ? escape(t("customizer.saving")) : escape(t("customizer.save")), ssrAttribute("disabled", !dirty(), true), escape(t("customizer.reset")), escape(t("customizer.refreshPreview")), escape(createComponent(Show, {
1582
+ get when() {
1583
+ return saved();
1584
+ },
1585
+ get children() {
1586
+ return ssr(_tmpl$9, ssrHydrationKey(), escape(t("customizer.saved")));
1587
+ }
1588
+ })), escape(createComponent(Show, {
1589
+ get when() {
1590
+ return error();
1591
+ },
1592
+ get children() {
1593
+ return ssr(_tmpl$0, ssrHydrationKey(), escape(error()));
1594
+ }
1595
+ })), escape(t("customizer.previewHint")), ssrAttribute("value", escape(previewPath(), true), false), ssrAttribute("aria-label", escape(t("customizer.previewPath"), true), false), ssrAttribute("title", escape(t("customizer.previewTitle"), true), false) + ssrAttribute("src", escape(previewUrl(), true), false));
1596
+ }
1597
+ });
1598
+ }
1599
+ })));
1600
+ }
1601
+ //#endregion
1602
+ //#region src/pages/customize.astro
1603
+ var customize_exports = /* @__PURE__ */ __exportAll({
1604
+ default: () => $$Customize,
1605
+ file: () => $$file,
1606
+ url: () => $$url
1607
+ });
1608
+ createAstro("https://astro.build");
1609
+ var $$Customize = createComponent$1(($$result, $$props, $$slots) => {
1610
+ const Astro = $$result.createAstro($$props, $$slots);
1611
+ Astro.self = $$Customize;
1612
+ const { t } = Astro.locals;
1613
+ return renderTemplate`${renderComponent($$result, "DashboardLayout", $$DashboardLayout, { "title": t("customizer.title") }, { "default": ($$result) => renderTemplate`${renderComponent($$result, "PageHeader", PageHeader, {
1614
+ "title": t("customizer.title"),
1615
+ "description": t("customizer.description")
1616
+ })}${renderComponent($$result, "ThemeCustomizer", ThemeCustomizer, {
1617
+ "client:load": true,
1618
+ "client:component-hydration": "load",
1619
+ "client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/apps/themes/ThemeCustomizer.tsx",
1620
+ "client:component-export": "ThemeCustomizer"
1621
+ })}` })}`;
1622
+ }, "/home/runner/work/cms/cms/apps/admin/src/pages/customize.astro", void 0);
1623
+ var $$file = "/home/runner/work/cms/cms/apps/admin/src/pages/customize.astro";
1624
+ var $$url = "/customize";
1625
+ //#endregion
1626
+ //#region \0virtual:astro:page:src/pages/customize@_@astro
1627
+ var page = () => customize_exports;
1628
+ //#endregion
1629
+ export { page };