@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,277 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Blocks,
|
|
4
|
+
Settings,
|
|
5
|
+
ToggleRight,
|
|
6
|
+
ToggleLeft,
|
|
7
|
+
CheckCircle2,
|
|
8
|
+
Clock,
|
|
9
|
+
RefreshCw,
|
|
10
|
+
ShieldCheck,
|
|
11
|
+
Search,
|
|
12
|
+
Plus,
|
|
13
|
+
X,
|
|
14
|
+
} from "./ui/icons";
|
|
15
|
+
import { Modal, ModalContent, ModalActions } from "./ui/Modal";
|
|
16
|
+
import { PageHeader } from "./ui/PageHeader";
|
|
17
|
+
import { Badge } from "./ui/Badge";
|
|
18
|
+
|
|
19
|
+
interface Plugin {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
version: string;
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
author: string;
|
|
26
|
+
updatedAt: string;
|
|
27
|
+
icon: string;
|
|
28
|
+
status: "active" | "error" | "update_available";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const mockPlugins: Plugin[] = [
|
|
32
|
+
{
|
|
33
|
+
id: "seo-optimizer",
|
|
34
|
+
name: "SEO Optimizer Pro",
|
|
35
|
+
description:
|
|
36
|
+
"Advanced meta tags, sitemaps, and rich snippets for all collections.",
|
|
37
|
+
version: "2.1.4",
|
|
38
|
+
enabled: true,
|
|
39
|
+
author: "Kyro Team",
|
|
40
|
+
updatedAt: "2024-05-10T14:30:00Z",
|
|
41
|
+
icon: "search",
|
|
42
|
+
status: "active",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "analytics-dashboard",
|
|
46
|
+
name: "Analytics Integration",
|
|
47
|
+
description:
|
|
48
|
+
"Connect to Google Analytics, Plausible, or Mixpanel for traffic insights.",
|
|
49
|
+
version: "1.0.2",
|
|
50
|
+
enabled: true,
|
|
51
|
+
author: "Kyro Team",
|
|
52
|
+
updatedAt: "2024-04-20T09:15:00Z",
|
|
53
|
+
icon: "activity",
|
|
54
|
+
status: "update_available",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "aws-s3-adapter",
|
|
58
|
+
name: "AWS S3 Storage",
|
|
59
|
+
description: "Cloud storage adapter for Media Library with S3 integration.",
|
|
60
|
+
version: "3.0.0",
|
|
61
|
+
enabled: false,
|
|
62
|
+
author: "AWS",
|
|
63
|
+
updatedAt: "2024-01-15T11:00:00Z",
|
|
64
|
+
icon: "database",
|
|
65
|
+
status: "active",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "ai-writer",
|
|
69
|
+
name: "AI Content Writer",
|
|
70
|
+
description:
|
|
71
|
+
"Generate blog posts and product descriptions with AI assistance.",
|
|
72
|
+
version: "1.2.0",
|
|
73
|
+
enabled: true,
|
|
74
|
+
author: "Kyro Team",
|
|
75
|
+
updatedAt: "2024-05-01T10:00:00Z",
|
|
76
|
+
icon: "sparkles",
|
|
77
|
+
status: "active",
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
export function PluginsManager() {
|
|
82
|
+
const [plugins, setPlugins] = useState<Plugin[]>(mockPlugins);
|
|
83
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
84
|
+
const [showConfigModal, setShowConfigModal] = useState<string | null>(null);
|
|
85
|
+
|
|
86
|
+
const togglePlugin = (id: string) => {
|
|
87
|
+
setPlugins((prev) =>
|
|
88
|
+
prev.map((p) => (p.id === id ? { ...p, enabled: !p.enabled } : p)),
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const filteredPlugins = plugins.filter(
|
|
93
|
+
(p) =>
|
|
94
|
+
p.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
95
|
+
p.description.toLowerCase().includes(searchQuery.toLowerCase()),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const activeCount = plugins.filter((p) => p.enabled).length;
|
|
99
|
+
const updateCount = plugins.filter(
|
|
100
|
+
(p) => p.status === "update_available",
|
|
101
|
+
).length;
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div className="w-full space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-700 pb-32">
|
|
105
|
+
<PageHeader
|
|
106
|
+
title="Plugins"
|
|
107
|
+
description="Extend Kyro CMS with modular features and integrations."
|
|
108
|
+
icon={Blocks}
|
|
109
|
+
actions={[
|
|
110
|
+
{
|
|
111
|
+
label: "Marketplace",
|
|
112
|
+
onClick: () => (window.location.href = "/admin/marketplace"),
|
|
113
|
+
icon: Plus,
|
|
114
|
+
},
|
|
115
|
+
]}
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<div className="flex flex-col gap-8 surface-tile p-8">
|
|
119
|
+
{/* Stats Summary */}
|
|
120
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
121
|
+
<div className="p-4 rounded-2xl bg-[var(--kyro-bg-secondary)]/50 border border-[var(--kyro-border)] flex items-center gap-3 group hover:border-[var(--kyro-primary)]/30 transition-all">
|
|
122
|
+
<div className="p-2.5 bg-green-500/10 rounded-xl group-hover:scale-105 transition-transform">
|
|
123
|
+
<CheckCircle2 className="w-4 h-4 text-green-500" />
|
|
124
|
+
</div>
|
|
125
|
+
<div>
|
|
126
|
+
<div className="text-[9px] font-bold opacity-40 uppercase tracking-widest mb-0.5">Active</div>
|
|
127
|
+
<div className="text-sm font-bold tracking-tight">{activeCount} Plugins Enabled</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div className="p-4 rounded-2xl bg-[var(--kyro-bg-secondary)]/50 border border-[var(--kyro-border)] flex items-center gap-3 group hover:border-[var(--kyro-primary)]/30 transition-all">
|
|
131
|
+
<div className="p-2.5 bg-amber-500/10 rounded-xl group-hover:scale-105 transition-transform">
|
|
132
|
+
<RefreshCw className={`w-4 h-4 text-amber-500 ${updateCount > 0 ? "animate-spin-slow" : ""}`} />
|
|
133
|
+
</div>
|
|
134
|
+
<div>
|
|
135
|
+
<div className="text-[9px] font-bold opacity-40 uppercase tracking-widest mb-0.5">Maintenance</div>
|
|
136
|
+
<div className="text-sm font-bold tracking-tight">{updateCount} Updates Ready</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div className="p-4 rounded-2xl bg-[var(--kyro-bg-secondary)]/50 border border-[var(--kyro-border)] flex items-center gap-3 group hover:border-[var(--kyro-primary)]/30 transition-all">
|
|
140
|
+
<div className="p-2.5 bg-[var(--kyro-primary)]/10 rounded-xl group-hover:scale-105 transition-transform">
|
|
141
|
+
<ShieldCheck className="w-4 h-4 text-[var(--kyro-primary)]" />
|
|
142
|
+
</div>
|
|
143
|
+
<div>
|
|
144
|
+
<div className="text-[9px] font-bold opacity-40 uppercase tracking-widest mb-0.5">Security</div>
|
|
145
|
+
<div className="text-sm font-bold tracking-tight">Verified Ecosystem</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
{/* Search & Filter */}
|
|
151
|
+
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-4 border-b border-[var(--kyro-border)]/50">
|
|
152
|
+
<div className="relative group max-w-sm w-full">
|
|
153
|
+
<div className="absolute -inset-0.5 bg-gradient-to-r from-[var(--kyro-primary)]/10 to-transparent rounded-xl blur opacity-0 group-hover:opacity-100 transition-all duration-500"></div>
|
|
154
|
+
<div className="relative">
|
|
155
|
+
<Search className="w-4 h-4 absolute left-3.5 top-1/2 -translate-y-1/2 text-[var(--kyro-text-secondary)] opacity-40" />
|
|
156
|
+
<input
|
|
157
|
+
type="text"
|
|
158
|
+
placeholder="Search ecosystem..."
|
|
159
|
+
value={searchQuery}
|
|
160
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
161
|
+
className="w-full pl-10 pr-4 py-3 bg-[var(--kyro-bg-secondary)] border border-[var(--kyro-border)] rounded-xl text-xs focus:outline-none focus:border-[var(--kyro-primary)]/50 transition-all"
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div className="flex items-center gap-2 px-1">
|
|
167
|
+
<div className="w-0.5 h-3 bg-[var(--kyro-primary)] rounded-full" />
|
|
168
|
+
<h2 className="text-[10px] font-bold tracking-[0.2em] opacity-40 uppercase">Installed Extensions</h2>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
{/* Plugin Grid */}
|
|
173
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
|
174
|
+
{filteredPlugins.length > 0 ? (
|
|
175
|
+
filteredPlugins.map((plugin) => (
|
|
176
|
+
<div
|
|
177
|
+
key={plugin.id}
|
|
178
|
+
className={`group relative overflow-hidden bg-[var(--kyro-bg-secondary)]/30 border border-[var(--kyro-border)] rounded-2xl p-5 hover:border-[var(--kyro-primary)]/50 transition-all duration-300 ${!plugin.enabled ? "grayscale opacity-60" : ""}`}
|
|
179
|
+
>
|
|
180
|
+
<div className="flex flex-col gap-4 relative z-10">
|
|
181
|
+
<div className="flex items-start justify-between gap-3">
|
|
182
|
+
<div className="flex items-center gap-2.5">
|
|
183
|
+
<div className="p-2 bg-[var(--kyro-surface)] rounded-xl group-hover:bg-[var(--kyro-primary)]/10 transition-colors shadow-sm">
|
|
184
|
+
<Blocks className="w-5 h-5 text-[var(--kyro-text-secondary)] group-hover:text-[var(--kyro-primary)] transition-colors" />
|
|
185
|
+
</div>
|
|
186
|
+
<div>
|
|
187
|
+
<h3 className="font-bold text-base leading-none mb-1.5">{plugin.name}</h3>
|
|
188
|
+
<div className="flex items-center gap-1.5">
|
|
189
|
+
<span className={`w-1 h-1 rounded-full ${plugin.enabled ? "bg-green-500" : "bg-red-500"}`} />
|
|
190
|
+
<span className="text-[9px] font-bold opacity-40 uppercase tracking-tighter">
|
|
191
|
+
{plugin.enabled ? "Active" : "Disabled"}
|
|
192
|
+
</span>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
{plugin.status === "update_available" && (
|
|
197
|
+
<Badge variant="warning" className="text-[7px] font-bold px-1.5 py-0.5 animate-pulse">Update</Badge>
|
|
198
|
+
)}
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<p className="text-xs text-[var(--kyro-text-secondary)] opacity-70 leading-relaxed min-h-[32px] line-clamp-2">
|
|
202
|
+
{plugin.description}
|
|
203
|
+
</p>
|
|
204
|
+
|
|
205
|
+
<div className="flex items-center justify-between pt-3 border-t border-[var(--kyro-border)]/50">
|
|
206
|
+
<div className="flex items-center gap-3 text-[9px] font-bold opacity-40 uppercase tracking-widest">
|
|
207
|
+
<div className="flex items-center gap-1">
|
|
208
|
+
<Clock className="w-2.5 h-2.5" />
|
|
209
|
+
v{plugin.version}
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
<div className="flex items-center gap-1.5">
|
|
214
|
+
<button
|
|
215
|
+
type="button"
|
|
216
|
+
onClick={() => setShowConfigModal(plugin.id)}
|
|
217
|
+
className="p-2 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-lg hover:border-[var(--kyro-primary)] transition-all disabled:opacity-30 shadow-sm"
|
|
218
|
+
disabled={!plugin.enabled}
|
|
219
|
+
>
|
|
220
|
+
<Settings className="w-3.5 h-3.5" />
|
|
221
|
+
</button>
|
|
222
|
+
<button
|
|
223
|
+
type="button"
|
|
224
|
+
onClick={() => togglePlugin(plugin.id)}
|
|
225
|
+
className={`p-2 border rounded-lg transition-all shadow-sm ${plugin.enabled
|
|
226
|
+
? "bg-red-500/5 border-red-500/10 text-red-500/40 hover:text-red-500 hover:border-red-500/30"
|
|
227
|
+
: "bg-green-500/5 border-green-500/10 text-green-500/40 hover:text-green-500 hover:border-green-500/30"
|
|
228
|
+
}`}
|
|
229
|
+
>
|
|
230
|
+
{plugin.enabled ? <X className="w-3.5 h-3.5" /> : <Plus className="w-3.5 h-3.5" />}
|
|
231
|
+
</button>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
))
|
|
237
|
+
) : (
|
|
238
|
+
<div className="col-span-full p-12 text-center rounded-3xl border border-dashed border-[var(--kyro-border)] bg-[var(--kyro-surface-accent)]/30">
|
|
239
|
+
<Blocks className="w-10 h-10 mx-auto mb-3 text-[var(--kyro-text-secondary)] opacity-20" />
|
|
240
|
+
<h3 className="text-lg font-bold mb-1">No results</h3>
|
|
241
|
+
<p className="text-xs text-[var(--kyro-text-secondary)] opacity-50">Try adjusting your search query.</p>
|
|
242
|
+
</div>
|
|
243
|
+
)}
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
{/* Modal */}
|
|
248
|
+
<Modal
|
|
249
|
+
open={!!showConfigModal}
|
|
250
|
+
onClose={() => setShowConfigModal(null)}
|
|
251
|
+
title="Plugin Architecture"
|
|
252
|
+
size="lg"
|
|
253
|
+
>
|
|
254
|
+
<ModalContent>
|
|
255
|
+
<div className="p-12 text-center space-y-4">
|
|
256
|
+
<div className="w-20 h-20 mx-auto bg-[var(--kyro-surface-accent)] rounded-3xl flex items-center justify-center border border-[var(--kyro-border)] shadow-xl">
|
|
257
|
+
<Settings className="w-10 h-10 text-[var(--kyro-primary)] opacity-40 animate-spin-slow" />
|
|
258
|
+
</div>
|
|
259
|
+
<div>
|
|
260
|
+
<h4 className="text-xl font-bold mb-1">Advanced Configuration</h4>
|
|
261
|
+
<p className="text-sm text-[var(--kyro-text-secondary)] opacity-50 italic">Settings for this plugin will be synthesized dynamically from its manifest.</p>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</ModalContent>
|
|
265
|
+
<ModalActions>
|
|
266
|
+
<button
|
|
267
|
+
type="button"
|
|
268
|
+
onClick={() => setShowConfigModal(null)}
|
|
269
|
+
className="w-full py-3 rounded-xl font-bold text-sm bg-[var(--kyro-primary)] text-white hover:opacity-90 transition-all shadow-lg shadow-[var(--kyro-primary)]/20"
|
|
270
|
+
>
|
|
271
|
+
Save Configuration
|
|
272
|
+
</button>
|
|
273
|
+
</ModalActions>
|
|
274
|
+
</Modal>
|
|
275
|
+
</div>
|
|
276
|
+
);
|
|
277
|
+
}
|