@kyro-cms/admin 0.3.1 → 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.
- package/dist/EditorClient-XEUOVAAC.js +466 -0
- package/dist/EditorClient-XEUOVAAC.js.map +1 -0
- package/dist/EditorClient-YLCGVDXY.cjs +468 -0
- package/dist/EditorClient-YLCGVDXY.cjs.map +1 -0
- package/dist/chunk-7KPIUCGT.js +384 -0
- package/dist/chunk-7KPIUCGT.js.map +1 -0
- package/dist/chunk-GOACG6R7.cjs +473 -0
- package/dist/chunk-GOACG6R7.cjs.map +1 -0
- package/dist/index.cjs +14861 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +1661 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +563 -0
- package/dist/index.js +14784 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -19
- package/src/components/ActionBar.tsx +7 -43
- package/src/components/Admin.tsx +138 -277
- package/src/components/ApiKeysManager.tsx +428 -419
- package/src/components/AuditLogsPage.tsx +35 -39
- package/src/components/AuthBridge.tsx +51 -0
- package/src/components/AutoForm.tsx +495 -1230
- package/src/components/BrandingHub.tsx +18 -19
- package/src/components/BulkActionsBar.tsx +1 -1
- package/src/components/CreateView.tsx +22 -36
- package/src/components/Dashboard.tsx +60 -84
- package/src/components/DetailView.tsx +113 -91
- package/src/components/DeveloperCenter.tsx +200 -198
- package/src/components/FieldRenderer.tsx +206 -0
- package/src/components/GraphQLPlayground.tsx +340 -480
- package/src/components/ListView.tsx +828 -254
- package/src/components/LoginPage.tsx +3 -4
- package/src/components/MarketplaceManager.tsx +254 -0
- package/src/components/MediaGallery.tsx +856 -1192
- package/src/components/PluginsManager.tsx +277 -0
- package/src/components/RestPlayground.tsx +398 -560
- package/src/components/SessionsManager.tsx +211 -0
- package/src/components/Sidebar.astro +179 -151
- package/src/components/ThemeProvider.tsx +7 -161
- package/src/components/UserManagement.tsx +162 -146
- package/src/components/UserMenu.tsx +110 -0
- package/src/components/WebhookManager.tsx +305 -367
- package/src/components/blocks/AccordionBlock.tsx +4 -4
- package/src/components/blocks/ArrayBlock.tsx +3 -3
- package/src/components/blocks/BlockEditModal.tsx +8 -8
- package/src/components/blocks/BlockWrapper.tsx +61 -0
- package/src/components/blocks/ButtonBlock.tsx +4 -4
- package/src/components/blocks/ChildBlocksTree.tsx +23 -25
- package/src/components/blocks/CodeBlock.tsx +15 -15
- package/src/components/blocks/ColumnsBlock.tsx +6 -44
- package/src/components/blocks/DividerBlock.tsx +3 -3
- package/src/components/blocks/FileBlock.tsx +4 -4
- package/src/components/blocks/HeadingBlock.tsx +6 -38
- package/src/components/blocks/HeroBlock.tsx +4 -4
- package/src/components/blocks/ImageBlock.tsx +4 -4
- package/src/components/blocks/LinkBlock.tsx +4 -4
- package/src/components/blocks/ListBlock.tsx +3 -3
- package/src/components/blocks/ParagraphBlock.tsx +12 -42
- package/src/components/blocks/RelationshipBlock.tsx +4 -4
- package/src/components/blocks/RichTextBlock.tsx +4 -4
- package/src/components/blocks/VStackBlock.tsx +5 -37
- package/src/components/blocks/VideoBlock.tsx +4 -4
- package/src/components/blocks/types.ts +11 -0
- package/src/components/fields/AccordionField.tsx +1 -1
- package/src/components/fields/ArrayField.tsx +2 -2
- package/src/components/fields/ArrayLayout.tsx +93 -0
- package/src/components/fields/BlocksField.tsx +122 -111
- package/src/components/fields/ButtonField.tsx +1 -1
- package/src/components/fields/CheckboxField.tsx +14 -15
- package/src/components/fields/ChildrenField.tsx +2 -2
- package/src/components/fields/CodeField.tsx +3 -3
- package/src/components/fields/ColumnsField.tsx +2 -2
- package/src/components/fields/DateField.tsx +13 -26
- package/src/components/fields/EditorClient.tsx +26 -28
- package/src/components/fields/FieldLayout.tsx +52 -0
- package/src/components/fields/GroupLayout.tsx +35 -0
- package/src/components/fields/JSONField.tsx +7 -7
- package/src/components/fields/LinkField.tsx +1 -1
- package/src/components/fields/MarkdownField.tsx +1 -1
- package/src/components/fields/NumberField.tsx +13 -26
- package/src/components/fields/PortableTextField.tsx +4 -4
- package/src/components/fields/PortableTextRenderer.tsx +1 -1
- package/src/components/fields/RelationshipBlockField.tsx +31 -23
- package/src/components/fields/RelationshipField.tsx +14 -14
- package/src/components/fields/SelectField.tsx +17 -26
- package/src/components/fields/TabsLayout.tsx +69 -0
- package/src/components/fields/TextField.tsx +85 -38
- package/src/components/fields/UploadField.tsx +71 -41
- package/src/components/fields/VideoField.tsx +1 -1
- package/src/components/fields/extensions/blockComponents.tsx +2 -2
- package/src/components/fields/extensions/blocksStore.ts +207 -193
- package/src/components/fields/types.ts +22 -0
- package/src/components/layout/Layout.tsx +1 -1
- package/src/components/ui/ActionMenu.tsx +63 -0
- package/src/components/ui/Badge.tsx +59 -5
- package/src/components/ui/BlockDrawer.tsx +4 -5
- package/src/components/ui/CommandPalette.tsx +58 -36
- package/src/components/ui/CommandPaletteWrapper.tsx +18 -17
- package/src/components/ui/Dropdown.tsx +18 -16
- package/src/components/ui/EmptyState.tsx +25 -0
- package/src/components/ui/GlobalModal.tsx +49 -0
- package/src/components/ui/IconButton.tsx +44 -0
- package/src/components/ui/Modal.tsx +19 -20
- package/src/components/ui/PageHeader.tsx +158 -0
- package/src/components/ui/Pagination.tsx +61 -0
- package/src/components/ui/PromptModal.tsx +1 -1
- package/src/components/ui/SearchInput.tsx +57 -0
- package/src/components/ui/SeoPreview.tsx +31 -0
- package/src/components/ui/SessionModal.tsx +0 -0
- package/src/components/ui/SlidePanel.tsx +2 -0
- package/src/components/ui/Toast.tsx +65 -122
- package/src/components/ui/Toaster.tsx +18 -0
- package/src/components/ui/icons.tsx +112 -0
- package/src/components/users/UserDetail.tsx +290 -0
- package/src/components/users/UserForm.tsx +242 -0
- package/src/components/users/UsersList.tsx +338 -0
- package/src/env.d.ts +13 -13
- package/src/fields/index.ts +2 -1
- package/src/global.d.ts +7 -0
- package/src/hooks/data.ts +2 -9
- package/src/hooks/useAsyncData.ts +36 -0
- package/src/hooks/useAutoFormState.ts +527 -0
- package/src/hooks/useSelection.ts +49 -0
- package/src/hooks/useSession.ts +0 -0
- package/src/index.ts +11 -1
- package/src/integration.ts +86 -11
- package/src/kyro-cms.d.ts +209 -0
- package/src/layouts/AdminLayout.astro +128 -11
- package/src/layouts/AuthLayout.astro +21 -5
- package/src/lib/api.ts +175 -55
- package/src/lib/autoform-store.ts +435 -0
- package/src/lib/config.ts +82 -34
- package/src/lib/createRegistry.ts +29 -0
- package/src/lib/default-kyro-config.ts +4 -0
- package/src/lib/globals.ts +50 -0
- package/src/lib/media-utils.ts +18 -0
- package/src/lib/object-utils.ts +77 -0
- package/src/lib/paths.ts +61 -0
- package/src/lib/stores/index.ts +370 -0
- package/src/lib/types.ts +43 -0
- package/src/lib/useResourceManager.ts +105 -0
- package/src/pages/403.astro +67 -0
- package/src/pages/[collection]/[id].astro +14 -180
- package/src/pages/[collection]/index.astro +11 -6
- package/src/pages/api-explorer.astro +173 -0
- package/src/pages/audit/index.astro +2 -0
- package/src/pages/auth/login.astro +122 -0
- package/src/pages/auth/register.astro +167 -0
- package/src/pages/graphql-explorer.astro +59 -0
- package/src/pages/{admin/graphql.astro → graphql.astro} +51 -17
- package/src/pages/index.astro +577 -0
- package/src/pages/index_ALT.astro +3 -0
- package/src/pages/keys.astro +11 -0
- package/src/pages/marketplace.astro +11 -0
- package/src/pages/media.astro +3 -0
- package/src/pages/plugins.astro +8 -0
- package/src/pages/preview/[collection]/[id].astro +188 -123
- package/src/pages/rest-playground.astro +62 -0
- package/src/pages/roles/index.astro +183 -76
- package/src/pages/sessions.astro +8 -0
- package/src/pages/settings/[slug].astro +92 -114
- package/src/pages/settings/index.astro +5 -3
- package/src/pages/users/[id].astro +25 -154
- package/src/pages/users/index.astro +19 -130
- package/src/pages/users/new.astro +9 -86
- package/src/pages/webhooks.astro +11 -0
- package/src/routes.ts +80 -0
- package/src/styles/main.css +119 -79
- package/src/theme/tokens.ts +1 -0
- package/src/vite-env.d.ts +14 -0
- package/src/collections/auth/index.ts +0 -155
- package/src/collections/portfolio/index.ts +0 -343
- package/src/components/ApiExplorer.tsx +0 -325
- package/src/components/EnhancedListView.tsx +0 -889
- package/src/components/GraphQLExplorer.tsx +0 -675
- package/src/components/Icons.tsx +0 -23
- package/src/components/StatusBadge.tsx +0 -76
- package/src/lib/MediaService.ts +0 -541
- package/src/lib/auth/sqlite-adapter.ts +0 -319
- package/src/lib/dataStore.ts +0 -226
- package/src/lib/db/adapter.ts +0 -54
- package/src/lib/db/drizzle-mysql-adapter.ts +0 -194
- package/src/lib/db/drizzle-mysql-auth-adapter.ts +0 -327
- package/src/lib/db/drizzle-postgres-adapter.ts +0 -202
- package/src/lib/db/drizzle-postgres-auth-adapter.ts +0 -304
- package/src/lib/db/drizzle-sqlite-adapter.ts +0 -227
- package/src/lib/db/drizzle-sqlite-auth-adapter.ts +0 -548
- package/src/lib/db/index.ts +0 -449
- package/src/lib/db/mongodb-adapter.ts +0 -207
- package/src/lib/db/mongodb-auth-adapter.ts +0 -305
- package/src/lib/db/schema/mysql-auth.ts +0 -113
- package/src/lib/db/schema/mysql-content.ts +0 -20
- package/src/lib/db/schema/postgres-auth.ts +0 -116
- package/src/lib/db/schema/postgres-content.ts +0 -35
- package/src/lib/db/schema/postgres-media.ts +0 -52
- package/src/lib/db/schema/postgres-settings.ts +0 -11
- package/src/lib/db/schema/sqlite-auth.ts +0 -112
- package/src/lib/db/schema/sqlite-content.ts +0 -20
- package/src/lib/db/version-adapter.ts +0 -248
- package/src/lib/graphql/index.ts +0 -1
- package/src/lib/graphql/schema.ts +0 -443
- package/src/lib/rate-limit.ts +0 -267
- package/src/lib/storage.ts +0 -374
- package/src/lib/store.ts +0 -85
- package/src/middleware.ts +0 -177
- package/src/pages/admin/api-explorer.astro +0 -98
- package/src/pages/admin/graphql-explorer.astro +0 -40
- package/src/pages/admin/index.astro +0 -286
- package/src/pages/admin/keys.astro +0 -8
- package/src/pages/admin/rest-playground.astro +0 -44
- package/src/pages/admin/webhooks.astro +0 -8
- package/src/pages/api/[collection]/[id]/publish.ts +0 -52
- package/src/pages/api/[collection]/[id]/unpublish.ts +0 -42
- package/src/pages/api/[collection]/[id]/versions.ts +0 -66
- package/src/pages/api/[collection]/[id].ts +0 -213
- package/src/pages/api/[collection]/index.ts +0 -209
- package/src/pages/api/auth/[id].ts +0 -121
- package/src/pages/api/auth/audit-logs.ts +0 -57
- package/src/pages/api/auth/login.ts +0 -211
- package/src/pages/api/auth/logout.ts +0 -66
- package/src/pages/api/auth/me.ts +0 -36
- package/src/pages/api/auth/refresh.ts +0 -119
- package/src/pages/api/auth/register.ts +0 -188
- package/src/pages/api/auth/users.ts +0 -97
- package/src/pages/api/collections.ts +0 -59
- package/src/pages/api/globals/[slug].ts +0 -42
- package/src/pages/api/graphql.ts +0 -90
- package/src/pages/api/health.ts +0 -426
- package/src/pages/api/keys/[id].ts +0 -26
- package/src/pages/api/keys/index.ts +0 -75
- package/src/pages/api/media/[id].ts +0 -309
- package/src/pages/api/media/folders.ts +0 -609
- package/src/pages/api/media/index.ts +0 -146
- package/src/pages/api/media/resize.ts +0 -267
- package/src/pages/api/search.ts +0 -82
- package/src/pages/api/slug-availability.ts +0 -70
- package/src/pages/api/storage-config.ts +0 -20
- package/src/pages/api/storage-status.ts +0 -206
- package/src/pages/api/upload.ts +0 -334
- package/src/pages/api/webhooks/index.ts +0 -71
- package/src/pages/login.astro +0 -82
- 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,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>
|
package/src/pages/media.astro
CHANGED