@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
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "
|
|
6
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
7
7
|
import { AccordionField } from "../fields/AccordionField";
|
|
8
8
|
|
|
9
|
-
export const AccordionBlock: React.FC<{ block:
|
|
9
|
+
export const AccordionBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
@@ -16,7 +16,7 @@ export const AccordionBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
16
16
|
const data = blockData?.data ?? block.data ?? {};
|
|
17
17
|
const items = Array.isArray(data.items) ? data.items : [];
|
|
18
18
|
|
|
19
|
-
const handleChange = (items:
|
|
19
|
+
const handleChange = (items: Record<string, unknown>[]) => {
|
|
20
20
|
updateBlock(block.id, { data: { ...data, items } });
|
|
21
21
|
};
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ export const AccordionBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
24
24
|
<div className="block-accordion border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
|
|
25
25
|
<div className="flex items-center justify-between mb-2">
|
|
26
26
|
<div className="flex items-center gap-2">
|
|
27
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
27
|
+
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
|
|
28
28
|
Accordion
|
|
29
29
|
</span>
|
|
30
30
|
<span className="text-[10px] text-[var(--kyro-text-muted)]">
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "
|
|
6
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
7
7
|
import { ArrayField } from "../fields/ArrayField";
|
|
8
8
|
import { ChildBlocksTree } from "./ChildBlocksTree";
|
|
9
9
|
|
|
10
|
-
export const ArrayBlock: React.FC<{ block:
|
|
10
|
+
export const ArrayBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
11
11
|
block,
|
|
12
12
|
index,
|
|
13
13
|
}) => {
|
|
@@ -22,7 +22,7 @@ export const ArrayBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
22
22
|
<div className="block-array border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
|
|
23
23
|
<div className="flex items-center justify-between mb-2">
|
|
24
24
|
<div className="flex items-center gap-2">
|
|
25
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
25
|
+
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
|
|
26
26
|
Repeater
|
|
27
27
|
</span>
|
|
28
28
|
<span className="text-[10px] text-[var(--kyro-text-muted)]">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { ChevronRight } from "
|
|
2
|
+
import { ChevronRight } from "../ui/icons";
|
|
3
3
|
import {
|
|
4
4
|
useBlockById,
|
|
5
5
|
useBlockActions,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "../fields";
|
|
25
25
|
|
|
26
26
|
interface BlockEditModalProps {
|
|
27
|
-
block:
|
|
27
|
+
block: Record<string, unknown>;
|
|
28
28
|
onClose: () => void;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -40,17 +40,17 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
|
|
|
40
40
|
const data = blockData?.data || block.data || {};
|
|
41
41
|
const children = blockData?.children || block.children || [];
|
|
42
42
|
|
|
43
|
-
const handleChange = (field: string, value:
|
|
43
|
+
const handleChange = (field: string, value: unknown) => {
|
|
44
44
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
const handleUpdateChildren = (newChildren:
|
|
47
|
+
const handleUpdateChildren = (newChildren: Record<string, unknown>[]) => {
|
|
48
48
|
updateBlock(block.id, { children: newChildren });
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
const handleUpdateColumnChildren = (
|
|
52
52
|
columnIndex: number,
|
|
53
|
-
newChildren:
|
|
53
|
+
newChildren: Record<string, unknown>[],
|
|
54
54
|
) => {
|
|
55
55
|
const columnData = data.columnData || [];
|
|
56
56
|
const newColumnData = [...columnData];
|
|
@@ -90,7 +90,7 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
|
|
|
90
90
|
<PortableTextField
|
|
91
91
|
field={{ name: "richtext", label: "Content" }}
|
|
92
92
|
value={data.content}
|
|
93
|
-
onChange={(value:
|
|
93
|
+
onChange={(value: unknown) => handleChange("content", value)}
|
|
94
94
|
/>
|
|
95
95
|
</div>
|
|
96
96
|
);
|
|
@@ -184,14 +184,14 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
|
|
|
184
184
|
|
|
185
185
|
<div className="grid grid-cols-2 gap-3">
|
|
186
186
|
<div>
|
|
187
|
-
<label className="text-[10px] font-bold
|
|
187
|
+
<label className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-1.5 block">
|
|
188
188
|
Language
|
|
189
189
|
</label>
|
|
190
190
|
<div className="relative">
|
|
191
191
|
<select
|
|
192
192
|
value={data.language || "javascript"}
|
|
193
193
|
onChange={(e) => handleChange("language", e.target.value)}
|
|
194
|
-
className="w-full pl-3 pr-10 py-2.5 bg-[var(--kyro-bg-secondary)] border border-[var(--kyro-border)] rounded-xl text-xs font-
|
|
194
|
+
className="w-full pl-3 pr-10 py-2.5 bg-[var(--kyro-bg-secondary)] border border-[var(--kyro-border)] rounded-xl text-xs font-medium text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 transition-all appearance-none cursor-pointer"
|
|
195
195
|
>
|
|
196
196
|
<option value="plaintext">Plain Text</option>
|
|
197
197
|
<option value="javascript">JS</option>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
3
|
+
import { useBlockActions } from "../fields/extensions/blocksStore";
|
|
4
|
+
|
|
5
|
+
interface BlockWrapperProps {
|
|
6
|
+
id: string;
|
|
7
|
+
type: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const BlockWrapper: React.FC<BlockWrapperProps> = ({
|
|
14
|
+
id,
|
|
15
|
+
type,
|
|
16
|
+
label,
|
|
17
|
+
children,
|
|
18
|
+
className = "",
|
|
19
|
+
}) => {
|
|
20
|
+
const { moveBlock, removeBlock } = useBlockActions();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div className={`block-${type} border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group bg-[var(--kyro-surface)] transition-all hover:border-[var(--kyro-primary)]/30 ${className}`}>
|
|
24
|
+
<div className="flex items-center justify-between mb-2">
|
|
25
|
+
<span className="text-[10px] font-bold text-[var(--kyro-text-muted)] tracking-wider">
|
|
26
|
+
{label || type}
|
|
27
|
+
</span>
|
|
28
|
+
<div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
onClick={() => moveBlock(id, "up")}
|
|
32
|
+
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
|
|
33
|
+
title="Move up"
|
|
34
|
+
>
|
|
35
|
+
<ChevronRight className="w-3 h-3 rotate-90" />
|
|
36
|
+
</button>
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
onClick={() => moveBlock(id, "down")}
|
|
40
|
+
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
|
|
41
|
+
title="Move down"
|
|
42
|
+
>
|
|
43
|
+
<ChevronRight className="w-3 h-3" />
|
|
44
|
+
</button>
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
onClick={() => removeBlock(id)}
|
|
48
|
+
className="p-1 hover:bg-[var(--kyro-error)]/10 rounded text-[var(--kyro-error)]"
|
|
49
|
+
title="Remove"
|
|
50
|
+
>
|
|
51
|
+
<X className="w-3 h-3" />
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div className="block-content">
|
|
57
|
+
{children}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "
|
|
6
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
7
7
|
import { ButtonField } from "../fields/ButtonField";
|
|
8
8
|
|
|
9
|
-
export const ButtonBlock: React.FC<{ block:
|
|
9
|
+
export const ButtonBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
@@ -15,14 +15,14 @@ export const ButtonBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
15
15
|
|
|
16
16
|
const data = blockData?.data ?? block.data ?? {};
|
|
17
17
|
|
|
18
|
-
const handleChange = (field: string, value:
|
|
18
|
+
const handleChange = (field: string, value: unknown) => {
|
|
19
19
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<div className="block-button border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
|
|
24
24
|
<div className="flex items-center justify-between mb-2">
|
|
25
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
25
|
+
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
|
|
26
26
|
Button
|
|
27
27
|
</span>
|
|
28
28
|
<div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import { Plus, X, ChevronRight, ChevronDown } from "
|
|
2
|
+
import { Plus, X, ChevronRight, ChevronDown } from "../ui/icons";
|
|
3
3
|
import {
|
|
4
4
|
blockCategories,
|
|
5
5
|
blockIcons,
|
|
@@ -12,8 +12,8 @@ import { BlockEditModal } from "./BlockEditModal";
|
|
|
12
12
|
|
|
13
13
|
interface ChildBlocksTreeProps {
|
|
14
14
|
blockId: string;
|
|
15
|
-
children:
|
|
16
|
-
onUpdateChildren: (children:
|
|
15
|
+
children: Record<string, unknown>[];
|
|
16
|
+
onUpdateChildren: (children: Record<string, unknown>[]) => void;
|
|
17
17
|
depth?: number;
|
|
18
18
|
maxDepth?: number;
|
|
19
19
|
}
|
|
@@ -47,7 +47,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
47
47
|
onUpdateChildren(filtered);
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const handleUpdateChildData = (childId: string, newData:
|
|
50
|
+
const handleUpdateChildData = (childId: string, newData: Record<string, unknown>) => {
|
|
51
51
|
const updated = children.map((child) => {
|
|
52
52
|
if (child.id === childId) {
|
|
53
53
|
return { ...child, data: newData };
|
|
@@ -59,7 +59,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
59
59
|
|
|
60
60
|
const handleUpdateChildChildren = (
|
|
61
61
|
childId: string,
|
|
62
|
-
newGrandchildren:
|
|
62
|
+
newGrandchildren: Record<string, unknown>[],
|
|
63
63
|
) => {
|
|
64
64
|
const updated = children.map((child) => {
|
|
65
65
|
if (child.id === childId) {
|
|
@@ -82,7 +82,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
82
82
|
});
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
const renderBlock = (child:
|
|
85
|
+
const renderBlock = (child: Record<string, unknown>) => {
|
|
86
86
|
const hasChildren = child.children && child.children.length > 0;
|
|
87
87
|
const isExpanded = expandedIds.has(child.id);
|
|
88
88
|
const BlockComponent = getBlockComponent(child.type);
|
|
@@ -92,11 +92,10 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
92
92
|
return (
|
|
93
93
|
<div key={child.id} className="relative group">
|
|
94
94
|
<div
|
|
95
|
-
className={`flex items-center group/column gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
} ${canAddChildren ? "cursor-pointer" : ""}`}
|
|
95
|
+
className={`flex items-center group/column gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${isEditing
|
|
96
|
+
? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
|
|
97
|
+
: "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
|
|
98
|
+
} ${canAddChildren ? "cursor-pointer" : ""}`}
|
|
100
99
|
style={{ marginLeft: depth * indentWidth }}
|
|
101
100
|
onClick={() => {
|
|
102
101
|
if (canAddChildren) {
|
|
@@ -226,7 +225,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
226
225
|
>
|
|
227
226
|
{blockCategories.map((category) => (
|
|
228
227
|
<div key={category.title} className="mb-4">
|
|
229
|
-
<h3 className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
228
|
+
<h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] tracking-wide mb-2">
|
|
230
229
|
{category.title}
|
|
231
230
|
</h3>
|
|
232
231
|
<div className="grid grid-cols-3 gap-2">
|
|
@@ -244,7 +243,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
244
243
|
{blockIcons[block.icon]}
|
|
245
244
|
</div>
|
|
246
245
|
<div className="flex-1 min-w-0">
|
|
247
|
-
<div className="text-xs font-medium
|
|
246
|
+
<div className="text-xs font-medium tracking-tight text-[var(--kyro-text-primary)]">
|
|
248
247
|
{block.label}
|
|
249
248
|
</div>
|
|
250
249
|
<div className="text-[10px] text-[var(--kyro-text-muted)] mt-0.5">
|
|
@@ -283,8 +282,8 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
283
282
|
|
|
284
283
|
interface NestedChildBlocksProps {
|
|
285
284
|
parentId: string;
|
|
286
|
-
children:
|
|
287
|
-
onUpdateChildren: (children:
|
|
285
|
+
children: Record<string, unknown>[];
|
|
286
|
+
onUpdateChildren: (children: Record<string, unknown>[]) => void;
|
|
288
287
|
depth: number;
|
|
289
288
|
maxDepth: number;
|
|
290
289
|
}
|
|
@@ -316,7 +315,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
316
315
|
onUpdateChildren(filtered);
|
|
317
316
|
};
|
|
318
317
|
|
|
319
|
-
const handleUpdateChildData = (childId: string, newData:
|
|
318
|
+
const handleUpdateChildData = (childId: string, newData: Record<string, unknown>) => {
|
|
320
319
|
const updated = children.map((child) => {
|
|
321
320
|
if (child.id === childId) {
|
|
322
321
|
return { ...child, data: newData };
|
|
@@ -328,7 +327,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
328
327
|
|
|
329
328
|
const handleUpdateChildChildren = (
|
|
330
329
|
childId: string,
|
|
331
|
-
newGrandchildren:
|
|
330
|
+
newGrandchildren: Record<string, unknown>[],
|
|
332
331
|
) => {
|
|
333
332
|
const updated = children.map((child) => {
|
|
334
333
|
if (child.id === childId) {
|
|
@@ -351,7 +350,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
351
350
|
});
|
|
352
351
|
};
|
|
353
352
|
|
|
354
|
-
const renderBlock = (child:
|
|
353
|
+
const renderBlock = (child: Record<string, unknown>) => {
|
|
355
354
|
const hasChildren = child.children && child.children.length > 0;
|
|
356
355
|
const isExpanded = expandedIds.has(child.id);
|
|
357
356
|
const BlockComponent = getBlockComponent(child.type);
|
|
@@ -361,11 +360,10 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
361
360
|
return (
|
|
362
361
|
<div key={child.id} className="relative group">
|
|
363
362
|
<div
|
|
364
|
-
className={`flex items-center gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
} ${canAddChildren ? "cursor-pointer" : ""}`}
|
|
363
|
+
className={`flex items-center gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${isEditing
|
|
364
|
+
? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
|
|
365
|
+
: "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
|
|
366
|
+
} ${canAddChildren ? "cursor-pointer" : ""}`}
|
|
369
367
|
style={{ marginLeft: depth * indentWidth }}
|
|
370
368
|
onClick={() => {
|
|
371
369
|
if (canAddChildren) {
|
|
@@ -495,7 +493,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
495
493
|
>
|
|
496
494
|
{blockCategories.map((category) => (
|
|
497
495
|
<div key={category.title} className="mb-4">
|
|
498
|
-
<h3 className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
496
|
+
<h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] tracking-wide mb-2">
|
|
499
497
|
{category.title}
|
|
500
498
|
</h3>
|
|
501
499
|
<div className="grid grid-cols-3 gap-2">
|
|
@@ -513,7 +511,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
513
511
|
{blockIcons[block.icon]}
|
|
514
512
|
</div>
|
|
515
513
|
<div className="flex-1 min-w-0">
|
|
516
|
-
<div className="text-xs font-medium
|
|
514
|
+
<div className="text-xs font-medium tracking-tight text-[var(--kyro-text-primary)]">
|
|
517
515
|
{block.label}
|
|
518
516
|
</div>
|
|
519
517
|
<div className="text-[10px] text-[var(--kyro-text-muted)] mt-0.5">
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X, Code2 } from "
|
|
6
|
+
import { ChevronRight, X, Code2 } from "../ui/icons";
|
|
7
7
|
import { CodeField } from "../fields/CodeField";
|
|
8
8
|
|
|
9
|
-
export const CodeBlock: React.FC<{ block:
|
|
9
|
+
export const CodeBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
@@ -14,7 +14,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
14
14
|
const { updateBlock, removeBlock, moveBlock } = useBlockActions();
|
|
15
15
|
const data = blockData?.data ?? block.data ?? {};
|
|
16
16
|
|
|
17
|
-
const handleChange = (field: string, value:
|
|
17
|
+
const handleChange = (field: string, value: unknown) => {
|
|
18
18
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
19
19
|
};
|
|
20
20
|
|
|
@@ -27,15 +27,15 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
27
27
|
</div>
|
|
28
28
|
<div>
|
|
29
29
|
<h4 className="text-sm font-bold tracking-tight text-[var(--kyro-text-primary)]">Code Snippet</h4>
|
|
30
|
-
<p className="text-[10px] font-medium text-[var(--kyro-text-muted)]
|
|
30
|
+
<p className="text-[10px] font-medium text-[var(--kyro-text-muted)] tracking-widest">
|
|
31
31
|
Block Editor • {data.language || "javascript"}
|
|
32
32
|
</p>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
<div className="flex items-center gap-1.5 opacity-0 group-hover/block:opacity-100 transition-all translate-x-2 group-hover/block:translate-x-0">
|
|
37
37
|
<div className="flex bg-[var(--kyro-surface-accent)]/50 p-1 rounded-xl border border-[var(--kyro-border)]">
|
|
38
|
-
<button
|
|
38
|
+
<button
|
|
39
39
|
type="button"
|
|
40
40
|
onClick={() => moveBlock(block.id, "up")}
|
|
41
41
|
className="p-1.5 hover:bg-[var(--kyro-surface)] rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
|
|
@@ -44,7 +44,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
44
44
|
<ChevronRight className="w-4 h-4 rotate-[-90deg]" />
|
|
45
45
|
</button>
|
|
46
46
|
<div className="w-px h-4 bg-[var(--kyro-border)] mx-1 self-center" />
|
|
47
|
-
<button
|
|
47
|
+
<button
|
|
48
48
|
type="button"
|
|
49
49
|
onClick={() => removeBlock(block.id)}
|
|
50
50
|
className="p-1.5 hover:bg-red-500/10 rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-red-500"
|
|
@@ -55,7 +55,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
57
|
</div>
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
<div className="space-y-6">
|
|
60
60
|
<CodeField
|
|
61
61
|
field={{
|
|
@@ -67,17 +67,17 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
67
67
|
value={data.code || ""}
|
|
68
68
|
onChange={(val) => handleChange("code", val)}
|
|
69
69
|
/>
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
<div className="flex items-center gap-4 bg-[var(--kyro-surface-accent)]/20 p-4 rounded-xl border border-[var(--kyro-border)]/50">
|
|
72
72
|
<div className="flex-1">
|
|
73
|
-
<label className="text-[10px] font-
|
|
73
|
+
<label className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-2 block">
|
|
74
74
|
Syntax Highlighting
|
|
75
75
|
</label>
|
|
76
76
|
<div className="relative">
|
|
77
77
|
<select
|
|
78
78
|
value={data.language || "javascript"}
|
|
79
79
|
onChange={(e) => handleChange("language", e.target.value)}
|
|
80
|
-
className="w-full pl-4 pr-10 py-2.5 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl text-xs font-
|
|
80
|
+
className="w-full pl-4 pr-10 py-2.5 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl text-xs font-medium text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 focus:border-[var(--kyro-primary)] transition-all appearance-none cursor-pointer"
|
|
81
81
|
>
|
|
82
82
|
<option value="plaintext">Plain Text</option>
|
|
83
83
|
<option value="javascript">JavaScript</option>
|
|
@@ -95,16 +95,16 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
95
95
|
</div>
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
<div className="hidden sm:block w-px h-10 bg-[var(--kyro-border)]" />
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
<div className="hidden sm:flex flex-col justify-center">
|
|
102
|
-
<span className="text-[10px] font-
|
|
102
|
+
<span className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-2">
|
|
103
103
|
Status
|
|
104
104
|
</span>
|
|
105
105
|
<div className="flex items-center gap-2 px-3 py-2 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl">
|
|
106
106
|
<div className="w-2 h-2 rounded-full bg-blue-500 animate-pulse" />
|
|
107
|
-
<span className="text-[10px] font-
|
|
107
|
+
<span className="text-[10px] font-medium text-[var(--kyro-text-primary)] tracking-wide">EDITING</span>
|
|
108
108
|
</div>
|
|
109
109
|
</div>
|
|
110
110
|
</div>
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X, Columns3 } from "lucide-react";
|
|
7
6
|
import { ColumnsField } from "../fields/ColumnsField";
|
|
7
|
+
import { BlockWrapper } from "./BlockWrapper";
|
|
8
8
|
|
|
9
|
-
export const ColumnsBlock: React.FC<{ block:
|
|
9
|
+
export const ColumnsBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
13
13
|
const blockData = useBlockById(block.id);
|
|
14
|
-
const { updateBlock
|
|
14
|
+
const { updateBlock } = useBlockActions();
|
|
15
15
|
|
|
16
16
|
const data = blockData?.data ?? block.data ?? {};
|
|
17
17
|
const columns = data.columns || 2;
|
|
@@ -30,7 +30,7 @@ export const ColumnsBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
30
30
|
|
|
31
31
|
const handleUpdateColumnChildren = (
|
|
32
32
|
columnIndex: number,
|
|
33
|
-
newChildren:
|
|
33
|
+
newChildren: Record<string, unknown>[],
|
|
34
34
|
) => {
|
|
35
35
|
const newColumnData = [...columnData];
|
|
36
36
|
newColumnData[columnIndex] = {
|
|
@@ -43,51 +43,13 @@ export const ColumnsBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
|
-
<
|
|
47
|
-
<div className="flex items-center justify-between mb-2">
|
|
48
|
-
<div className="flex items-center gap-2">
|
|
49
|
-
<Columns3 className="w-3.5 h-3.5 text-[var(--kyro-primary)]" />
|
|
50
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
|
|
51
|
-
Columns
|
|
52
|
-
</span>
|
|
53
|
-
<span className="text-[10px] text-[var(--kyro-text-muted)]">
|
|
54
|
-
({columns})
|
|
55
|
-
</span>
|
|
56
|
-
</div>
|
|
57
|
-
<div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
58
|
-
<button
|
|
59
|
-
type="button"
|
|
60
|
-
onClick={() => moveBlock(block.id, "up")}
|
|
61
|
-
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
|
|
62
|
-
title="Move up"
|
|
63
|
-
>
|
|
64
|
-
<ChevronRight className="w-3 h-3 rotate-90" />
|
|
65
|
-
</button>
|
|
66
|
-
<button
|
|
67
|
-
type="button"
|
|
68
|
-
onClick={() => moveBlock(block.id, "down")}
|
|
69
|
-
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
|
|
70
|
-
title="Move down"
|
|
71
|
-
>
|
|
72
|
-
<ChevronRight className="w-3 h-3" />
|
|
73
|
-
</button>
|
|
74
|
-
<button
|
|
75
|
-
type="button"
|
|
76
|
-
onClick={() => removeBlock(block.id)}
|
|
77
|
-
className="p-1 hover:bg-red-50 rounded text-red-500"
|
|
78
|
-
title="Remove"
|
|
79
|
-
>
|
|
80
|
-
<X className="w-3 h-3" />
|
|
81
|
-
</button>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
46
|
+
<BlockWrapper id={block.id} type="columns" label="Columns">
|
|
85
47
|
<ColumnsField
|
|
86
48
|
columns={columns}
|
|
87
49
|
columnData={columnData}
|
|
88
50
|
onColumnsChange={handleColumnsChange}
|
|
89
51
|
onUpdateColumnChildren={handleUpdateColumnChildren}
|
|
90
52
|
/>
|
|
91
|
-
</
|
|
53
|
+
</BlockWrapper>
|
|
92
54
|
);
|
|
93
55
|
};
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "
|
|
6
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
7
7
|
|
|
8
|
-
export const DividerBlock: React.FC<{ block:
|
|
8
|
+
export const DividerBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
9
9
|
block,
|
|
10
10
|
index,
|
|
11
11
|
}) => {
|
|
12
12
|
const blockData = useBlockById(block.id);
|
|
13
13
|
const { updateBlock, removeBlock, moveBlock } = useBlockActions();
|
|
14
14
|
const data = blockData?.data ?? block.data ?? {};
|
|
15
|
-
const handleChange = (field: string, value:
|
|
15
|
+
const handleChange = (field: string, value: unknown) => {
|
|
16
16
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "
|
|
6
|
+
import { ChevronRight, X } from "../ui/icons";
|
|
7
7
|
import { UploadField } from "../fields/UploadField";
|
|
8
8
|
|
|
9
|
-
export const FileBlock: React.FC<{ block:
|
|
9
|
+
export const FileBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
@@ -15,14 +15,14 @@ export const FileBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
15
15
|
|
|
16
16
|
const data = blockData?.data ?? block.data ?? {};
|
|
17
17
|
|
|
18
|
-
const handleChange = (field: string, value:
|
|
18
|
+
const handleChange = (field: string, value: unknown) => {
|
|
19
19
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
23
|
<div className="block-file border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
|
|
24
24
|
<div className="flex items-center justify-between mb-1">
|
|
25
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)]
|
|
25
|
+
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
|
|
26
26
|
File
|
|
27
27
|
</span>
|
|
28
28
|
<div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
@@ -3,57 +3,25 @@ import {
|
|
|
3
3
|
useBlockById,
|
|
4
4
|
useBlockActions,
|
|
5
5
|
} from "../fields/extensions/blocksStore";
|
|
6
|
-
import { ChevronRight, X } from "lucide-react";
|
|
7
6
|
import { HeadingField } from "../fields/HeadingField";
|
|
7
|
+
import { BlockWrapper } from "./BlockWrapper";
|
|
8
8
|
|
|
9
|
-
export const HeadingBlock: React.FC<{ block:
|
|
9
|
+
export const HeadingBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
|
|
10
10
|
block,
|
|
11
11
|
index,
|
|
12
12
|
}) => {
|
|
13
13
|
const blockData = useBlockById(block.id);
|
|
14
|
-
const { updateBlock
|
|
14
|
+
const { updateBlock } = useBlockActions();
|
|
15
15
|
|
|
16
16
|
const data = blockData?.data || block.data || {};
|
|
17
17
|
|
|
18
|
-
const handleChange = (field: string, value:
|
|
18
|
+
const handleChange = (field: string, value: unknown) => {
|
|
19
19
|
updateBlock(block.id, { data: { ...data, [field]: value } });
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<
|
|
24
|
-
<div className="flex items-center justify-between mb-1">
|
|
25
|
-
<span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
|
|
26
|
-
Heading
|
|
27
|
-
</span>
|
|
28
|
-
<div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
29
|
-
<button
|
|
30
|
-
type="button"
|
|
31
|
-
onClick={() => moveBlock(block.id, "up")}
|
|
32
|
-
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
|
|
33
|
-
title="Move up"
|
|
34
|
-
>
|
|
35
|
-
<ChevronRight className="w-3 h-3 rotate-90" />
|
|
36
|
-
</button>
|
|
37
|
-
<button
|
|
38
|
-
type="button"
|
|
39
|
-
onClick={() => moveBlock(block.id, "down")}
|
|
40
|
-
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
|
|
41
|
-
title="Move down"
|
|
42
|
-
>
|
|
43
|
-
<ChevronRight className="w-3 h-3" />
|
|
44
|
-
</button>
|
|
45
|
-
<button
|
|
46
|
-
type="button"
|
|
47
|
-
onClick={() => removeBlock(block.id)}
|
|
48
|
-
className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
|
|
49
|
-
title="Remove"
|
|
50
|
-
>
|
|
51
|
-
<X className="w-3 h-3" />
|
|
52
|
-
</button>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
23
|
+
<BlockWrapper id={block.id} type="heading" label="Heading">
|
|
56
24
|
<HeadingField text={data.text || ""} onChange={handleChange} compact />
|
|
57
|
-
</
|
|
25
|
+
</BlockWrapper>
|
|
58
26
|
);
|
|
59
27
|
};
|