betterstart-cli 0.0.17 → 0.0.19
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/assets/adapters/next/plugins/blog/schemas/menus.json +1 -0
- package/dist/assets/adapters/next/plugins/blog/schemas/posts.json +1 -0
- package/dist/assets/adapters/next/plugins/portfolio/plugin.ts +17 -0
- package/dist/assets/adapters/next/plugins/portfolio/schemas/portfolio.json +128 -0
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/dev-mode-types.ts +2 -2
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/snippets-tab.tsx +1 -0
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode-integrate.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-delete-dialog.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-delete-drawer.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-grid-item.tsx +17 -7
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-preview.tsx +1 -0
- package/dist/assets/adapters/next/templates/init/data/navigation.ts +2 -1
- package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +3 -3
- package/dist/assets/adapters/next/templates/init/hooks/use-media.ts +2 -1
- package/dist/assets/adapters/next/templates/init/pages/profile/profile-form.tsx +3 -3
- package/dist/assets/shared-assets/react-admin/custom/content-editor/media-gallery-block.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/content-editor/table-add-controls.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/gallery-field.tsx +219 -40
- package/dist/assets/shared-assets/react-admin/custom/media-field-empty-state.tsx +99 -0
- package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +181 -0
- package/dist/assets/shared-assets/react-admin/custom/sortable-gallery-item.tsx +38 -38
- package/dist/assets/shared-assets/react-admin/schema.json +64 -2
- package/dist/assets/shared-assets/react-admin/ui/pagination.tsx +1 -1
- package/dist/cli.js +474 -143
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/dist/assets/shared-assets/react-admin/custom/gallery-thumbnail.tsx +0 -39
- package/dist/assets/shared-assets/react-admin/custom/media-gallery-field.tsx +0 -182
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Button } from '@admin/components/ui/button'
|
|
2
|
+
import { Card, CardContent, CardFooter } from '@admin/components/ui/card'
|
|
3
|
+
import { Skeleton } from '@admin/components/ui/skeleton'
|
|
2
4
|
import { useSortable } from '@dnd-kit/sortable'
|
|
3
5
|
import { CSS } from '@dnd-kit/utilities'
|
|
4
|
-
import { GripVertical
|
|
6
|
+
import { GripVertical } from 'lucide-react'
|
|
5
7
|
import type * as React from 'react'
|
|
6
|
-
import { GalleryThumbnail } from './gallery-thumbnail'
|
|
7
8
|
|
|
8
9
|
export function SortableGalleryItem({
|
|
9
10
|
id,
|
|
10
|
-
media,
|
|
11
11
|
disabled,
|
|
12
|
-
|
|
12
|
+
children
|
|
13
13
|
}: {
|
|
14
14
|
id: string
|
|
15
|
-
media: AdminMedia | undefined
|
|
16
15
|
disabled?: boolean
|
|
17
|
-
|
|
16
|
+
children: React.ReactNode
|
|
18
17
|
}) {
|
|
19
18
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
20
19
|
id,
|
|
21
20
|
disabled
|
|
22
21
|
})
|
|
23
22
|
|
|
24
|
-
const style: React.CSSProperties = {
|
|
25
|
-
transform: CSS.Transform.toString(transform),
|
|
26
|
-
transition,
|
|
27
|
-
opacity: isDragging ? 0.5 : 1
|
|
28
|
-
}
|
|
29
|
-
|
|
30
23
|
return (
|
|
31
24
|
<div
|
|
32
25
|
ref={setNodeRef}
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
data-gallery-dragging={isDragging ? 'true' : undefined}
|
|
27
|
+
style={{
|
|
28
|
+
transform: CSS.Translate.toString(transform),
|
|
29
|
+
transition: isDragging ? undefined : transition,
|
|
30
|
+
zIndex: isDragging ? 30 : undefined,
|
|
31
|
+
willChange: isDragging ? 'transform' : undefined
|
|
32
|
+
}}
|
|
33
|
+
className="group relative min-w-0 select-none [&[data-gallery-dragging=true]_[data-gallery-drag-handle]]:pointer-events-none [&[data-gallery-dragging=true]_[data-gallery-drag-handle]]:opacity-0 [&[data-gallery-dragging=true]_[data-media-field-action]]:pointer-events-none [&[data-gallery-dragging=true]_[data-media-field-action]]:opacity-0"
|
|
35
34
|
>
|
|
35
|
+
<div
|
|
36
|
+
aria-hidden="true"
|
|
37
|
+
className="pointer-events-none absolute inset-0 opacity-0 transition-opacity group-data-[gallery-dragging=true]:opacity-100"
|
|
38
|
+
>
|
|
39
|
+
<Card className="h-full">
|
|
40
|
+
<CardContent className="p-2 flex flex-col">
|
|
41
|
+
<div className="flex size-full bg-background border border-border rounded-sm aspect-square overflow-hidden">
|
|
42
|
+
<Skeleton className="size-full" />
|
|
43
|
+
</div>
|
|
44
|
+
</CardContent>
|
|
45
|
+
<CardFooter>
|
|
46
|
+
<Skeleton className="h-4 w-3/4" />
|
|
47
|
+
</CardFooter>
|
|
48
|
+
</Card>
|
|
49
|
+
</div>
|
|
36
50
|
{!disabled && (
|
|
37
|
-
<
|
|
51
|
+
<Button
|
|
38
52
|
{...attributes}
|
|
39
53
|
{...listeners}
|
|
40
|
-
|
|
54
|
+
data-gallery-drag-handle
|
|
55
|
+
variant="outline"
|
|
56
|
+
size="icon-sm"
|
|
57
|
+
className="absolute right-1 top-1 z-10 cursor-grab touch-none opacity-0 transition-[opacity,transform] group-hover:opacity-100 active:scale-[0.96] active:cursor-grabbing border-primary/10"
|
|
41
58
|
>
|
|
42
59
|
<GripVertical className="size-3.5 text-foreground" />
|
|
43
|
-
</
|
|
44
|
-
)}
|
|
45
|
-
|
|
46
|
-
{!disabled && (
|
|
47
|
-
<button
|
|
48
|
-
type="button"
|
|
49
|
-
onClick={(e) => {
|
|
50
|
-
e.stopPropagation()
|
|
51
|
-
onRemove()
|
|
52
|
-
}}
|
|
53
|
-
className="absolute right-1 top-1 z-10 flex size-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground opacity-0 transition-opacity group-hover:opacity-100"
|
|
54
|
-
>
|
|
55
|
-
<X className="size-3" />
|
|
56
|
-
</button>
|
|
60
|
+
</Button>
|
|
57
61
|
)}
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<div className="flex size-full items-center justify-center">
|
|
63
|
-
<div className="size-4 animate-pulse rounded-full bg-muted-foreground/20" />
|
|
64
|
-
</div>
|
|
65
|
-
)}
|
|
63
|
+
<div className="relative transition-opacity group-data-[gallery-dragging=true]:opacity-0">
|
|
64
|
+
{children}
|
|
65
|
+
</div>
|
|
66
66
|
</div>
|
|
67
67
|
)
|
|
68
68
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"title": "BetterStart Schema Definition",
|
|
5
5
|
"description": "JSON Schema for validating custom schema files (courses.json, testimonials.json, instructors.json, events.json, etc.)",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["name", "label"],
|
|
7
|
+
"required": ["type", "name", "label"],
|
|
8
8
|
"additionalProperties": false,
|
|
9
9
|
"properties": {
|
|
10
10
|
"$schema": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"type": {
|
|
32
32
|
"type": "string",
|
|
33
|
-
"description": "Schema type: 'entity' for CRUD list
|
|
33
|
+
"description": "Schema type: 'entity' for CRUD list, 'single' for singleton record (site settings, about page), or 'form' for public submission forms",
|
|
34
34
|
"enum": ["entity", "single", "form"]
|
|
35
35
|
},
|
|
36
36
|
"fields": {
|
|
@@ -157,6 +157,9 @@
|
|
|
157
157
|
{
|
|
158
158
|
"$ref": "#/$defs/stringField"
|
|
159
159
|
},
|
|
160
|
+
{
|
|
161
|
+
"$ref": "#/$defs/emailField"
|
|
162
|
+
},
|
|
160
163
|
{
|
|
161
164
|
"$ref": "#/$defs/textField"
|
|
162
165
|
},
|
|
@@ -423,6 +426,61 @@
|
|
|
423
426
|
}
|
|
424
427
|
}
|
|
425
428
|
},
|
|
429
|
+
"emailField": {
|
|
430
|
+
"type": "object",
|
|
431
|
+
"description": "Email input field",
|
|
432
|
+
"required": ["name", "type"],
|
|
433
|
+
"additionalProperties": false,
|
|
434
|
+
"properties": {
|
|
435
|
+
"name": {
|
|
436
|
+
"type": "string"
|
|
437
|
+
},
|
|
438
|
+
"type": {
|
|
439
|
+
"const": "email"
|
|
440
|
+
},
|
|
441
|
+
"label": {
|
|
442
|
+
"type": "string"
|
|
443
|
+
},
|
|
444
|
+
"required": {
|
|
445
|
+
"type": "boolean"
|
|
446
|
+
},
|
|
447
|
+
"length": {
|
|
448
|
+
"type": "integer",
|
|
449
|
+
"description": "Maximum character length",
|
|
450
|
+
"minimum": 1,
|
|
451
|
+
"maximum": 65535
|
|
452
|
+
},
|
|
453
|
+
"hint": {
|
|
454
|
+
"type": "string"
|
|
455
|
+
},
|
|
456
|
+
"placeholder": {
|
|
457
|
+
"type": "string",
|
|
458
|
+
"description": "Placeholder text displayed in the email input"
|
|
459
|
+
},
|
|
460
|
+
"default": {
|
|
461
|
+
"type": "string"
|
|
462
|
+
},
|
|
463
|
+
"defaultValueFrom": {
|
|
464
|
+
"$ref": "#/$defs/defaultValueFrom"
|
|
465
|
+
},
|
|
466
|
+
"hasIcon": {
|
|
467
|
+
"type": "boolean",
|
|
468
|
+
"description": "Whether this field has an associated icon picker"
|
|
469
|
+
},
|
|
470
|
+
"hidden": {
|
|
471
|
+
"type": "boolean",
|
|
472
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
473
|
+
},
|
|
474
|
+
"showWhen": {
|
|
475
|
+
"$ref": "#/$defs/showWhenCondition"
|
|
476
|
+
},
|
|
477
|
+
"height": {
|
|
478
|
+
"enum": ["auto", "fill"],
|
|
479
|
+
"default": "auto",
|
|
480
|
+
"description": "Generated field height behavior: auto size or fill remaining flexible space."
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
},
|
|
426
484
|
"markdownField": {
|
|
427
485
|
"type": "object",
|
|
428
486
|
"description": "Rich text editor with markdown support",
|
|
@@ -1221,6 +1279,10 @@
|
|
|
1221
1279
|
"type": "string",
|
|
1222
1280
|
"description": "Tab display label"
|
|
1223
1281
|
},
|
|
1282
|
+
"icon": {
|
|
1283
|
+
"type": "string",
|
|
1284
|
+
"description": "Lucide icon name rendered before the tab label"
|
|
1285
|
+
},
|
|
1224
1286
|
"fields": {
|
|
1225
1287
|
"type": "array",
|
|
1226
1288
|
"description": "Fields within this tab",
|