@opengis/cms 0.0.56 → 0.0.58

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 (149) hide show
  1. package/README.md +131 -131
  2. package/dist/AddNewItemInTree-05PSSEFi.js +76 -0
  3. package/dist/ArticlesPage-CFjE_cw_.js +298 -0
  4. package/dist/CollectionsBreadcrumb-BCxeRikP.js +4 -0
  5. package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-umRzB5mY.js +53 -0
  6. package/dist/CollectionsPage-DHfPNql6.js +124 -0
  7. package/dist/{CreateForm-BMOBeP4G.js → CreateForm-5FvT45vH.js} +1 -1
  8. package/dist/Dashboard-C1eGscNd.js +358 -0
  9. package/dist/EditCollectionPage-DIr1tdtn.js +187 -0
  10. package/dist/{EmptyData-DaZt_nAm.js → EmptyData-DxPrSXhV.js} +1 -1
  11. package/dist/{MenuAddPage-Bf48Z-ah.js → MenuAddPage-D-p3gFgm.js} +40 -35
  12. package/dist/MenuBody-rN5j4YBu.js +125 -0
  13. package/dist/MenuItemPage-BoJw885D.js +1027 -0
  14. package/dist/MenuList-DFEBS0NB.js +172 -0
  15. package/dist/MenuPage-BCZB_S8j.js +107 -0
  16. package/dist/MenuWrapper-AZ_8s-zd.js +12 -0
  17. package/dist/MonacoEditor-Db-3Jc3E.js +4 -0
  18. package/dist/{UniversalTable.vue_vue_type_script_setup_true_lang-CJGTsd1V.js → UniversalTable-CzqPG-tY.js} +12 -12
  19. package/dist/{UniversalTablePagination.vue_vue_type_script_setup_true_lang-GYZd_gkA.js → UniversalTablePagination-4gL47A7I.js} +1 -1
  20. package/dist/VsFormTags-CMjiu9sY.js +114 -0
  21. package/dist/VsPreview-DwETkOpb.js +63 -0
  22. package/dist/contentForm-CtMhQTG0.js +489 -0
  23. package/dist/getField-CpwVE28P.js +179 -0
  24. package/dist/index.d.ts +8 -0
  25. package/dist/index.html +29 -29
  26. package/dist/index.js +72 -71
  27. package/dist/style.css +1 -1
  28. package/dist/vs-builder-edit-D-q1o8tF.js +604 -0
  29. package/dist/vs-builder-monaco-B3Jj0V31.js +33 -0
  30. package/dist/vs-builder-preview-BH4VAM3a.js +44 -0
  31. package/dist/vs-form-custom-datatable-BDZo48w3.js +317 -0
  32. package/dist/vs-form-integer-BZ855R3g.js +61 -0
  33. package/dist/vs-form-media-select-NY27EaG1.js +837 -0
  34. package/dist/vs-form-reference-list-Dtv8fJJU.js +1536 -0
  35. package/dist/vs-form-reletion-link-BhzNQszm.js +34 -0
  36. package/dist/vs-form-tiptap-DDFQjRjY.js +4 -0
  37. package/dist/vs-form-tiptap.vue_vue_type_script_setup_true_lang-DGgsqXwg.js +11 -0
  38. package/dist/vs-richtext-md-C098v_6Q.js +4 -0
  39. package/dist/vs-richtext-md.vue_vue_type_script_setup_true_lang-Ct8uTV-J.js +14 -0
  40. package/input-types.json +9 -9
  41. package/locales/en.json +815 -814
  42. package/locales/uk.json +813 -812
  43. package/module/cms/cls/content.status.json +17 -17
  44. package/module/cms/cls/user_type.json +9 -9
  45. package/module/cms/form/admin.users.form.json +77 -77
  46. package/module/cms/select/cms.page_type.sql +1 -1
  47. package/module/cms/select/news_tag_id.sql +11 -11
  48. package/module/cms/table/admin.users.table.json +53 -53
  49. package/module/cms/table/collection.default.table.json +96 -96
  50. package/module/cms/table/single.default.table.json +116 -116
  51. package/package.json +68 -68
  52. package/plugin.js +43 -43
  53. package/server/app.js +35 -35
  54. package/server/config.js +4 -4
  55. package/server/functions/getContent.js +45 -45
  56. package/server/functions/getDraftKey.js +22 -22
  57. package/server/functions/getSearchData.js +31 -31
  58. package/server/functions/getTags.js +30 -30
  59. package/server/functions/getUser.js +27 -27
  60. package/server/functions/utils/mock.reply.js +55 -55
  61. package/server/index.js +22 -22
  62. package/server/migrations/fixes.sql +129 -129
  63. package/server/migrations/site.sql +595 -595
  64. package/server/plugins/adminHook.js +78 -78
  65. package/server/plugins/hook.js +59 -59
  66. package/server/plugins/vite.js +75 -75
  67. package/server/routes/category/controllers/cms.category.delete.js +21 -21
  68. package/server/routes/category/controllers/cms.category.get.js +17 -17
  69. package/server/routes/category/controllers/cms.category.list.js +16 -16
  70. package/server/routes/category/controllers/cms.category.post.js +21 -21
  71. package/server/routes/category/controllers/cms.category.put.js +23 -23
  72. package/server/routes/category/index.mjs +22 -22
  73. package/server/routes/cms/controllers/cmsStat.js +55 -55
  74. package/server/routes/cms/controllers/cmsSuggest.js +57 -57
  75. package/server/routes/cms/controllers/deleteContent.js +113 -113
  76. package/server/routes/cms/controllers/deleteMedia.js +76 -76
  77. package/server/routes/cms/controllers/downloadMedia.js +84 -84
  78. package/server/routes/cms/controllers/getContent.js +113 -113
  79. package/server/routes/cms/controllers/getContentBySlug.js +93 -93
  80. package/server/routes/cms/controllers/insertContent.js +217 -217
  81. package/server/routes/cms/controllers/listMedia.js +155 -155
  82. package/server/routes/cms/controllers/metadataMedia.js +39 -39
  83. package/server/routes/cms/controllers/properties.get.js +18 -18
  84. package/server/routes/cms/controllers/properties.post.js +99 -99
  85. package/server/routes/cms/controllers/searchContent.js +214 -214
  86. package/server/routes/cms/controllers/translate.js +89 -89
  87. package/server/routes/cms/controllers/updateContent.js +266 -264
  88. package/server/routes/cms/controllers/uploadMedia.js +79 -79
  89. package/server/routes/cms/functions/getSettings.js +48 -48
  90. package/server/routes/cms/index.mjs +112 -112
  91. package/server/routes/cms/utils/additionalData.js +35 -35
  92. package/server/routes/cms/utils/getCollection.js +89 -89
  93. package/server/routes/cms/utils/getSingle.js +188 -183
  94. package/server/routes/cms/utils/inputTypes.js +5 -5
  95. package/server/routes/cms/utils/insertContentLocalization.js +104 -104
  96. package/server/routes/cms/utils/requestTranslation.js +85 -85
  97. package/server/routes/cms/utils/updateLocalization.js +47 -47
  98. package/server/routes/cmsSpace/controllers/deleteSpace.js +25 -25
  99. package/server/routes/cmsSpace/controllers/getSpaces.js +27 -27
  100. package/server/routes/cmsSpace/controllers/insertSpace.js +21 -21
  101. package/server/routes/cmsSpace/controllers/updateSpace.js +23 -23
  102. package/server/routes/cmsSpace/index.mjs +20 -20
  103. package/server/routes/contentType/controllers/addContentType.js +160 -160
  104. package/server/routes/contentType/controllers/contentTypeList.js +54 -54
  105. package/server/routes/contentType/controllers/delContentType.js +75 -75
  106. package/server/routes/contentType/controllers/editContentType.js +88 -81
  107. package/server/routes/contentType/controllers/getContentType.js +65 -57
  108. package/server/routes/contentType/index.mjs +35 -35
  109. package/server/routes/contentType/utils/updateContents.js +44 -44
  110. package/server/routes/contentType/utils/updateCustomContentTable.js +53 -53
  111. package/server/routes/feedback/controllers/email.list.js +24 -24
  112. package/server/routes/feedback/controllers/feedback.js +48 -48
  113. package/server/routes/feedback/controllers/feedback.list.js +37 -37
  114. package/server/routes/feedback/controllers/news.subscriptions.js +44 -44
  115. package/server/routes/feedback/index.mjs +71 -71
  116. package/server/routes/logs/controllers/export.user.logs.js +77 -77
  117. package/server/routes/logs/controllers/user.logs.js +44 -44
  118. package/server/routes/logs/index.mjs +9 -9
  119. package/server/routes/menu/controllers/addMenu.js +37 -37
  120. package/server/routes/menu/controllers/delMenu.js +31 -31
  121. package/server/routes/menu/controllers/editMenu.js +41 -41
  122. package/server/routes/menu/controllers/getMenu.js +24 -24
  123. package/server/routes/menu/functions/getMenu.js +50 -50
  124. package/server/routes/menu/index.mjs +13 -13
  125. package/server/routes/migration/controllers/collectionToCustom.js +137 -137
  126. package/server/routes/migration/index.mjs +8 -8
  127. package/server/routes/root.mjs +8 -8
  128. package/server/routes/tags/controllers/add.tags.js +24 -24
  129. package/server/routes/tags/controllers/del.tags.js +19 -19
  130. package/server/routes/tags/controllers/edit.tags.js +25 -25
  131. package/server/routes/tags/controllers/get.tags.js +15 -15
  132. package/server/routes/tags/index.mjs +14 -14
  133. package/server/templates/cls/cms.category_type.json +9 -9
  134. package/server/templates/cls/cms.content_review_status.json +9 -9
  135. package/server/templates/cls/cms.content_status.json +9 -9
  136. package/server/templates/cls/cms.content_type.json +9 -9
  137. package/server/templates/cls/cms.lang.json +9 -9
  138. package/server/templates/page/login.html +126 -126
  139. package/utils.d.ts +52 -52
  140. package/utils.js +8 -8
  141. package/dist/ArticlesPage-BcR1hbds.js +0 -286
  142. package/dist/BuilderPage-CK_osM89.js +0 -386
  143. package/dist/CollectionsBreadcrumb.vue_vue_type_script_setup_true_lang-CnOe9ORD.js +0 -45
  144. package/dist/CollectionsPage-JfmrHNR_.js +0 -110
  145. package/dist/EditCollectionPage-Cw3GQYRe.js +0 -809
  146. package/dist/MenuItemPage-CXn5HC8j.js +0 -1366
  147. package/dist/MenuPage-tJZtK46W.js +0 -106
  148. package/dist/contentForm-B6gHgGkz.js +0 -586
  149. package/dist/getField-Y5WXnRR0.js +0 -2948
@@ -0,0 +1,53 @@
1
+ import { defineComponent as b, openBlock as e, createElementBlock as t, createElementVNode as s, createVNode as c, unref as n, toDisplayString as u, Fragment as r, createBlock as x, createCommentVNode as k, renderList as h } from "vue";
2
+ import { Layers as g, ChevronRight as i } from "lucide-vue-next";
3
+ const p = { class: "flex items-center space-x-1 mb-4 overflow-hidden" }, w = { class: "truncate block max-w-[12rem]" }, f = ["onClick"], v = { class: "truncate block max-w-[20rem]" }, y = {
4
+ key: 1,
5
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium text-slate-700 dark:text-slate-300 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis"
6
+ }, C = { class: "truncate block max-w-[20rem]" }, V = /* @__PURE__ */ b({
7
+ __name: "CollectionsBreadcrumb",
8
+ props: {
9
+ items: {},
10
+ loading: { type: Boolean }
11
+ },
12
+ emits: ["navigate"],
13
+ setup(a) {
14
+ return (d, l) => (e(), t("div", p, [
15
+ s("button", {
16
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium transition-all duration-200 text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis",
17
+ onClick: l[0] || (l[0] = (o) => d.$emit("navigate", "collections"))
18
+ }, [
19
+ c(n(g), { class: "w-3 h-3 flex-shrink-0" }),
20
+ s("span", w, u(d.$t("cms.navigation.collections")), 1)
21
+ ]),
22
+ a.loading ? (e(), t(r, { key: 0 }, [
23
+ c(n(i), { class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0" }),
24
+ l[1] || (l[1] = s("div", { class: "h-7 w-24 rounded bg-slate-200 dark:bg-slate-700 animate-pulse" }, null, -1)),
25
+ c(n(i), { class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0" }),
26
+ l[2] || (l[2] = s("div", { class: "h-7 w-20 rounded bg-slate-200 dark:bg-slate-700 animate-pulse" }, null, -1))
27
+ ], 64)) : (e(), t(r, { key: 1 }, [
28
+ a.items.length > 0 ? (e(), x(n(i), {
29
+ key: 0,
30
+ class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0"
31
+ })) : k("", !0),
32
+ (e(!0), t(r, null, h(a.items, (o, m) => (e(), t(r, { key: m }, [
33
+ m < a.items.length - 1 ? (e(), t("button", {
34
+ key: 0,
35
+ class: "flex gap-x-1 items-center px-2 py-1 rounded text-sm font-medium transition-all duration-200 text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/20 hover:bg-blue-100 dark:hover:bg-blue-900/30 min-w-0 overflow-hidden whitespace-nowrap text-ellipsis",
36
+ onClick: (B) => d.$emit("navigate", o.route)
37
+ }, [
38
+ s("span", v, u(o.label), 1)
39
+ ], 8, f)) : (e(), t("span", y, [
40
+ s("span", C, u(o.label), 1)
41
+ ])),
42
+ m < a.items.length - 1 ? (e(), x(n(i), {
43
+ key: 2,
44
+ class: "w-3 h-3 text-slate-400 dark:text-slate-500 flex-shrink-0"
45
+ })) : k("", !0)
46
+ ], 64))), 128))
47
+ ], 64))
48
+ ]));
49
+ }
50
+ });
51
+ export {
52
+ V as _
53
+ };
@@ -0,0 +1,124 @@
1
+ import { defineComponent as E, defineAsyncComponent as f, inject as L, ref as u, computed as V, onMounted as B, openBlock as i, createElementBlock as n, createElementVNode as e, toDisplayString as a, unref as r, createVNode as d, withDirectives as F, vModelText as A, Fragment as y, renderList as v, createStaticVNode as D, createBlock as _ } from "vue";
2
+ import { useRouter as N } from "vue-router";
3
+ import { HelpCircle as S, Search as M, File as R, Layers as T, ChevronRight as q } from "lucide-vue-next";
4
+ import { useI18n as H } from "vue-i18n";
5
+ const I = { class: "space-y-6 mx-auto max-w-[90%]" }, P = { class: "flex items-center justify-between mb-8" }, Q = { class: "flex gap-4" }, U = { class: "text-3xl font-bold text-slate-800 dark:text-slate-100 mb-2" }, z = { class: "text-slate-600 dark:text-slate-300" }, G = ["href", "title"], J = { class: "flex items-center gap-3" }, K = { class: "relative w-full max-w-sm" }, O = { class: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none" }, W = ["placeholder"], X = {
6
+ key: 0,
7
+ class: "grid grid-cols-1 gap-4 mb-6 md:grid-cols-2 lg:grid-cols-3"
8
+ }, Y = { key: 1 }, Z = { class: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6" }, ee = ["onClick"], te = { class: "flex items-start justify-between" }, se = { class: "flex items-start gap-3" }, oe = { class: "text-sm font-semibold text-gray-800 mb-1" }, le = { class: "flex items-center gap-2" }, ie = { class: "text-xs text-gray-500 whitespace-nowrap" }, re = { class: "pl-8 text-xs text-gray-600 line-clamp-2" }, ne = {
9
+ key: 2,
10
+ class: "flex items-center justify-center min-h-[400px]"
11
+ }, pe = /* @__PURE__ */ E({
12
+ __name: "CollectionsPage",
13
+ setup(ae) {
14
+ const x = f(
15
+ () => import("./EmptyData-DxPrSXhV.js")
16
+ ), b = f(
17
+ () => import("./CreateForm-5FvT45vH.js")
18
+ ), { t: de, locale: w } = H(), k = N();
19
+ L("fetchContentTypes");
20
+ const h = u([]), c = u(""), g = u(!0), p = V(() => {
21
+ const s = h.value.filter(
22
+ (t) => t.type !== "single"
23
+ ), l = c.value.trim().toLowerCase();
24
+ return [...l ? s.filter((t) => [t == null ? void 0 : t.title, t == null ? void 0 : t.name, t == null ? void 0 : t.id, t == null ? void 0 : t.description].filter(Boolean).join(" ").toLowerCase().includes(l)) : s].sort((t, m) => t.id === "pages" ? -1 : m.id === "pages" ? 1 : 0);
25
+ });
26
+ async function C() {
27
+ try {
28
+ const s = await fetch("/api/cms-type?type=collection");
29
+ if (!s.ok)
30
+ throw new Error("Failed to fetch collections");
31
+ const l = await s.json();
32
+ h.value = l.rows || [];
33
+ } catch (s) {
34
+ console.error("Error fetching collections:", s);
35
+ } finally {
36
+ g.value = !1;
37
+ }
38
+ }
39
+ const $ = (s) => {
40
+ k.push(`/collections/${s.id}`);
41
+ };
42
+ return B(() => {
43
+ C();
44
+ }), (s, l) => (i(), n("div", I, [
45
+ e("div", P, [
46
+ e("div", Q, [
47
+ e("div", null, [
48
+ e("h1", U, a(s.$t("cms.navigation.collections")), 1),
49
+ e("p", z, a(s.$t("cms.collections.selectCollection")), 1)
50
+ ]),
51
+ e("a", {
52
+ href: `https://cms.opengis.info/${r(w)}/guides/collections/`,
53
+ target: "_blank",
54
+ title: s.$t("cms.guide.collections"),
55
+ class: "mt-2"
56
+ }, [
57
+ d(r(S), { class: "w-5 h-5" })
58
+ ], 8, G)
59
+ ]),
60
+ e("div", J, [
61
+ e("div", K, [
62
+ e("div", O, [
63
+ d(r(M), { class: "w-5 h-5 text-gray-400" })
64
+ ]),
65
+ F(e("input", {
66
+ "onUpdate:modelValue": l[0] || (l[0] = (o) => c.value = o),
67
+ type: "text",
68
+ class: "block w-full py-2 pl-10 pr-3 leading-5 text-gray-900 placeholder-gray-500 transition-colors bg-white border border-gray-300 rounded-md dark:border-gray-600 dark:bg-gray-700 dark:placeholder-gray-400 focus:outline-none focus:ring-sky-500 focus:border-sky-500 dark:text-white sm:text-sm",
69
+ placeholder: s.$t("cms.collections.searchCollections")
70
+ }, null, 8, W), [
71
+ [A, c.value]
72
+ ])
73
+ ]),
74
+ d(r(b), {
75
+ redirectAfterCreate: (o) => `/collections/${o.id}`
76
+ }, null, 8, ["redirectAfterCreate"])
77
+ ])
78
+ ]),
79
+ g.value ? (i(), n("div", X, [
80
+ (i(), n(y, null, v(6, (o) => e("div", {
81
+ key: o,
82
+ class: "rounded-lg border border-gray-200 bg-white p-4 animate-pulse"
83
+ }, [...l[1] || (l[1] = [
84
+ D('<div class="flex items-start justify-between"><div class="flex items-start gap-3 flex-1"><div class="h-5 w-5 rounded bg-gray-200 shrink-0"></div><div class="flex-1 space-y-2"><div class="h-4 w-32 rounded bg-gray-200"></div><div class="h-3 w-20 rounded bg-gray-100"></div></div></div><div class="h-4 w-16 rounded bg-gray-100"></div></div>', 1)
85
+ ])])), 64))
86
+ ])) : p.value.length > 0 ? (i(), n("div", Y, [
87
+ e("div", Z, [
88
+ (i(!0), n(y, null, v(p.value, (o) => (i(), n("button", {
89
+ key: o.id,
90
+ onClick: (j) => $(o),
91
+ class: "w-full border border-gray-200 bg-white rounded-lg p-4 text-left hover:shadow-md transition-all hover:border-gray-300"
92
+ }, [
93
+ e("div", null, [
94
+ e("div", te, [
95
+ e("div", se, [
96
+ o.id === "pages" ? (i(), _(r(R), {
97
+ key: 0,
98
+ class: "shrink-0 lucide lucide-page w-5 h-5 text-blue-600"
99
+ })) : (i(), _(r(T), {
100
+ key: 1,
101
+ class: "shrink-0 lucide lucide-layers w-5 h-5 text-blue-600"
102
+ })),
103
+ e("div", null, [
104
+ e("h4", oe, a(o.title), 1)
105
+ ])
106
+ ]),
107
+ e("div", le, [
108
+ e("span", ie, a(o.entries) + " записів", 1),
109
+ d(r(q), { class: "w-4 h-4 text-gray-400" })
110
+ ])
111
+ ]),
112
+ e("p", re, a(o.description || "Опис відсутній"), 1)
113
+ ])
114
+ ], 8, ee))), 128))
115
+ ])
116
+ ])) : (i(), n("div", ne, [
117
+ d(r(x))
118
+ ]))
119
+ ]));
120
+ }
121
+ });
122
+ export {
123
+ pe as default
124
+ };
@@ -121,5 +121,5 @@ const O = { class: "flex justify-end p-[20px] gap-[10px] border-t w-full" }, D =
121
121
  }
122
122
  };
123
123
  export {
124
- D as _
124
+ D as default
125
125
  };
@@ -0,0 +1,358 @@
1
+ import { defineComponent as b, resolveComponent as S, openBlock as d, createElementBlock as u, createElementVNode as e, toDisplayString as i, unref as m, createVNode as l, withCtx as A, createTextVNode as g, normalizeClass as x, createBlock as f, resolveDynamicComponent as j, Fragment as _, renderList as k, ref as P, onMounted as I } from "vue";
2
+ import { HelpCircle as T, Plus as L, FileText as v, Users as w, Image as U, Eye as F, Calendar as N, SquarePen as R, Activity as V, Zap as z } from "lucide-vue-next";
3
+ import { useI18n as $ } from "vue-i18n";
4
+ import { useRouter as M } from "vue-router";
5
+ const B = { class: "flex items-center justify-between" }, E = { class: "flex items-center gap-2" }, q = { class: "text-4xl font-bold text-slate-800 dark:text-slate-100 mb-2" }, H = ["href", "title"], J = { class: "text-lg text-slate-600 dark:text-slate-300" }, O = /* @__PURE__ */ b({
6
+ __name: "DashboardHeader",
7
+ setup(o) {
8
+ const { locale: s } = $();
9
+ return (r, a) => {
10
+ const n = S("router-link");
11
+ return d(), u("div", B, [
12
+ e("div", null, [
13
+ e("div", E, [
14
+ e("h1", q, i(r.$t("cms.dashboard.title")), 1),
15
+ e("a", {
16
+ href: `https://cms.opengis.info/${m(s)}/get-started/app-overview`,
17
+ target: "_blank",
18
+ title: r.$t("cms.guide.appOverview")
19
+ }, [
20
+ l(m(T), { class: "w-5 h-5" })
21
+ ], 8, H)
22
+ ]),
23
+ e("div", J, i(r.$t("cms.dashboard.description")), 1)
24
+ ]),
25
+ e("div", null, [
26
+ l(n, {
27
+ to: "/settings/collections",
28
+ class: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 shadow h-9 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white"
29
+ }, {
30
+ default: A(() => [
31
+ l(m(L), { class: "w-4 h-4 mr-2" }),
32
+ g(" " + i(r.$t("cms.dashboard.newCollection")), 1)
33
+ ]),
34
+ _: 1
35
+ })
36
+ ])
37
+ ]);
38
+ };
39
+ }
40
+ }), W = { class: "rounded-xl text-card-foreground shadow-lg border-0 bg-white dark:bg-slate-800 backdrop-blur-sm hover:shadow-xl transition-all duration-300 transform hover:scale-105" }, G = { class: "p-6" }, K = { class: "flex items-start justify-between" }, Q = { class: "flex-1" }, Z = { class: "flex items-center space-x-2 mb-2" }, X = { class: "text-sm font-medium text-slate-600 dark:text-slate-400" }, Y = { class: "text-3xl font-bold text-slate-800 dark:text-slate-100 mb-1" }, ee = { class: "text-xs text-slate-500 dark:text-slate-400 mb-3" }, te = /* @__PURE__ */ b({
41
+ __name: "StatCard",
42
+ props: {
43
+ stat: {}
44
+ },
45
+ setup(o) {
46
+ const s = (r) => ({
47
+ "file-text": v,
48
+ users: w,
49
+ image: U,
50
+ eye: F
51
+ })[r] || v;
52
+ return (r, a) => (d(), u("div", W, [
53
+ e("div", G, [
54
+ e("div", K, [
55
+ e("div", Q, [
56
+ e("div", Z, [
57
+ e("div", {
58
+ class: x(`p-2 rounded-lg bg-${o.stat.color}-50 dark:bg-${o.stat.color}-900/20`)
59
+ }, [
60
+ (d(), f(j(s(o.stat.icon)), {
61
+ class: x(`w-5 h-5 text-${o.stat.color}-600`)
62
+ }, null, 8, ["class"]))
63
+ ], 2),
64
+ e("p", X, i(o.stat.title), 1)
65
+ ]),
66
+ e("p", Y, i(o.stat.value), 1),
67
+ e("p", ee, i(o.stat.description), 1)
68
+ ])
69
+ ])
70
+ ])
71
+ ]));
72
+ }
73
+ }), se = { class: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" }, oe = /* @__PURE__ */ b({
74
+ __name: "StatsGrid",
75
+ props: {
76
+ stats: {}
77
+ },
78
+ setup(o) {
79
+ return (s, r) => (d(), u("div", se, [
80
+ (d(!0), u(_, null, k(o.stats, (a) => (d(), f(te, {
81
+ key: a.id,
82
+ stat: a
83
+ }, null, 8, ["stat"]))), 128))
84
+ ]));
85
+ }
86
+ }), re = { class: "p-4 hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors" }, ae = { class: "flex items-center justify-between" }, ie = { class: "flex-1" }, ne = { class: "flex items-center space-x-3 mb-2" }, le = { class: "inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-xs bg-white dark:bg-slate-700 border-slate-300 dark:border-slate-600 text-slate-600 dark:text-slate-300" }, de = { class: "font-semibold text-slate-800 dark:text-slate-100 mb-1" }, ce = { class: "flex items-center space-x-4 text-sm text-slate-500 dark:text-slate-400" }, ue = { class: "flex items-center" }, me = { class: "flex items-center" }, he = { class: "flex items-center" }, be = { class: "flex items-center space-x-2" }, ge = /* @__PURE__ */ b({
87
+ __name: "ContentItem",
88
+ props: {
89
+ item: {}
90
+ },
91
+ setup(o) {
92
+ const s = (a) => {
93
+ const n = {
94
+ published: "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent hover:bg-secondary/80 bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300",
95
+ draft: "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent hover:bg-secondary/80 bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-300",
96
+ review: "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent hover:bg-secondary/80 bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-300"
97
+ };
98
+ return n[a] || n.draft;
99
+ }, r = (a) => {
100
+ if (!a)
101
+ return "--.--.--";
102
+ const n = new Date(a);
103
+ return new Intl.DateTimeFormat("en-US", {
104
+ year: "numeric",
105
+ month: "short",
106
+ day: "numeric"
107
+ }).format(n);
108
+ };
109
+ return (a, n) => {
110
+ const c = S("router-link");
111
+ return d(), u("div", re, [
112
+ e("div", ae, [
113
+ e("div", ie, [
114
+ e("div", ne, [
115
+ e("div", le, i(o.item.type), 1),
116
+ e("div", {
117
+ class: x(s(o.item.status))
118
+ }, i(o.item.status || "--"), 3)
119
+ ]),
120
+ e("h3", de, i(o.item.title || "--"), 1),
121
+ e("div", ce, [
122
+ e("span", ue, [
123
+ l(m(w), { class: "w-4 h-4 mr-1" }),
124
+ g(" " + i(o.item.author || "--"), 1)
125
+ ]),
126
+ e("span", me, [
127
+ l(m(N), { class: "w-4 h-4 mr-1" }),
128
+ g(" " + i(r(o.item.updated_at) || "--.--.--"), 1)
129
+ ]),
130
+ e("span", he, [
131
+ l(m(F), { class: "w-4 h-4 mr-1" }),
132
+ g(" " + i(o.item.views || "--") + " " + i(a.$t("cms.dashboard.views")), 1)
133
+ ])
134
+ ])
135
+ ]),
136
+ e("div", be, [
137
+ l(c, {
138
+ to: `/collections/${o.item.object_id}/${o.item.content_id}`,
139
+ class: "inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors border shadow-sm rounded-md text-xs h-8 w-8 p-0 bg-white border-slate-300 hover:text-accent-foreground hover:bg-slate-50 dark:border-slate-600 dark:bg-slate-700 dark:hover:bg-slate-600"
140
+ }, {
141
+ default: A(() => [
142
+ l(m(R), { class: "w-4 h-4 dark:text-blue-50" })
143
+ ]),
144
+ _: 1
145
+ }, 8, ["to"])
146
+ ])
147
+ ])
148
+ ]);
149
+ };
150
+ }
151
+ }), xe = { class: "lg:col-span-2" }, fe = { class: "rounded-xl text-card-foreground shadow-lg border-0 bg-white dark:bg-slate-800 backdrop-blur-sm" }, pe = { class: "flex flex-col space-y-1.5 p-6 border-b border-slate-200 dark:border-slate-700 bg-gradient-to-r from-slate-50 dark:from-slate-800 to-white dark:to-slate-800" }, ve = { class: "flex items-center justify-between" }, _e = { class: "tracking-tight text-xl font-semibold text-slate-800 dark:text-slate-100 flex items-center" }, ke = { class: "p-0" }, we = { class: "divide-y divide-slate-100 dark:divide-slate-700" }, $e = /* @__PURE__ */ b({
152
+ __name: "RecentContent",
153
+ props: {
154
+ content: {}
155
+ },
156
+ setup(o) {
157
+ const s = M(), r = (a) => {
158
+ s.push(a);
159
+ };
160
+ return (a, n) => (d(), u("div", xe, [
161
+ e("div", fe, [
162
+ e("div", pe, [
163
+ e("div", ve, [
164
+ e("h3", _e, [
165
+ l(m(V), { class: "w-5 h-5 mr-2" }),
166
+ g(" " + i(a.$t("cms.dashboard.recentContent")), 1)
167
+ ]),
168
+ e("button", {
169
+ onClick: n[0] || (n[0] = (c) => r("/settings/collections")),
170
+ class: "inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border shadow-sm hover:text-accent-foreground h-8 rounded-md px-3 text-xs bg-white dark:bg-slate-700 border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-600"
171
+ }, i(a.$t("cms.dashboard.viewAll")), 1)
172
+ ])
173
+ ]),
174
+ e("div", ke, [
175
+ e("div", we, [
176
+ (d(!0), u(_, null, k(o.content, (c) => (d(), f(ge, {
177
+ key: c.id,
178
+ item: c
179
+ }, null, 8, ["item"]))), 128))
180
+ ])
181
+ ])
182
+ ])
183
+ ]));
184
+ }
185
+ }), ye = { class: "rounded-xl text-card-foreground shadow-lg border-0 bg-white dark:bg-slate-800 backdrop-blur-sm" }, Ce = { class: "flex flex-col space-y-1.5 p-6 border-b border-slate-200 dark:border-slate-700 bg-gradient-to-r from-slate-50 dark:from-slate-800 to-white dark:to-slate-800" }, De = { class: "tracking-tight text-lg font-semibold text-slate-800 dark:text-slate-100 flex items-center" }, Pe = { class: "p-4" }, Se = { class: "grid grid-cols-2 gap-3" }, Ae = ["onClick"], je = { class: "p-2 rounded-lg bg-blue-50 dark:bg-blue-900/20 mb-2 w-fit" }, Ue = { class: "font-medium text-slate-800 dark:text-slate-100 text-sm mb-1 group-hover:text-slate-900 dark:group-hover:text-slate-50" }, Fe = { class: "text-xs text-slate-500 dark:text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300" }, Me = /* @__PURE__ */ b({
186
+ __name: "QuickActions",
187
+ setup(o) {
188
+ const s = M(), { t: r } = $(), a = [
189
+ {
190
+ id: "create-article",
191
+ title: r("cms.dashboard.createArticle"),
192
+ description: r("cms.dashboard.createArticleDescription"),
193
+ icon: v,
194
+ iconColor: "text-blue-500",
195
+ link: "/collections/pages/create"
196
+ },
197
+ {
198
+ id: "upload-media",
199
+ title: r("cms.dashboard.uploadMedia"),
200
+ description: r("cms.dashboard.uploadMediaDescription"),
201
+ icon: U,
202
+ iconColor: "text-purple-500",
203
+ link: "/media"
204
+ },
205
+ {
206
+ id: "manage-users",
207
+ title: r("cms.dashboard.manageUsers"),
208
+ description: r("cms.dashboard.manageUsersDescription"),
209
+ icon: w,
210
+ iconColor: "text-green-500",
211
+ link: "/settings/users"
212
+ }
213
+ ], n = (c) => {
214
+ c && s.push(c);
215
+ };
216
+ return (c, h) => (d(), u("div", ye, [
217
+ e("div", Ce, [
218
+ e("h3", De, [
219
+ l(m(z), { class: "w-5 h-5 mr-2" }),
220
+ g(" " + i(c.$t("cms.dashboard.quickActions")), 1)
221
+ ])
222
+ ]),
223
+ e("div", Pe, [
224
+ e("div", Se, [
225
+ (d(), u(_, null, k(a, (t) => e("button", {
226
+ key: t.id,
227
+ class: "p-3 rounded-lg border border-slate-200 transition-all duration-200 text-left group hover:bg-slate-50 hover:shadow-md dark:border-slate-600 bg-white dark:bg-slate-700 dark:hover:bg-slate-600",
228
+ onClick: (p) => n(t == null ? void 0 : t.link)
229
+ }, [
230
+ e("div", je, [
231
+ (d(), f(j(t == null ? void 0 : t.icon), {
232
+ class: x(`w-4 h-4 ${t == null ? void 0 : t.iconColor}`)
233
+ }, null, 8, ["class"]))
234
+ ]),
235
+ e("h3", Ue, i(t == null ? void 0 : t.title), 1),
236
+ e("p", Fe, i(t == null ? void 0 : t.description), 1)
237
+ ], 8, Ae)), 64))
238
+ ])
239
+ ])
240
+ ]));
241
+ }
242
+ }), Ie = { class: "w-full max-w-7xl mx-auto space-y-8" }, Te = { class: "grid grid-cols-1 lg:grid-cols-3 gap-6" }, ze = /* @__PURE__ */ b({
243
+ __name: "Dashboard",
244
+ setup(o) {
245
+ const { t: s } = $(), r = P([
246
+ {
247
+ id: "total-content",
248
+ title: s("cms.dashboard.totalContent"),
249
+ value: "2,847",
250
+ description: s("cms.dashboard.articlesPostsPages"),
251
+ change: { value: "+12.5%", isPositive: !0 },
252
+ icon: "file-text",
253
+ color: "blue"
254
+ },
255
+ {
256
+ id: "active-users",
257
+ title: s("cms.dashboard.activeUsers"),
258
+ value: "1,234",
259
+ description: s("cms.dashboard.monthlyActiveUsers"),
260
+ change: { value: "+8.2%", isPositive: !0 },
261
+ icon: "users",
262
+ color: "emerald"
263
+ },
264
+ {
265
+ id: "media-files",
266
+ title: s("cms.dashboard.mediaFiles"),
267
+ value: "5,692",
268
+ description: s("cms.dashboard.imagesVideosDocs"),
269
+ change: { value: "+23.1%", isPositive: !0 },
270
+ icon: "image",
271
+ color: "purple"
272
+ },
273
+ {
274
+ id: "new-media",
275
+ title: s("cms.dashboard.newMediaFiles"),
276
+ value: "89.2K",
277
+ description: s("cms.dashboard.thisMonth"),
278
+ change: { value: "-2.4%", isPositive: !1 },
279
+ icon: "eye",
280
+ color: "orange"
281
+ }
282
+ ]), a = P([
283
+ {
284
+ id: 1,
285
+ type: "Article",
286
+ status: "published",
287
+ title: s("cms.dashboard.gettingStartedWithNextJs14"),
288
+ author: s("cms.dashboard.sarahJohnson"),
289
+ updated_at: "2024-01-15",
290
+ views: 1247
291
+ },
292
+ {
293
+ id: 2,
294
+ type: "Post",
295
+ status: "draft",
296
+ title: s("cms.dashboard.advancedReactPatterns"),
297
+ author: s("cms.dashboard.mikeChen"),
298
+ updated_at: "2024-01-14",
299
+ views: 0
300
+ },
301
+ {
302
+ id: 3,
303
+ type: "Article",
304
+ status: "published",
305
+ title: s("cms.dashboard.uiUxDesignPrinciples"),
306
+ author: s("cms.dashboard.emmaWilson"),
307
+ updated_at: "2024-01-13",
308
+ views: 892
309
+ },
310
+ {
311
+ id: 4,
312
+ type: "Post",
313
+ status: "review",
314
+ title: s("cms.dashboard.databaseOptimizationTips"),
315
+ author: s("cms.dashboard.alexRodriguez"),
316
+ updated_at: "2024-01-12",
317
+ views: 0
318
+ }
319
+ ]), n = (h) => {
320
+ r.value = r.value.map((t) => {
321
+ var p, y, C, D;
322
+ switch (t.id) {
323
+ case "total-content":
324
+ return { ...t, value: ((p = h.totalContent) == null ? void 0 : p.toLocaleString()) ?? t.value };
325
+ case "active-users":
326
+ return { ...t, value: ((y = h.totalUsers) == null ? void 0 : y.toLocaleString()) ?? t.value };
327
+ case "media-files":
328
+ return { ...t, value: ((C = h.totalMediaFiles) == null ? void 0 : C.toLocaleString()) ?? t.value };
329
+ case "new-media":
330
+ return { ...t, value: ((D = h.newMediaFiles) == null ? void 0 : D.toLocaleString()) ?? t.value };
331
+ default:
332
+ return t;
333
+ }
334
+ });
335
+ }, c = async () => {
336
+ const t = await (await fetch("api/cms-stat")).json();
337
+ a.value = t.recentContent, n(t.stat);
338
+ };
339
+ return I(() => {
340
+ c();
341
+ }), (h, t) => (d(), u("div", Ie, [
342
+ l(O),
343
+ l(oe, { stats: r.value }, null, 8, ["stats"]),
344
+ e("div", Te, [
345
+ l($e, {
346
+ content: a.value,
347
+ class: "lg:col-span-2"
348
+ }, null, 8, ["content"]),
349
+ e("div", null, [
350
+ l(Me)
351
+ ])
352
+ ])
353
+ ]));
354
+ }
355
+ });
356
+ export {
357
+ ze as default
358
+ };