@kyro-cms/admin 0.3.2 → 0.3.5
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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { fetchWithAuth } from "../lib/api";
|
|
3
3
|
import { Modal } from "./ui/Modal";
|
|
4
4
|
|
|
5
5
|
interface AuditLog {
|
|
@@ -143,7 +143,7 @@ function MetadataRow({ label, value }: { label: string; value: unknown }) {
|
|
|
143
143
|
typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
144
144
|
return (
|
|
145
145
|
<div className="flex items-start gap-3 py-2 px-4 border-b border-[var(--kyro-border)] last:border-0 bg-[var(--kyro-surface-accent)]">
|
|
146
|
-
<span className="text-[10px] font-bold
|
|
146
|
+
<span className="text-[10px] font-bold tracking-wider text-[var(--kyro-text-muted)] w-24 shrink-0 pt-0.5">
|
|
147
147
|
{label}
|
|
148
148
|
</span>
|
|
149
149
|
<span className="text-xs font-mono text-[var(--kyro-text-primary)] break-all">
|
|
@@ -177,7 +177,7 @@ export function AuditLogsPage() {
|
|
|
177
177
|
if (action) params.set("action", action);
|
|
178
178
|
if (successFilter) params.set("success", successFilter);
|
|
179
179
|
|
|
180
|
-
const res = await
|
|
180
|
+
const res = await fetchWithAuth(`/api/auth/audit-logs?${params}`);
|
|
181
181
|
if (!res.ok) throw new Error("Failed to fetch");
|
|
182
182
|
const data: AuditLogsResponse = await res.json();
|
|
183
183
|
setLogs(data.docs);
|
|
@@ -206,11 +206,11 @@ export function AuditLogsPage() {
|
|
|
206
206
|
};
|
|
207
207
|
|
|
208
208
|
return (
|
|
209
|
-
<div className="flex-1 overflow-y-auto
|
|
209
|
+
<div className="flex-1 overflow-y-auto pr-12 space-y-6">
|
|
210
210
|
{/* Header */}
|
|
211
211
|
<div className="surface-tile p-6 flex items-center justify-between gap-8">
|
|
212
212
|
<div>
|
|
213
|
-
<h1 className="text-
|
|
213
|
+
<h1 className="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]">
|
|
214
214
|
Audit Logs
|
|
215
215
|
</h1>
|
|
216
216
|
<p className="text-sm text-[var(--kyro-text-secondary)] mt-1 font-medium">
|
|
@@ -320,8 +320,8 @@ export function AuditLogsPage() {
|
|
|
320
320
|
},
|
|
321
321
|
].map(({ label, value, color }) => (
|
|
322
322
|
<div key={label} className="surface-tile p-4">
|
|
323
|
-
<div className={`text-2xl font-
|
|
324
|
-
<div className="text-[10px] font-bold text-[var(--kyro-text-secondary)]
|
|
323
|
+
<div className={`text-2xl font-bold ${color}`}>{value}</div>
|
|
324
|
+
<div className="text-[10px] font-bold text-[var(--kyro-text-secondary)] tracking-wider mt-1">
|
|
325
325
|
{label}
|
|
326
326
|
</div>
|
|
327
327
|
</div>
|
|
@@ -358,7 +358,7 @@ export function AuditLogsPage() {
|
|
|
358
358
|
/>
|
|
359
359
|
</svg>
|
|
360
360
|
</div>
|
|
361
|
-
<p className="font-
|
|
361
|
+
<p className="font-medium text-[var(--kyro-text-primary)] text-base">
|
|
362
362
|
No audit logs found
|
|
363
363
|
</p>
|
|
364
364
|
<p className="text-sm text-[var(--kyro-text-secondary)]">
|
|
@@ -371,7 +371,7 @@ export function AuditLogsPage() {
|
|
|
371
371
|
) : (
|
|
372
372
|
<table className="w-full text-left">
|
|
373
373
|
<thead>
|
|
374
|
-
<tr className="text-[var(--kyro-text-secondary)] font-bold text-[10px]
|
|
374
|
+
<tr className="text-[var(--kyro-text-secondary)] font-bold text-[10px] tracking-[0.2em] border-b border-[var(--kyro-border)]">
|
|
375
375
|
<th className="px-6 py-5 w-8"></th>
|
|
376
376
|
<th className="px-6 py-5">Action</th>
|
|
377
377
|
<th className="px-6 py-5">User</th>
|
|
@@ -405,16 +405,16 @@ export function AuditLogsPage() {
|
|
|
405
405
|
{log.userEmail ? (
|
|
406
406
|
<div className="flex items-center gap-2.5">
|
|
407
407
|
<div
|
|
408
|
-
className={`w-7 h-7 rounded-lg ${getAvatarColor(log.userEmail)} text-[var(--kyro-text-primary)] text-[10px] font-
|
|
408
|
+
className={`w-7 h-7 rounded-lg ${getAvatarColor(log.userEmail)} text-[var(--kyro-text-primary)] text-[10px] font-bold flex items-center justify-center shrink-0`}
|
|
409
409
|
>
|
|
410
410
|
{getInitials(log.userEmail)}
|
|
411
411
|
</div>
|
|
412
412
|
<div>
|
|
413
|
-
<div className="text-sm font-
|
|
413
|
+
<div className="text-sm font-medium text-[var(--kyro-text-primary)] leading-none">
|
|
414
414
|
{log.userEmail.split("@")[0]}
|
|
415
415
|
</div>
|
|
416
416
|
{log.role && (
|
|
417
|
-
<div className="text-[10px] font-bold text-[var(--kyro-text-muted)] mt-0.5
|
|
417
|
+
<div className="text-[10px] font-bold text-[var(--kyro-text-muted)] mt-0.5 tracking-wider">
|
|
418
418
|
{log.role}
|
|
419
419
|
</div>
|
|
420
420
|
)}
|
|
@@ -427,7 +427,7 @@ export function AuditLogsPage() {
|
|
|
427
427
|
)}
|
|
428
428
|
</td>
|
|
429
429
|
<td className="px-6 py-4">
|
|
430
|
-
<div className="text-sm font-
|
|
430
|
+
<div className="text-sm font-medium text-[var(--kyro-text-primary)]">
|
|
431
431
|
{log.resource}
|
|
432
432
|
</div>
|
|
433
433
|
{log.resourceId && (
|
|
@@ -497,11 +497,10 @@ export function AuditLogsPage() {
|
|
|
497
497
|
type="button"
|
|
498
498
|
onClick={() => fetchLogs(page - 1)}
|
|
499
499
|
disabled={page <= 1}
|
|
500
|
-
className={`px-4 py-2 rounded-xl text-sm font-bold transition-all ${
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}`}
|
|
500
|
+
className={`px-4 py-2 rounded-xl text-sm font-bold transition-all ${page <= 1
|
|
501
|
+
? "opacity-30 pointer-events-none text-[var(--kyro-text-muted)]"
|
|
502
|
+
: "bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] hover:bg-[var(--kyro-surface)] border border-[var(--kyro-border)]"
|
|
503
|
+
}`}
|
|
505
504
|
>
|
|
506
505
|
← Prev
|
|
507
506
|
</button>
|
|
@@ -512,11 +511,10 @@ export function AuditLogsPage() {
|
|
|
512
511
|
type="button"
|
|
513
512
|
key={p}
|
|
514
513
|
onClick={() => fetchLogs(p)}
|
|
515
|
-
className={`px-3.5 py-2 rounded-xl text-sm font-bold transition-all ${
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}`}
|
|
514
|
+
className={`px-3.5 py-2 rounded-xl text-sm font-bold transition-all ${p === page
|
|
515
|
+
? "bg-[var(--kyro-sidebar-active)] text-[var(--kyro-sidebar-text-active)]"
|
|
516
|
+
: "bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface)] border border-[var(--kyro-border)]"
|
|
517
|
+
}`}
|
|
520
518
|
>
|
|
521
519
|
{p}
|
|
522
520
|
</button>
|
|
@@ -526,11 +524,10 @@ export function AuditLogsPage() {
|
|
|
526
524
|
type="button"
|
|
527
525
|
onClick={() => fetchLogs(page + 1)}
|
|
528
526
|
disabled={page >= totalPages}
|
|
529
|
-
className={`px-4 py-2 rounded-xl text-sm font-bold transition-all ${
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}`}
|
|
527
|
+
className={`px-4 py-2 rounded-xl text-sm font-bold transition-all ${page >= totalPages
|
|
528
|
+
? "opacity-30 pointer-events-none text-[var(--kyro-text-muted)]"
|
|
529
|
+
: "bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] hover:bg-[var(--kyro-surface)] border border-[var(--kyro-border)]"
|
|
530
|
+
}`}
|
|
534
531
|
>
|
|
535
532
|
Next →
|
|
536
533
|
</button>
|
|
@@ -549,18 +546,17 @@ export function AuditLogsPage() {
|
|
|
549
546
|
<div className="space-y-0">
|
|
550
547
|
{/* Status banner */}
|
|
551
548
|
<div
|
|
552
|
-
className={
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
}`}
|
|
549
|
+
className={`px-4 py-4 mb-6 rounded-lg flex items-center gap-3 ${selectedLog.success
|
|
550
|
+
? "bg-green-500/5 border-b border-green-500/10"
|
|
551
|
+
: "bg-red-500/5 border-b border-red-500/10"
|
|
552
|
+
}`}
|
|
557
553
|
>
|
|
558
554
|
<span
|
|
559
555
|
className={`w-2.5 h-2.5 rounded-full shrink-0 ${selectedLog.success ? "bg-green-500" : "bg-red-500"}`}
|
|
560
556
|
/>
|
|
561
557
|
<div>
|
|
562
558
|
<div
|
|
563
|
-
className={`text-sm font-
|
|
559
|
+
className={`text-sm font-bold ${selectedLog.success ? "text-green-500" : "text-red-500"}`}
|
|
564
560
|
>
|
|
565
561
|
{selectedLog.success ? "Successful" : "Failed"}
|
|
566
562
|
</div>
|
|
@@ -586,7 +582,7 @@ export function AuditLogsPage() {
|
|
|
586
582
|
{/* Error message */}
|
|
587
583
|
{selectedLog.error && (
|
|
588
584
|
<div className="mt-4 -mx-6 px-6 py-4 bg-red-500/5 border-y border-red-500/10">
|
|
589
|
-
<div className="text-[10px] font-bold
|
|
585
|
+
<div className="text-[10px] font-bold tracking-wider text-red-400 mb-2">
|
|
590
586
|
Error
|
|
591
587
|
</div>
|
|
592
588
|
<div className="text-sm font-mono text-red-300">
|
|
@@ -598,7 +594,7 @@ export function AuditLogsPage() {
|
|
|
598
594
|
{/* Changes */}
|
|
599
595
|
{selectedLog.changes && selectedLog.changes.length > 0 && (
|
|
600
596
|
<div className="mt-4">
|
|
601
|
-
<div className="text-[10px] font-bold
|
|
597
|
+
<div className="text-[10px] font-bold tracking-wider text-[var(--kyro-text-muted)] mb-3">
|
|
602
598
|
Changes ({selectedLog.changes.length})
|
|
603
599
|
</div>
|
|
604
600
|
<div className="rounded-xl border border-[var(--kyro-border)] overflow-hidden">
|
|
@@ -607,7 +603,7 @@ export function AuditLogsPage() {
|
|
|
607
603
|
key={i}
|
|
608
604
|
className="flex items-start gap-4 px-4 py-3 text-xs font-mono border-b border-[var(--kyro-border)] last:border-0 hover:bg-[var(--kyro-surface-accent)] transition-colors"
|
|
609
605
|
>
|
|
610
|
-
<span className="text-[10px] font-bold
|
|
606
|
+
<span className="text-[10px] font-bold tracking-wider text-[var(--kyro-text-muted)] w-24 shrink-0 pt-0.5">
|
|
611
607
|
{change.field}
|
|
612
608
|
</span>
|
|
613
609
|
<span className="text-red-400 line-through flex-1 truncate">
|
|
@@ -633,7 +629,7 @@ export function AuditLogsPage() {
|
|
|
633
629
|
{selectedLog.metadata &&
|
|
634
630
|
Object.keys(selectedLog.metadata).length > 0 && (
|
|
635
631
|
<div className="mt-4">
|
|
636
|
-
<div className="text-[10px] font-bold
|
|
632
|
+
<div className="text-[10px] font-bold tracking-wider text-[var(--kyro-text-muted)] mb-3">
|
|
637
633
|
Metadata
|
|
638
634
|
</div>
|
|
639
635
|
<div className="border border-[var(--kyro-border)] overflow-hidden">
|
|
@@ -653,7 +649,7 @@ export function AuditLogsPage() {
|
|
|
653
649
|
{/* User Agent */}
|
|
654
650
|
{selectedLog.userAgent && (
|
|
655
651
|
<div className="mt-4">
|
|
656
|
-
<div className="text-[10px] font-bold
|
|
652
|
+
<div className="text-[10px] font-bold tracking-wider text-[var(--kyro-text-muted)] mb-2">
|
|
657
653
|
User Agent
|
|
658
654
|
</div>
|
|
659
655
|
<div className="text-xs font-mono text-[var(--kyro-text-secondary)] bg-[var(--kyro-bg-secondary)] rounded-lg px-3 py-2 border border-[var(--kyro-border)]">
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useAuthStore } from "../lib/stores";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AuthBridge
|
|
6
|
+
*
|
|
7
|
+
* This component is the critical link between the vanilla-JS auth flow
|
|
8
|
+
* (which runs in AdminLayout.astro and fires `kyro:auth-ready`) and the
|
|
9
|
+
* React Zustand store (`useAuthStore`).
|
|
10
|
+
*
|
|
11
|
+
* It:
|
|
12
|
+
* 1. Checks `window.__kyroAuth` immediately in case the event already fired
|
|
13
|
+
* before this component mounted (race condition on fast networks).
|
|
14
|
+
* 2. Listens for the `kyro:auth-ready` custom event and populates the store.
|
|
15
|
+
*
|
|
16
|
+
* Once the store is hydrated, every React component that calls
|
|
17
|
+
* `useAuthStore()` will automatically re-render with the correct permissions.
|
|
18
|
+
*/
|
|
19
|
+
export function AuthBridge() {
|
|
20
|
+
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const { setUser, setLoading } = useAuthStore.getState();
|
|
24
|
+
|
|
25
|
+
function populate(detail: { user: unknown; permissions: unknown }) {
|
|
26
|
+
if (detail?.user) {
|
|
27
|
+
setUser(detail.user, detail.permissions ?? null);
|
|
28
|
+
} else {
|
|
29
|
+
// Unauthenticated – set loading to false so components don't hang
|
|
30
|
+
setLoading(false);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check if the event already fired before this component mounted
|
|
35
|
+
const cached = (window as { __kyroAuth?: { user: unknown; permissions: unknown; verified: boolean } }).__kyroAuth;
|
|
36
|
+
if (cached?.verified && cached?.user) {
|
|
37
|
+
populate({ user: cached.user, permissions: cached.permissions ?? null });
|
|
38
|
+
return; // No need to register the event listener
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Otherwise wait for the event
|
|
42
|
+
const handler = (event: Event) => {
|
|
43
|
+
populate((event as CustomEvent).detail);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
window.addEventListener("kyro:auth-ready", handler);
|
|
47
|
+
return () => window.removeEventListener("kyro:auth-ready", handler);
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
return null;
|
|
51
|
+
}
|