@kyro-cms/admin 0.3.2 → 0.3.4

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 (242) hide show
  1. package/dist/EditorClient-XEUOVAAC.js +466 -0
  2. package/dist/EditorClient-XEUOVAAC.js.map +1 -0
  3. package/dist/EditorClient-YLCGVDXY.cjs +468 -0
  4. package/dist/EditorClient-YLCGVDXY.cjs.map +1 -0
  5. package/dist/chunk-7KPIUCGT.js +384 -0
  6. package/dist/chunk-7KPIUCGT.js.map +1 -0
  7. package/dist/chunk-GOACG6R7.cjs +473 -0
  8. package/dist/chunk-GOACG6R7.cjs.map +1 -0
  9. package/dist/index.cjs +14861 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.css +1661 -0
  12. package/dist/index.css.map +1 -0
  13. package/dist/index.d.ts +563 -0
  14. package/dist/index.js +14784 -0
  15. package/dist/index.js.map +1 -0
  16. package/package.json +19 -19
  17. package/src/components/ActionBar.tsx +7 -43
  18. package/src/components/Admin.tsx +138 -277
  19. package/src/components/ApiKeysManager.tsx +428 -419
  20. package/src/components/AuditLogsPage.tsx +35 -39
  21. package/src/components/AuthBridge.tsx +51 -0
  22. package/src/components/AutoForm.tsx +495 -1230
  23. package/src/components/BrandingHub.tsx +18 -19
  24. package/src/components/BulkActionsBar.tsx +1 -1
  25. package/src/components/CreateView.tsx +22 -36
  26. package/src/components/Dashboard.tsx +60 -84
  27. package/src/components/DetailView.tsx +113 -91
  28. package/src/components/DeveloperCenter.tsx +200 -198
  29. package/src/components/FieldRenderer.tsx +206 -0
  30. package/src/components/GraphQLPlayground.tsx +340 -480
  31. package/src/components/ListView.tsx +828 -254
  32. package/src/components/LoginPage.tsx +3 -4
  33. package/src/components/MarketplaceManager.tsx +254 -0
  34. package/src/components/MediaGallery.tsx +856 -1192
  35. package/src/components/PluginsManager.tsx +277 -0
  36. package/src/components/RestPlayground.tsx +398 -560
  37. package/src/components/SessionsManager.tsx +211 -0
  38. package/src/components/Sidebar.astro +179 -151
  39. package/src/components/ThemeProvider.tsx +7 -161
  40. package/src/components/UserManagement.tsx +162 -146
  41. package/src/components/UserMenu.tsx +110 -0
  42. package/src/components/WebhookManager.tsx +305 -367
  43. package/src/components/blocks/AccordionBlock.tsx +4 -4
  44. package/src/components/blocks/ArrayBlock.tsx +3 -3
  45. package/src/components/blocks/BlockEditModal.tsx +8 -8
  46. package/src/components/blocks/BlockWrapper.tsx +61 -0
  47. package/src/components/blocks/ButtonBlock.tsx +4 -4
  48. package/src/components/blocks/ChildBlocksTree.tsx +23 -25
  49. package/src/components/blocks/CodeBlock.tsx +15 -15
  50. package/src/components/blocks/ColumnsBlock.tsx +6 -44
  51. package/src/components/blocks/DividerBlock.tsx +3 -3
  52. package/src/components/blocks/FileBlock.tsx +4 -4
  53. package/src/components/blocks/HeadingBlock.tsx +6 -38
  54. package/src/components/blocks/HeroBlock.tsx +4 -4
  55. package/src/components/blocks/ImageBlock.tsx +4 -4
  56. package/src/components/blocks/LinkBlock.tsx +4 -4
  57. package/src/components/blocks/ListBlock.tsx +3 -3
  58. package/src/components/blocks/ParagraphBlock.tsx +12 -42
  59. package/src/components/blocks/RelationshipBlock.tsx +4 -4
  60. package/src/components/blocks/RichTextBlock.tsx +4 -4
  61. package/src/components/blocks/VStackBlock.tsx +5 -37
  62. package/src/components/blocks/VideoBlock.tsx +4 -4
  63. package/src/components/blocks/types.ts +11 -0
  64. package/src/components/fields/AccordionField.tsx +1 -1
  65. package/src/components/fields/ArrayField.tsx +2 -2
  66. package/src/components/fields/ArrayLayout.tsx +93 -0
  67. package/src/components/fields/BlocksField.tsx +122 -111
  68. package/src/components/fields/ButtonField.tsx +1 -1
  69. package/src/components/fields/CheckboxField.tsx +14 -15
  70. package/src/components/fields/ChildrenField.tsx +2 -2
  71. package/src/components/fields/CodeField.tsx +3 -3
  72. package/src/components/fields/ColumnsField.tsx +2 -2
  73. package/src/components/fields/DateField.tsx +13 -26
  74. package/src/components/fields/EditorClient.tsx +26 -28
  75. package/src/components/fields/FieldLayout.tsx +52 -0
  76. package/src/components/fields/GroupLayout.tsx +35 -0
  77. package/src/components/fields/JSONField.tsx +7 -7
  78. package/src/components/fields/LinkField.tsx +1 -1
  79. package/src/components/fields/MarkdownField.tsx +1 -1
  80. package/src/components/fields/NumberField.tsx +13 -26
  81. package/src/components/fields/PortableTextField.tsx +4 -4
  82. package/src/components/fields/PortableTextRenderer.tsx +1 -1
  83. package/src/components/fields/RelationshipBlockField.tsx +31 -23
  84. package/src/components/fields/RelationshipField.tsx +14 -14
  85. package/src/components/fields/SelectField.tsx +17 -26
  86. package/src/components/fields/TabsLayout.tsx +69 -0
  87. package/src/components/fields/TextField.tsx +85 -38
  88. package/src/components/fields/UploadField.tsx +71 -41
  89. package/src/components/fields/VideoField.tsx +1 -1
  90. package/src/components/fields/extensions/blockComponents.tsx +2 -2
  91. package/src/components/fields/extensions/blocksStore.ts +207 -193
  92. package/src/components/fields/types.ts +22 -0
  93. package/src/components/layout/Layout.tsx +1 -1
  94. package/src/components/ui/ActionMenu.tsx +63 -0
  95. package/src/components/ui/Badge.tsx +59 -5
  96. package/src/components/ui/BlockDrawer.tsx +4 -5
  97. package/src/components/ui/CommandPalette.tsx +58 -36
  98. package/src/components/ui/CommandPaletteWrapper.tsx +18 -17
  99. package/src/components/ui/Dropdown.tsx +18 -16
  100. package/src/components/ui/EmptyState.tsx +25 -0
  101. package/src/components/ui/GlobalModal.tsx +49 -0
  102. package/src/components/ui/IconButton.tsx +44 -0
  103. package/src/components/ui/Modal.tsx +19 -20
  104. package/src/components/ui/PageHeader.tsx +158 -0
  105. package/src/components/ui/Pagination.tsx +61 -0
  106. package/src/components/ui/PromptModal.tsx +1 -1
  107. package/src/components/ui/SearchInput.tsx +57 -0
  108. package/src/components/ui/SeoPreview.tsx +31 -0
  109. package/src/components/ui/SessionModal.tsx +0 -0
  110. package/src/components/ui/SlidePanel.tsx +2 -0
  111. package/src/components/ui/Toast.tsx +65 -122
  112. package/src/components/ui/Toaster.tsx +18 -0
  113. package/src/components/ui/icons.tsx +112 -0
  114. package/src/components/users/UserDetail.tsx +290 -0
  115. package/src/components/users/UserForm.tsx +242 -0
  116. package/src/components/users/UsersList.tsx +338 -0
  117. package/src/env.d.ts +13 -13
  118. package/src/fields/index.ts +2 -1
  119. package/src/global.d.ts +7 -0
  120. package/src/hooks/data.ts +2 -9
  121. package/src/hooks/useAsyncData.ts +36 -0
  122. package/src/hooks/useAutoFormState.ts +527 -0
  123. package/src/hooks/useSelection.ts +49 -0
  124. package/src/hooks/useSession.ts +0 -0
  125. package/src/index.ts +11 -1
  126. package/src/integration.ts +86 -11
  127. package/src/kyro-cms.d.ts +209 -0
  128. package/src/layouts/AdminLayout.astro +128 -11
  129. package/src/layouts/AuthLayout.astro +21 -5
  130. package/src/lib/api.ts +175 -55
  131. package/src/lib/autoform-store.ts +435 -0
  132. package/src/lib/config.ts +82 -34
  133. package/src/lib/createRegistry.ts +29 -0
  134. package/src/lib/default-kyro-config.ts +4 -0
  135. package/src/lib/globals.ts +50 -0
  136. package/src/lib/media-utils.ts +18 -0
  137. package/src/lib/object-utils.ts +77 -0
  138. package/src/lib/paths.ts +61 -0
  139. package/src/lib/stores/index.ts +370 -0
  140. package/src/lib/types.ts +43 -0
  141. package/src/lib/useResourceManager.ts +105 -0
  142. package/src/pages/403.astro +67 -0
  143. package/src/pages/[collection]/[id].astro +14 -180
  144. package/src/pages/[collection]/index.astro +11 -6
  145. package/src/pages/api-explorer.astro +173 -0
  146. package/src/pages/audit/index.astro +2 -0
  147. package/src/pages/auth/login.astro +122 -0
  148. package/src/pages/auth/register.astro +167 -0
  149. package/src/pages/graphql-explorer.astro +59 -0
  150. package/src/pages/{admin/graphql.astro → graphql.astro} +51 -17
  151. package/src/pages/index.astro +577 -0
  152. package/src/pages/index_ALT.astro +3 -0
  153. package/src/pages/keys.astro +11 -0
  154. package/src/pages/marketplace.astro +11 -0
  155. package/src/pages/media.astro +3 -0
  156. package/src/pages/plugins.astro +8 -0
  157. package/src/pages/preview/[collection]/[id].astro +188 -123
  158. package/src/pages/rest-playground.astro +62 -0
  159. package/src/pages/roles/index.astro +183 -76
  160. package/src/pages/sessions.astro +8 -0
  161. package/src/pages/settings/[slug].astro +92 -114
  162. package/src/pages/settings/index.astro +5 -3
  163. package/src/pages/users/[id].astro +25 -154
  164. package/src/pages/users/index.astro +19 -130
  165. package/src/pages/users/new.astro +9 -86
  166. package/src/pages/webhooks.astro +11 -0
  167. package/src/routes.ts +80 -0
  168. package/src/styles/main.css +119 -79
  169. package/src/theme/tokens.ts +1 -0
  170. package/src/vite-env.d.ts +14 -0
  171. package/src/collections/auth/index.ts +0 -155
  172. package/src/collections/portfolio/index.ts +0 -343
  173. package/src/components/ApiExplorer.tsx +0 -325
  174. package/src/components/EnhancedListView.tsx +0 -889
  175. package/src/components/GraphQLExplorer.tsx +0 -675
  176. package/src/components/Icons.tsx +0 -23
  177. package/src/components/StatusBadge.tsx +0 -76
  178. package/src/lib/MediaService.ts +0 -541
  179. package/src/lib/auth/sqlite-adapter.ts +0 -319
  180. package/src/lib/dataStore.ts +0 -226
  181. package/src/lib/db/adapter.ts +0 -54
  182. package/src/lib/db/drizzle-mysql-adapter.ts +0 -194
  183. package/src/lib/db/drizzle-mysql-auth-adapter.ts +0 -327
  184. package/src/lib/db/drizzle-postgres-adapter.ts +0 -202
  185. package/src/lib/db/drizzle-postgres-auth-adapter.ts +0 -304
  186. package/src/lib/db/drizzle-sqlite-adapter.ts +0 -227
  187. package/src/lib/db/drizzle-sqlite-auth-adapter.ts +0 -548
  188. package/src/lib/db/index.ts +0 -449
  189. package/src/lib/db/mongodb-adapter.ts +0 -207
  190. package/src/lib/db/mongodb-auth-adapter.ts +0 -305
  191. package/src/lib/db/schema/mysql-auth.ts +0 -113
  192. package/src/lib/db/schema/mysql-content.ts +0 -20
  193. package/src/lib/db/schema/postgres-auth.ts +0 -116
  194. package/src/lib/db/schema/postgres-content.ts +0 -35
  195. package/src/lib/db/schema/postgres-media.ts +0 -52
  196. package/src/lib/db/schema/postgres-settings.ts +0 -11
  197. package/src/lib/db/schema/sqlite-auth.ts +0 -112
  198. package/src/lib/db/schema/sqlite-content.ts +0 -20
  199. package/src/lib/db/version-adapter.ts +0 -248
  200. package/src/lib/graphql/index.ts +0 -1
  201. package/src/lib/graphql/schema.ts +0 -443
  202. package/src/lib/rate-limit.ts +0 -267
  203. package/src/lib/storage.ts +0 -374
  204. package/src/lib/store.ts +0 -85
  205. package/src/middleware.ts +0 -177
  206. package/src/pages/admin/api-explorer.astro +0 -98
  207. package/src/pages/admin/graphql-explorer.astro +0 -40
  208. package/src/pages/admin/index.astro +0 -286
  209. package/src/pages/admin/keys.astro +0 -8
  210. package/src/pages/admin/rest-playground.astro +0 -44
  211. package/src/pages/admin/webhooks.astro +0 -8
  212. package/src/pages/api/[collection]/[id]/publish.ts +0 -52
  213. package/src/pages/api/[collection]/[id]/unpublish.ts +0 -42
  214. package/src/pages/api/[collection]/[id]/versions.ts +0 -66
  215. package/src/pages/api/[collection]/[id].ts +0 -213
  216. package/src/pages/api/[collection]/index.ts +0 -209
  217. package/src/pages/api/auth/[id].ts +0 -121
  218. package/src/pages/api/auth/audit-logs.ts +0 -57
  219. package/src/pages/api/auth/login.ts +0 -211
  220. package/src/pages/api/auth/logout.ts +0 -66
  221. package/src/pages/api/auth/me.ts +0 -36
  222. package/src/pages/api/auth/refresh.ts +0 -119
  223. package/src/pages/api/auth/register.ts +0 -188
  224. package/src/pages/api/auth/users.ts +0 -97
  225. package/src/pages/api/collections.ts +0 -59
  226. package/src/pages/api/globals/[slug].ts +0 -42
  227. package/src/pages/api/graphql.ts +0 -90
  228. package/src/pages/api/health.ts +0 -426
  229. package/src/pages/api/keys/[id].ts +0 -26
  230. package/src/pages/api/keys/index.ts +0 -75
  231. package/src/pages/api/media/[id].ts +0 -309
  232. package/src/pages/api/media/folders.ts +0 -609
  233. package/src/pages/api/media/index.ts +0 -146
  234. package/src/pages/api/media/resize.ts +0 -267
  235. package/src/pages/api/search.ts +0 -82
  236. package/src/pages/api/slug-availability.ts +0 -70
  237. package/src/pages/api/storage-config.ts +0 -20
  238. package/src/pages/api/storage-status.ts +0 -206
  239. package/src/pages/api/upload.ts +0 -334
  240. package/src/pages/api/webhooks/index.ts +0 -71
  241. package/src/pages/login.astro +0 -82
  242. package/src/pages/register.astro +0 -102
@@ -0,0 +1,577 @@
1
+ ---
2
+ import AdminLayout from "../layouts/AdminLayout.astro";
3
+ import { collections } from "../lib/config";
4
+
5
+ const authCollections = ["users", "audit_logs"];
6
+ import { adminPath, apiPath } from "../lib/paths";
7
+
8
+ const authItems = authCollections.map((slug) => ({
9
+ slug,
10
+ label: collections[slug]?.label || slug,
11
+ icon: slug === "users" ? "users" : "file-text",
12
+ }));
13
+ ---
14
+
15
+ <AdminLayout title="Dashboard">
16
+ <div class="flex-1 overflow-y-auto pr-12 space-y-8">
17
+ <!-- Header -->
18
+ <div class="surface-tile p-6 flex items-center justify-between gap-8">
19
+ <div class="relative flex-1 max-w-2xl">
20
+ <div
21
+ class="absolute inset-y-0 left-6 flex items-center pointer-events-none text-[var(--kyro-text-muted)]"
22
+ >
23
+ <svg
24
+ class="w-6 h-6"
25
+ fill="none"
26
+ stroke="currentColor"
27
+ viewBox="0 0 24 24"
28
+ >
29
+ <path
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ stroke-width="2.5"
33
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
34
+ </svg>
35
+ </div>
36
+ <input
37
+ type="text"
38
+ id="header-search-input"
39
+ placeholder="Search anything..."
40
+ class="w-full bg-[var(--kyro-surface-accent)] border border-transparent rounded-2xl py-3 pl-16 pr-8 text-lg font-medium focus:outline-none focus:bg-[var(--kyro-surface)] focus:border-[var(--kyro-border)] transition-all shadow-inner text-[var(--kyro-text-primary)] placeholder-[var(--kyro-text-muted)]"
41
+ autocomplete="off"
42
+ />
43
+ <div
44
+ id="header-search-results"
45
+ class="hidden absolute top-full left-0 right-0 mt-2 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl shadow-xl max-h-80 overflow-y-auto z-50"
46
+ >
47
+ </div>
48
+ </div>
49
+ <div class="flex p-1.5 bg-[var(--kyro-surface-accent)] rounded-2xl">
50
+ <button
51
+ id="cmd-k-btn"
52
+ class="flex items-center gap-3 px-8 py-3 bg-[var(--kyro-sidebar-active)] text-[var(--kyro-sidebar-text-active)] rounded-xl font-bold shadow-lg transition-all active:scale-95 cursor-pointer"
53
+ >
54
+ <span>⌘ K</span>
55
+ </button>
56
+ </div>
57
+ </div>
58
+
59
+ <!-- Quick Links Section -->
60
+ <div class="surface-tile overflow-hidden">
61
+ <div
62
+ class="flex items-center justify-between p-6 border-b border-[var(--kyro-border)]"
63
+ >
64
+ <div class="flex-1">
65
+ <h2
66
+ class="text-xl font-bold tracking-tight text-[var(--kyro-text-primary)] flex items-center gap-2"
67
+ >
68
+ Quick Links
69
+ </h2>
70
+ <p class="text-xs text-[var(--kyro-text-secondary)] font-medium mt-1">
71
+ Create new collection documents
72
+ </p>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 p-4">
77
+ {
78
+ Object.entries(collections)
79
+ .filter(
80
+ ([slug]) => !["users", "audit_logs", "media"].includes(slug),
81
+ )
82
+ .slice(0, 6)
83
+ .map(([slug, config]: [string, any]) => (
84
+ <a
85
+ href={`${adminPath}/${slug}/new`}
86
+ class="group p-4 bg-[var(--kyro-surface-accent)] rounded-xl hover:bg-[var(--kyro-surface)] transition-all border border-transparent hover:border-[var(--kyro-border)] shadow-sm hover:shadow-md"
87
+ >
88
+ <div class="flex items-center gap-3">
89
+ <div class="w-8 h-8 rounded-lg flex items-center justify-center bg-[var(--kyro-bg-secondary)] text-[var(--kyro-text-secondary)] group-hover:bg-[var(--kyro-surface-accent)] group-hover:text-[var(--kyro-primary)] transition-all">
90
+ <svg
91
+ class="w-4 h-4"
92
+ fill="none"
93
+ stroke="currentColor"
94
+ viewBox="0 0 24 24"
95
+ >
96
+ <path
97
+ stroke-linecap="round"
98
+ stroke-linejoin="round"
99
+ stroke-width="2"
100
+ d="M12 5v14M5 12h14"
101
+ />
102
+ </svg>
103
+ </div>
104
+ <span class="text-sm font-medium text-[var(--kyro-text-primary)]">
105
+ New {config.label || slug}
106
+ </span>
107
+ </div>
108
+ </a>
109
+ ))
110
+ }
111
+ </div>
112
+ </div>
113
+
114
+ <!-- Security Quick Actions -->
115
+ <div class="surface-tile overflow-hidden">
116
+ <div class="p-6 border-b border-[var(--kyro-border)]">
117
+ <h2
118
+ class="text-xl font-bold tracking-tight text-[var(--kyro-text-primary)]"
119
+ >
120
+ Security & Monitoring
121
+ </h2>
122
+ <p class="text-xs text-[var(--kyro-text-secondary)] font-medium mt-1">
123
+ Rate limiting, audit logs, and account lockout settings
124
+ </p>
125
+ </div>
126
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 p-6">
127
+ <a
128
+ href={`${adminPath}/audit`}
129
+ class="p-5 bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)] group"
130
+ >
131
+ <div
132
+ class="w-10 h-10 rounded-lg bg-orange-500/10 text-orange-500 flex items-center justify-center mb-3"
133
+ >
134
+ <svg
135
+ class="w-5 h-5"
136
+ fill="none"
137
+ stroke="currentColor"
138
+ viewBox="0 0 24 24"
139
+ >
140
+ <path
141
+ stroke-linecap="round"
142
+ stroke-linejoin="round"
143
+ stroke-width="2"
144
+ d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
145
+ ></path>
146
+ </svg>
147
+ </div>
148
+ <h4 class="font-medium text-[var(--kyro-text-primary)] mb-1">
149
+ Audit Logs
150
+ </h4>
151
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
152
+ View last 30 days
153
+ </p>
154
+ </a>
155
+
156
+ <a
157
+ href={`${adminPath}/users?locked=true`}
158
+ class="p-5 bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)] group"
159
+ >
160
+ <div
161
+ class="w-10 h-10 rounded-lg bg-red-500/10 text-red-500 flex items-center justify-center mb-3"
162
+ >
163
+ <svg
164
+ class="w-5 h-5"
165
+ fill="none"
166
+ stroke="currentColor"
167
+ viewBox="0 0 24 24"
168
+ >
169
+ <path
170
+ stroke-linecap="round"
171
+ stroke-linejoin="round"
172
+ stroke-width="2"
173
+ d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
174
+ ></path>
175
+ </svg>
176
+ </div>
177
+ <h4 class="font-medium text-[var(--kyro-text-primary)] mb-1">
178
+ Locked Accounts
179
+ </h4>
180
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
181
+ Manage lockouts
182
+ </p>
183
+ </a>
184
+
185
+ <a
186
+ href={`${adminPath}/roles`}
187
+ class="p-5 bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)] group"
188
+ >
189
+ <div
190
+ class="w-10 h-10 rounded-lg bg-indigo-500/10 text-indigo-500 flex items-center justify-center mb-3"
191
+ >
192
+ <svg
193
+ class="w-5 h-5"
194
+ fill="none"
195
+ stroke="currentColor"
196
+ viewBox="0 0 24 24"
197
+ >
198
+ <path
199
+ stroke-linecap="round"
200
+ stroke-linejoin="round"
201
+ stroke-width="2"
202
+ d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
203
+ ></path>
204
+ </svg>
205
+ </div>
206
+ <h4 class="font-medium text-[var(--kyro-text-primary)] mb-1">
207
+ Permissions
208
+ </h4>
209
+ <p class="text-xs text-[var(--kyro-text-secondary)]">RBAC settings</p>
210
+ </a>
211
+
212
+ <a
213
+ href={`${apiPath}/health`}
214
+ target="_blank"
215
+ class="p-5 bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)] group"
216
+ >
217
+ <div
218
+ class="w-10 h-10 rounded-lg bg-green-500/10 text-green-500 flex items-center justify-center mb-3"
219
+ >
220
+ <svg
221
+ class="w-5 h-5"
222
+ fill="none"
223
+ stroke="currentColor"
224
+ viewBox="0 0 24 24"
225
+ >
226
+ <path
227
+ stroke-linecap="round"
228
+ stroke-linejoin="round"
229
+ stroke-width="2"
230
+ d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
231
+ </svg>
232
+ </div>
233
+ <h4 class="font-medium text-[var(--kyro-text-primary)] mb-1">
234
+ API Health
235
+ </h4>
236
+ <p class="text-xs text-[var(--kyro-text-secondary)]">System status</p>
237
+ </a>
238
+ </div>
239
+ </div>
240
+
241
+ <!-- Developer Tools Section -->
242
+ <div class="surface-tile overflow-hidden">
243
+ <div class="p-6 border-b border-[var(--kyro-border)]">
244
+ <h2
245
+ class="text-xl font-bold tracking-tight text-[var(--kyro-text-primary)]"
246
+ >
247
+ Developer Tools
248
+ </h2>
249
+ <p class="text-xs text-[var(--kyro-text-secondary)] font-medium mt-1">
250
+ REST API & GraphQL testing tools
251
+ </p>
252
+ </div>
253
+
254
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 p-8">
255
+ <!-- REST API -->
256
+ <div class="bg-[var(--kyro-surface-accent)] rounded-2xl p-6">
257
+ <div class="flex items-center gap-3 mb-6">
258
+ <div
259
+ class="w-10 h-10 rounded-xl bg-pink-500/10 flex items-center justify-center text-pink-500"
260
+ >
261
+ <svg
262
+ class="w-5 h-5"
263
+ fill="none"
264
+ stroke="currentColor"
265
+ viewBox="0 0 24 24"
266
+ >
267
+ <path
268
+ stroke-linecap="round"
269
+ stroke-linejoin="round"
270
+ stroke-width="2"
271
+ d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
272
+ ></path>
273
+ </svg>
274
+ </div>
275
+ <div>
276
+ <h3 class="text-xl font-bold text-[var(--kyro-text-primary)]">
277
+ REST API
278
+ </h3>
279
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
280
+ HTTP endpoints
281
+ </p>
282
+ </div>
283
+ </div>
284
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
285
+ <a
286
+ href={`${adminPath}/api-explorer`}
287
+ class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
288
+ >
289
+ <div class="flex items-center gap-3 mb-2">
290
+ <div
291
+ class="w-8 h-8 rounded-lg bg-green-500/10 flex items-center justify-center text-green-500 group-hover:scale-110 transition-transform"
292
+ >
293
+ <svg
294
+ class="w-4 h-4"
295
+ fill="none"
296
+ stroke="currentColor"
297
+ viewBox="0 0 24 24"
298
+ >
299
+ <path
300
+ stroke-linecap="round"
301
+ stroke-linejoin="round"
302
+ stroke-width="2"
303
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
304
+ </svg>
305
+ </div>
306
+ <h4 class="font-medium text-[var(--kyro-text-primary)]">
307
+ Explorer
308
+ </h4>
309
+ </div>
310
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
311
+ Test endpoints interactively
312
+ </p>
313
+ </a>
314
+ <a
315
+ href={`${adminPath}/rest-playground`}
316
+ class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
317
+ >
318
+ <div class="flex items-center gap-3 mb-2">
319
+ <div
320
+ class="w-8 h-8 rounded-lg bg-blue-500/10 flex items-center justify-center text-blue-500 group-hover:scale-110 transition-transform"
321
+ >
322
+ <svg
323
+ class="w-4 h-4"
324
+ fill="none"
325
+ stroke="currentColor"
326
+ viewBox="0 0 24 24"
327
+ >
328
+ <path
329
+ stroke-linecap="round"
330
+ stroke-linejoin="round"
331
+ stroke-width="2"
332
+ d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
333
+ ></path>
334
+ </svg>
335
+ </div>
336
+ <h4 class="font-medium text-[var(--kyro-text-primary)]">
337
+ Playground
338
+ </h4>
339
+ </div>
340
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
341
+ Saved requests & history
342
+ </p>
343
+ </a>
344
+ </div>
345
+ <div class="mt-4 pt-4 border-t border-[var(--kyro-border)]">
346
+ <a
347
+ href={`${apiPath}/collections`}
348
+ target="_blank"
349
+ class="flex items-center gap-2 text-xs text-[var(--kyro-text-muted)] hover:text-[var(--kyro-text-secondary)] transition-colors"
350
+ >
351
+ <svg
352
+ class="w-3 h-3"
353
+ fill="none"
354
+ stroke="currentColor"
355
+ viewBox="0 0 24 24"
356
+ >
357
+ <path
358
+ stroke-linecap="round"
359
+ stroke-linejoin="round"
360
+ stroke-width="2"
361
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
362
+ ></path>
363
+ </svg>
364
+ View Collections JSON
365
+ </a>
366
+ </div>
367
+ </div>
368
+
369
+ <!-- GraphQL -->
370
+ <div class="bg-[var(--kyro-surface-accent)] rounded-2xl p-6">
371
+ <div class="flex items-center gap-3 mb-6">
372
+ <div
373
+ class="w-10 h-10 rounded-xl bg-pink-500/10 flex items-center justify-center text-pink-500"
374
+ >
375
+ <svg
376
+ class="w-5 h-5"
377
+ fill="none"
378
+ stroke="currentColor"
379
+ viewBox="0 0 24 24"
380
+ >
381
+ <path
382
+ stroke-linecap="round"
383
+ stroke-linejoin="round"
384
+ stroke-width="2"
385
+ d="M13 10V3L4 14h7v7l9-11h-7z"></path>
386
+ </svg>
387
+ </div>
388
+ <div>
389
+ <h3 class="text-xl font-bold text-[var(--kyro-text-primary)]">
390
+ GraphQL
391
+ </h3>
392
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
393
+ Query language API
394
+ </p>
395
+ </div>
396
+ </div>
397
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
398
+ <a
399
+ href={`${adminPath}/graphql`}
400
+ class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
401
+ >
402
+ <div class="flex items-center gap-3 mb-2">
403
+ <div
404
+ class="w-8 h-8 rounded-lg bg-purple-500/10 flex items-center justify-center text-purple-500 group-hover:scale-110 transition-transform"
405
+ >
406
+ <svg
407
+ class="w-4 h-4"
408
+ fill="none"
409
+ stroke="currentColor"
410
+ viewBox="0 0 24 24"
411
+ >
412
+ <path
413
+ stroke-linecap="round"
414
+ stroke-linejoin="round"
415
+ stroke-width="2"
416
+ d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"
417
+ ></path>
418
+ <path
419
+ stroke-linecap="round"
420
+ stroke-linejoin="round"
421
+ stroke-width="2"
422
+ d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
423
+ </svg>
424
+ </div>
425
+ <h4 class="font-medium text-[var(--kyro-text-primary)]">
426
+ Playground
427
+ </h4>
428
+ </div>
429
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
430
+ Write & test queries
431
+ </p>
432
+ </a>
433
+ <a
434
+ href={`${adminPath}/graphql-explorer`}
435
+ class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
436
+ >
437
+ <div class="flex items-center gap-3 mb-2">
438
+ <div
439
+ class="w-8 h-8 rounded-lg bg-orange-500/10 flex items-center justify-center text-orange-500 group-hover:scale-110 transition-transform"
440
+ >
441
+ <svg
442
+ class="w-4 h-4"
443
+ fill="none"
444
+ stroke="currentColor"
445
+ viewBox="0 0 24 24"
446
+ >
447
+ <path
448
+ stroke-linecap="round"
449
+ stroke-linejoin="round"
450
+ stroke-width="2"
451
+ d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
452
+ ></path>
453
+ </svg>
454
+ </div>
455
+ <h4 class="font-medium text-[var(--kyro-text-primary)]">
456
+ Explorer
457
+ </h4>
458
+ </div>
459
+ <p class="text-xs text-[var(--kyro-text-secondary)]">
460
+ Schema documentation
461
+ </p>
462
+ </a>
463
+ </div>
464
+ <div class="mt-4 pt-4 border-t border-[var(--kyro-border)]">
465
+ <a
466
+ href={`${apiPath}/graphql`}
467
+ target="_blank"
468
+ class="flex items-center gap-2 text-xs text-[var(--kyro-text-muted)] hover:text-[var(--kyro-text-secondary)] transition-colors"
469
+ >
470
+ <svg
471
+ class="w-3 h-3"
472
+ fill="none"
473
+ stroke="currentColor"
474
+ viewBox="0 0 24 24"
475
+ >
476
+ <path
477
+ stroke-linecap="round"
478
+ stroke-linejoin="round"
479
+ stroke-width="2"
480
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
481
+ ></path>
482
+ </svg>
483
+ View GraphQL Endpoint
484
+ </a>
485
+ </div>
486
+ </div>
487
+ </div>
488
+ </div>
489
+
490
+ <script is:inline define:vars={{ apiPath, adminPath }}>
491
+ (function () {
492
+ var searchInput = document.getElementById("header-search-input");
493
+ var searchResults = document.getElementById("header-search-results");
494
+ if (!searchInput || !searchResults) return;
495
+
496
+ var debounceTimer = null;
497
+
498
+ function renderResults(results) {
499
+ var html = "";
500
+ if (!results || results.length === 0) {
501
+ html =
502
+ '<div class="p-4 text-center text-[var(--kyro-text-secondary)] opacity-60">No documents found</div>';
503
+ } else {
504
+ for (var i = 0; i < Math.min(results.length, 6); i++) {
505
+ var r = results[i];
506
+ var href = adminPath + "/" + r.collection + "/" + r.id;
507
+ if (r.collection === "users") {
508
+ href = adminPath + "/users/" + r.id;
509
+ }
510
+ html +=
511
+ '<a href="' +
512
+ href +
513
+ '" class="flex items-center justify-between px-4 py-3 hover:bg-[var(--kyro-surface-accent)] transition-colors">';
514
+ html +=
515
+ '<div class="flex flex-col"><span class="font-bold text-sm text-[var(--kyro-text-primary)]">' +
516
+ (r.title || "Untitled") +
517
+ "</span>";
518
+ html +=
519
+ '<span class="text-[10px] font-bold tracking-widest opacity-40">' +
520
+ r.label +
521
+ "</span></div>";
522
+ html +=
523
+ '<span class="text-xs text-[var(--kyro-text-muted)]">View</span></a>';
524
+ }
525
+ }
526
+ searchResults.innerHTML = html;
527
+ searchResults.classList.remove("hidden");
528
+ }
529
+
530
+ function hideResults() {
531
+ searchResults.classList.add("hidden");
532
+ }
533
+
534
+ searchInput.addEventListener("input", function (e) {
535
+ var query = e.target.value.trim();
536
+ if (query.length < 2) {
537
+ searchResults.classList.add("hidden");
538
+ return;
539
+ }
540
+ if (debounceTimer) clearTimeout(debounceTimer);
541
+ debounceTimer = setTimeout(function () {
542
+ var xhr = new XMLHttpRequest();
543
+ xhr.open(
544
+ "GET",
545
+ apiPath + "/search?q=" + encodeURIComponent(query) + "&limit=10",
546
+ true,
547
+ );
548
+ xhr.onload = function () {
549
+ if (xhr.status === 200) {
550
+ try {
551
+ var data = JSON.parse(xhr.responseText);
552
+ if (data.results) renderResults(data.results);
553
+ } catch (err) {
554
+ console.error(err);
555
+ }
556
+ }
557
+ };
558
+ xhr.send();
559
+ }, 300);
560
+ });
561
+
562
+ searchInput.addEventListener("blur", function () {
563
+ setTimeout(hideResults, 200);
564
+ });
565
+
566
+ document.addEventListener("click", function (e) {
567
+ if (
568
+ !searchInput.contains(e.target) &&
569
+ !searchResults.contains(e.target)
570
+ ) {
571
+ hideResults();
572
+ }
573
+ });
574
+ })();
575
+ </script>
576
+ </div>
577
+ </AdminLayout>
@@ -0,0 +1,3 @@
1
+ import { adminPath, apiPath } from '../lib/paths';
2
+ return Astro.redirect(adminPath);
3
+ ---
@@ -0,0 +1,11 @@
1
+ ---
2
+ import AdminLayout from "../layouts/AdminLayout.astro";
3
+ import { ApiKeysManager } from "../components/ApiKeysManager";
4
+
5
+ import { adminPath, apiPath } from '../lib/paths';
6
+
7
+ ---
8
+
9
+ <AdminLayout title="API Keys">
10
+ <ApiKeysManager client:only="react" />
11
+ </AdminLayout>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import AdminLayout from "../layouts/AdminLayout.astro";
3
+ import { MarketplaceManager } from "../components/MarketplaceManager";
4
+
5
+ import { adminPath, apiPath } from '../lib/paths';
6
+
7
+ ---
8
+
9
+ <AdminLayout title="Marketplace">
10
+ <MarketplaceManager client:only="react" />
11
+ </AdminLayout>
@@ -1,6 +1,9 @@
1
1
  ---
2
2
  import AdminLayout from '../layouts/AdminLayout.astro';
3
3
  import { MediaGallery } from '../components/MediaGallery';
4
+
5
+ import { adminPath, apiPath } from '../lib/paths';
6
+
4
7
  ---
5
8
 
6
9
  <AdminLayout title="Media Library">
@@ -0,0 +1,8 @@
1
+ ---
2
+ import AdminLayout from "../layouts/AdminLayout.astro";
3
+ import { PluginsManager } from "../components/PluginsManager";
4
+ ---
5
+
6
+ <AdminLayout title="Plugins">
7
+ <PluginsManager client:only="react" />
8
+ </AdminLayout>