create-nextblock 0.2.31 → 0.2.34
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/package.json +1 -1
- package/scripts/sync-template.js +70 -52
- package/templates/nextblock-template/app/[slug]/PageClientContent.tsx +67 -67
- package/templates/nextblock-template/app/[slug]/page.tsx +4 -4
- package/templates/nextblock-template/app/cms/blocks/actions.ts +10 -10
- package/templates/nextblock-template/app/cms/blocks/components/BackgroundSelector.tsx +348 -348
- package/templates/nextblock-template/app/cms/blocks/components/BlockEditorArea.tsx +8 -8
- package/templates/nextblock-template/app/cms/blocks/components/EditableBlock.tsx +10 -10
- package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +81 -81
- package/templates/nextblock-template/app/cms/media/actions.ts +35 -35
- package/templates/nextblock-template/app/cms/media/page.tsx +120 -120
- package/templates/nextblock-template/app/cms/revisions/JsonDiffView.tsx +86 -86
- package/templates/nextblock-template/app/cms/revisions/service.ts +344 -344
- package/templates/nextblock-template/app/providers.tsx +2 -2
- package/templates/nextblock-template/components/BlockRenderer.tsx +9 -9
- package/templates/nextblock-template/components/ResponsiveNav.tsx +22 -22
- package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +12 -12
- package/templates/nextblock-template/components/blocks/renderers/ClientTextBlockRenderer.tsx +26 -26
- package/templates/nextblock-template/components/blocks/renderers/HeroBlockRenderer.tsx +41 -41
- package/templates/nextblock-template/components/blocks/renderers/ImageBlockRenderer.tsx +7 -7
- package/templates/nextblock-template/components/theme-switcher.tsx +78 -78
- package/templates/nextblock-template/eslint.config.mjs +35 -37
- package/templates/nextblock-template/lib/blocks/blockRegistry.ts +19 -19
- package/templates/nextblock-template/next-env.d.ts +6 -6
- package/templates/nextblock-template/package.json +1 -1
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
// apps/nextblock/app/cms/revisions/JsonDiffView.tsx
|
|
2
|
-
"use client";
|
|
3
|
-
|
|
4
|
-
import React, { useMemo } from 'react';
|
|
5
|
-
import { compare, type Operation } from 'fast-json-patch';
|
|
6
|
-
|
|
7
|
-
interface JsonDiffViewProps {
|
|
8
|
-
oldValue: string;
|
|
9
|
-
newValue: string;
|
|
10
|
-
leftTitle?: string;
|
|
11
|
-
rightTitle?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function getByPointer(obj: any, pointer: string): any {
|
|
15
|
-
if (!pointer || pointer === '/') return obj;
|
|
16
|
-
const parts = pointer.split('/').slice(1).map(p => p.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
17
|
-
let cur = obj;
|
|
18
|
-
for (const part of parts) {
|
|
19
|
-
if (cur == null) return undefined;
|
|
20
|
-
cur = cur[part];
|
|
21
|
-
}
|
|
22
|
-
return cur;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function safeStringify(v: any): string {
|
|
26
|
-
try {
|
|
27
|
-
return JSON.stringify(v, null, 2);
|
|
28
|
-
} catch {
|
|
29
|
-
return String(v);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default function JsonDiffView({ oldValue, newValue, leftTitle = 'Current', rightTitle = 'Selected' }: JsonDiffViewProps) {
|
|
34
|
-
const { ops, oldObj } = useMemo(() => {
|
|
35
|
-
let a: any = null, b: any = null;
|
|
36
|
-
try { a = JSON.parse(oldValue); } catch { a = oldValue; }
|
|
37
|
-
try { b = JSON.parse(newValue); } catch { b = newValue; }
|
|
38
|
-
const operations: Operation[] = compare(a, b);
|
|
39
|
-
return { ops: operations, oldObj: a };
|
|
40
|
-
}, [oldValue, newValue]);
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<div className="border rounded">
|
|
44
|
-
<div className="flex items-center justify-between px-3 py-2 border-b text-sm text-muted-foreground">
|
|
45
|
-
<div>{leftTitle}</div>
|
|
46
|
-
<div>{rightTitle}</div>
|
|
47
|
-
</div>
|
|
48
|
-
<div className="p-3 text-sm space-y-2">
|
|
49
|
-
<div className="flex items-center gap-3 text-xs text-muted-foreground">
|
|
50
|
-
<span className="inline-flex items-center gap-1"><span className="inline-block w-3 h-3 rounded bg-green-200 border border-green-300" /> Current</span>
|
|
51
|
-
<span className="inline-flex items-center gap-1"><span className="inline-block w-3 h-3 rounded bg-red-200 border border-red-300" /> Selected Version</span>
|
|
52
|
-
</div>
|
|
53
|
-
{ops.length === 0 && (
|
|
54
|
-
<div className="text-muted-foreground">No differences.</div>
|
|
55
|
-
)}
|
|
56
|
-
{ops.map((op, idx) => {
|
|
57
|
-
const oldAtPath = op.op !== 'add' ? getByPointer(oldObj, op.path) : undefined;
|
|
58
|
-
const oldStr = op.op !== 'add' ? safeStringify(oldAtPath) : '';
|
|
59
|
-
const newStr = op.op !== 'remove' ? safeStringify((op as any).value) : '';
|
|
60
|
-
return (
|
|
61
|
-
<div key={idx} className="rounded border">
|
|
62
|
-
<div className="px-2 py-1 border-b flex items-center gap-2 text-xs">
|
|
63
|
-
<span className="uppercase tracking-wide font-semibold">{op.op}</span>
|
|
64
|
-
<code className="text-muted-foreground break-all">{op.path || '/'}</code>
|
|
65
|
-
</div>
|
|
66
|
-
<div className="grid grid-cols-1 md:grid-cols-2">
|
|
67
|
-
{op.op !== 'add' && (
|
|
68
|
-
<div className="p-2 border-r md:border-r">
|
|
69
|
-
<div className="text-xs text-muted-foreground mb-1">Current</div>
|
|
70
|
-
<pre className="whitespace-pre-wrap break-words text-green-800 bg-green-50 rounded p-2 m-0">{oldStr}</pre>
|
|
71
|
-
</div>
|
|
72
|
-
)}
|
|
73
|
-
{op.op !== 'remove' && (
|
|
74
|
-
<div className="p-2">
|
|
75
|
-
<div className="text-xs text-muted-foreground mb-1">Selected Version</div>
|
|
76
|
-
<pre className="whitespace-pre-wrap break-words text-red-800 bg-red-50 rounded p-2 m-0">{newStr}</pre>
|
|
77
|
-
</div>
|
|
78
|
-
)}
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
})}
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
1
|
+
// apps/nextblock/app/cms/revisions/JsonDiffView.tsx
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
import React, { useMemo } from 'react';
|
|
5
|
+
import { compare, type Operation } from 'fast-json-patch';
|
|
6
|
+
|
|
7
|
+
interface JsonDiffViewProps {
|
|
8
|
+
oldValue: string;
|
|
9
|
+
newValue: string;
|
|
10
|
+
leftTitle?: string;
|
|
11
|
+
rightTitle?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getByPointer(obj: any, pointer: string): any {
|
|
15
|
+
if (!pointer || pointer === '/') return obj;
|
|
16
|
+
const parts = pointer.split('/').slice(1).map(p => p.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
17
|
+
let cur = obj;
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
if (cur == null) return undefined;
|
|
20
|
+
cur = cur[part];
|
|
21
|
+
}
|
|
22
|
+
return cur;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function safeStringify(v: any): string {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.stringify(v, null, 2);
|
|
28
|
+
} catch {
|
|
29
|
+
return String(v);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default function JsonDiffView({ oldValue, newValue, leftTitle = 'Current', rightTitle = 'Selected' }: JsonDiffViewProps) {
|
|
34
|
+
const { ops, oldObj } = useMemo(() => {
|
|
35
|
+
let a: any = null, b: any = null;
|
|
36
|
+
try { a = JSON.parse(oldValue); } catch { a = oldValue; }
|
|
37
|
+
try { b = JSON.parse(newValue); } catch { b = newValue; }
|
|
38
|
+
const operations: Operation[] = compare(a, b);
|
|
39
|
+
return { ops: operations, oldObj: a };
|
|
40
|
+
}, [oldValue, newValue]);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className="border rounded">
|
|
44
|
+
<div className="flex items-center justify-between px-3 py-2 border-b text-sm text-muted-foreground">
|
|
45
|
+
<div>{leftTitle}</div>
|
|
46
|
+
<div>{rightTitle}</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div className="p-3 text-sm space-y-2">
|
|
49
|
+
<div className="flex items-center gap-3 text-xs text-muted-foreground">
|
|
50
|
+
<span className="inline-flex items-center gap-1"><span className="inline-block w-3 h-3 rounded bg-green-200 border border-green-300" /> Current</span>
|
|
51
|
+
<span className="inline-flex items-center gap-1"><span className="inline-block w-3 h-3 rounded bg-red-200 border border-red-300" /> Selected Version</span>
|
|
52
|
+
</div>
|
|
53
|
+
{ops.length === 0 && (
|
|
54
|
+
<div className="text-muted-foreground">No differences.</div>
|
|
55
|
+
)}
|
|
56
|
+
{ops.map((op, idx) => {
|
|
57
|
+
const oldAtPath = op.op !== 'add' ? getByPointer(oldObj, op.path) : undefined;
|
|
58
|
+
const oldStr = op.op !== 'add' ? safeStringify(oldAtPath) : '';
|
|
59
|
+
const newStr = op.op !== 'remove' ? safeStringify((op as any).value) : '';
|
|
60
|
+
return (
|
|
61
|
+
<div key={idx} className="rounded border">
|
|
62
|
+
<div className="px-2 py-1 border-b flex items-center gap-2 text-xs">
|
|
63
|
+
<span className="uppercase tracking-wide font-semibold">{op.op}</span>
|
|
64
|
+
<code className="text-muted-foreground break-all">{op.path || '/'}</code>
|
|
65
|
+
</div>
|
|
66
|
+
<div className="grid grid-cols-1 md:grid-cols-2">
|
|
67
|
+
{op.op !== 'add' && (
|
|
68
|
+
<div className="p-2 border-r md:border-r">
|
|
69
|
+
<div className="text-xs text-muted-foreground mb-1">Current</div>
|
|
70
|
+
<pre className="whitespace-pre-wrap break-words text-green-800 bg-green-50 rounded p-2 m-0">{oldStr}</pre>
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
{op.op !== 'remove' && (
|
|
74
|
+
<div className="p-2">
|
|
75
|
+
<div className="text-xs text-muted-foreground mb-1">Selected Version</div>
|
|
76
|
+
<pre className="whitespace-pre-wrap break-words text-red-800 bg-red-50 rounded p-2 m-0">{newStr}</pre>
|
|
77
|
+
</div>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
})}
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|