@dyrected/admin 2.4.0 → 2.4.1
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/App.d.ts +1 -0
- package/dist/admin.css +2 -0
- package/dist/components/auth/auth-gate.d.ts +13 -0
- package/dist/components/error-boundary.d.ts +16 -0
- package/dist/components/forms/field-renderer.d.ts +22 -0
- package/dist/components/forms/fields/block-builder.d.ts +9 -0
- package/dist/components/forms/fields/date-picker.d.ts +8 -0
- package/dist/components/forms/fields/json-editor.d.ts +8 -0
- package/dist/components/forms/fields/media-picker.d.ts +12 -0
- package/dist/components/forms/fields/multi-select.d.ts +19 -0
- package/dist/components/forms/fields/radio-field.d.ts +8 -0
- package/dist/components/forms/fields/relationship-picker.d.ts +10 -0
- package/dist/components/forms/fields/rich-text-editor.d.ts +9 -0
- package/dist/components/forms/fields/select-field.d.ts +8 -0
- package/dist/components/forms/fields/switch-field.d.ts +6 -0
- package/dist/components/forms/fields/text-area-field.d.ts +8 -0
- package/dist/components/forms/fields/text-field.d.ts +8 -0
- package/dist/components/forms/form-engine.d.ts +14 -0
- package/dist/components/forms/form-field-renderer.d.ts +20 -0
- package/dist/components/forms/utils.d.ts +11 -0
- package/dist/components/layout/admin-shell.d.ts +5 -0
- package/dist/components/layout/branding-provider.d.ts +4 -0
- package/dist/components/live-preview/LivePreviewPane.d.ts +7 -0
- package/dist/components/media/focal-point-picker.d.ts +12 -0
- package/dist/components/media/media-card.d.ts +8 -0
- package/dist/components/media/media-grid.d.ts +8 -0
- package/dist/components/media/media-library-dialog.d.ts +11 -0
- package/dist/components/ui/aspect-ratio.d.ts +3 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/calendar.d.ts +8 -0
- package/dist/components/ui/card.d.ts +8 -0
- package/dist/components/ui/checkbox.d.ts +4 -0
- package/dist/components/ui/command.d.ts +80 -0
- package/dist/components/ui/data-table.d.ts +14 -0
- package/dist/components/ui/dialog.d.ts +19 -0
- package/dist/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/form.d.ts +23 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/page-header.d.ts +10 -0
- package/dist/components/ui/pagination.d.ts +11 -0
- package/dist/components/ui/popover.d.ts +6 -0
- package/dist/components/ui/progress.d.ts +4 -0
- package/dist/components/ui/radio-group.d.ts +5 -0
- package/dist/components/ui/render-cell.d.ts +8 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/select.d.ts +13 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/sheet.d.ts +25 -0
- package/dist/components/ui/sidebar.d.ts +65 -0
- package/dist/components/ui/skeleton.d.ts +2 -0
- package/dist/components/ui/sonner.d.ts +4 -0
- package/dist/components/ui/switch.d.ts +4 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/tabs.d.ts +7 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/ui/toggle.d.ts +12 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-preferences.d.ts +6 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.mjs +69091 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/main.d.ts +0 -0
- package/dist/pages/auth/first-user-page.d.ts +4 -0
- package/dist/pages/auth/login-page.d.ts +4 -0
- package/dist/pages/collections/edit-page.d.ts +1 -0
- package/dist/pages/collections/list-page.d.ts +5 -0
- package/dist/pages/dashboard/dashboard.d.ts +1 -0
- package/dist/pages/globals/editor-page.d.ts +1 -0
- package/dist/pages/media/media-page.d.ts +4 -0
- package/dist/pages/setup/setup-prompt.d.ts +6 -0
- package/dist/providers/dyrected-provider.d.ts +29 -0
- package/dist/providers/query-provider.d.ts +3 -0
- package/package.json +6 -3
- package/CHANGELOG.md +0 -153
- package/components.json +0 -17
- package/eslint.config.js +0 -22
- package/index.html +0 -13
- package/postcss.config.js +0 -6
- package/scripts/prefix-tailwind-precision.py +0 -98
- package/scripts/prefix-tailwind.py +0 -67
- package/src/App.css +0 -184
- package/src/App.tsx +0 -25
- package/src/assets/dyrected.svg +0 -155
- package/src/assets/hero.png +0 -0
- package/src/assets/react.svg +0 -1
- package/src/assets/vite.svg +0 -1
- package/src/components/auth/auth-gate.tsx +0 -64
- package/src/components/error-boundary.tsx +0 -45
- package/src/components/forms/field-renderer.tsx +0 -111
- package/src/components/forms/fields/block-builder.tsx +0 -213
- package/src/components/forms/fields/date-picker.tsx +0 -60
- package/src/components/forms/fields/json-editor.tsx +0 -62
- package/src/components/forms/fields/media-picker.tsx +0 -286
- package/src/components/forms/fields/multi-select.tsx +0 -145
- package/src/components/forms/fields/radio-field.tsx +0 -51
- package/src/components/forms/fields/relationship-picker.tsx +0 -143
- package/src/components/forms/fields/rich-text-editor.tsx +0 -224
- package/src/components/forms/fields/select-field.tsx +0 -35
- package/src/components/forms/fields/switch-field.tsx +0 -16
- package/src/components/forms/fields/text-area-field.tsx +0 -15
- package/src/components/forms/fields/text-field.tsx +0 -24
- package/src/components/forms/form-engine.tsx +0 -87
- package/src/components/forms/form-field-renderer.tsx +0 -269
- package/src/components/forms/utils.ts +0 -97
- package/src/components/layout/admin-shell.tsx +0 -479
- package/src/components/layout/branding-provider.tsx +0 -112
- package/src/components/live-preview/LivePreviewPane.tsx +0 -128
- package/src/components/media/focal-point-picker.tsx +0 -66
- package/src/components/media/media-card.tsx +0 -44
- package/src/components/media/media-grid.tsx +0 -32
- package/src/components/media/media-library-dialog.tsx +0 -465
- package/src/components/ui/aspect-ratio.tsx +0 -7
- package/src/components/ui/badge.tsx +0 -36
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/calendar.tsx +0 -214
- package/src/components/ui/card.tsx +0 -79
- package/src/components/ui/checkbox.tsx +0 -28
- package/src/components/ui/command.tsx +0 -151
- package/src/components/ui/data-table.tsx +0 -219
- package/src/components/ui/dialog.tsx +0 -122
- package/src/components/ui/dropdown-menu.tsx +0 -200
- package/src/components/ui/form.tsx +0 -178
- package/src/components/ui/input.tsx +0 -24
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/page-header.tsx +0 -30
- package/src/components/ui/pagination.tsx +0 -57
- package/src/components/ui/popover.tsx +0 -29
- package/src/components/ui/progress.tsx +0 -26
- package/src/components/ui/radio-group.tsx +0 -42
- package/src/components/ui/render-cell.tsx +0 -110
- package/src/components/ui/scroll-area.tsx +0 -46
- package/src/components/ui/select.tsx +0 -160
- package/src/components/ui/separator.tsx +0 -29
- package/src/components/ui/sheet.tsx +0 -140
- package/src/components/ui/sidebar.tsx +0 -771
- package/src/components/ui/skeleton.tsx +0 -15
- package/src/components/ui/sonner.tsx +0 -27
- package/src/components/ui/switch.tsx +0 -27
- package/src/components/ui/table.tsx +0 -117
- package/src/components/ui/tabs.tsx +0 -53
- package/src/components/ui/textarea.tsx +0 -22
- package/src/components/ui/toggle.tsx +0 -43
- package/src/components/ui/tooltip.tsx +0 -28
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/hooks/use-preferences.ts +0 -56
- package/src/index.css +0 -111
- package/src/index.tsx +0 -198
- package/src/lib/utils.ts +0 -36
- package/src/main.tsx +0 -10
- package/src/pages/auth/first-user-page.tsx +0 -115
- package/src/pages/auth/login-page.tsx +0 -91
- package/src/pages/collections/edit-page.tsx +0 -280
- package/src/pages/collections/list-page.tsx +0 -343
- package/src/pages/dashboard/dashboard.tsx +0 -150
- package/src/pages/globals/editor-page.tsx +0 -122
- package/src/pages/media/media-page.tsx +0 -564
- package/src/pages/setup/setup-prompt.tsx +0 -181
- package/src/providers/dyrected-provider.tsx +0 -122
- package/src/providers/query-provider.tsx +0 -19
- package/src/types/jexl.d.ts +0 -11
- package/tailwind.config.ts +0 -103
- package/tsconfig.app.json +0 -28
- package/tsconfig.json +0 -12
- package/tsconfig.node.json +0 -25
- package/vite.config.ts +0 -39
- /package/{public → dist}/favicon.svg +0 -0
- /package/{public → dist}/icons.svg +0 -0
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Button } from '../ui/button';
|
|
3
|
-
import { ExternalLink, Smartphone, Monitor, RotateCcw } from 'lucide-react';
|
|
4
|
-
|
|
5
|
-
interface LivePreviewPaneProps {
|
|
6
|
-
previewUrl: string;
|
|
7
|
-
data: any;
|
|
8
|
-
mode?: 'postMessage' | 'token';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function LivePreviewPane({ previewUrl, data, mode = 'postMessage' }: LivePreviewPaneProps) {
|
|
12
|
-
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
13
|
-
const [isReady, setIsReady] = useState(false);
|
|
14
|
-
const [viewMode, setViewMode] = useState<'desktop' | 'mobile'>('desktop');
|
|
15
|
-
const [zoom, setZoom] = useState(0.50); // 85% zoom by default for desktop
|
|
16
|
-
|
|
17
|
-
// Handle postMessage communication
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
if (mode !== 'postMessage') return;
|
|
20
|
-
|
|
21
|
-
const handleMessage = (event: MessageEvent) => {
|
|
22
|
-
if (event.data?.type === 'dyrected-live-preview-ready') {
|
|
23
|
-
setIsReady(true);
|
|
24
|
-
// Send initial data once ready
|
|
25
|
-
iframeRef.current?.contentWindow?.postMessage(
|
|
26
|
-
{ type: 'dyrected-live-preview', data },
|
|
27
|
-
'*'
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
window.addEventListener('message', handleMessage);
|
|
33
|
-
return () => window.removeEventListener('message', handleMessage);
|
|
34
|
-
}, [mode, data]);
|
|
35
|
-
|
|
36
|
-
// Sync data whenever it changes
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (mode === 'postMessage' && isReady) {
|
|
39
|
-
iframeRef.current?.contentWindow?.postMessage(
|
|
40
|
-
{ type: 'dyrected-live-preview', data },
|
|
41
|
-
'*'
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
}, [data, isReady, mode]);
|
|
45
|
-
|
|
46
|
-
const reload = () => {
|
|
47
|
-
if (iframeRef.current) {
|
|
48
|
-
iframeRef.current.src = previewUrl;
|
|
49
|
-
setIsReady(false);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<div className="dy-flex dy-flex-col dy-h-full dy-bg-muted/20 dy-border-l dy-border-border/60">
|
|
55
|
-
<div className="dy-flex dy-items-center dy-justify-between dy-px-4 dy-py-2 dy-bg-white dy-border-b dy-border-border/40">
|
|
56
|
-
<div className="dy-flex dy-items-center dy-gap-2">
|
|
57
|
-
<Button
|
|
58
|
-
variant="ghost"
|
|
59
|
-
size="icon"
|
|
60
|
-
className={`h-8 w-8 ${viewMode === 'desktop' ? 'bg-muted' : ''}`}
|
|
61
|
-
onClick={() => setViewMode('desktop')}
|
|
62
|
-
>
|
|
63
|
-
<Monitor className="dy-h-4 dy-w-4" />
|
|
64
|
-
</Button>
|
|
65
|
-
<Button
|
|
66
|
-
variant="ghost"
|
|
67
|
-
size="icon"
|
|
68
|
-
className={`h-8 w-8 ${viewMode === 'mobile' ? 'bg-muted' : ''}`}
|
|
69
|
-
onClick={() => setViewMode('mobile')}
|
|
70
|
-
>
|
|
71
|
-
<Smartphone className="dy-h-4 dy-w-4" />
|
|
72
|
-
</Button>
|
|
73
|
-
|
|
74
|
-
{viewMode === 'desktop' && (
|
|
75
|
-
<div className="dy-flex dy-items-center dy-gap-1 dy-ml-2 dy-pl-2 dy-border-l dy-border-border/40">
|
|
76
|
-
<span className="dy-text-[10px] dy-font-bold dy-text-muted-foreground/50 dy-uppercase dy-tracking-wider dy-mr-1">Zoom</span>
|
|
77
|
-
{[0.50, 0.75, 1.0].map((z) => (
|
|
78
|
-
<Button
|
|
79
|
-
key={z}
|
|
80
|
-
variant="ghost"
|
|
81
|
-
size="sm"
|
|
82
|
-
className={`h-7 px-2 text-[10px] font-medium ${zoom === z ? 'bg-primary/10 text-primary' : 'text-muted-foreground/60'}`}
|
|
83
|
-
onClick={() => setZoom(z)}
|
|
84
|
-
>
|
|
85
|
-
{Math.round(z * 100)}%
|
|
86
|
-
</Button>
|
|
87
|
-
))}
|
|
88
|
-
</div>
|
|
89
|
-
)}
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<div className="dy-flex dy-items-center dy-gap-2">
|
|
93
|
-
<Button variant="ghost" size="icon" className="dy-h-8 dy-w-8" onClick={reload}>
|
|
94
|
-
<RotateCcw className="dy-h-3.5 dy-w-3.5" />
|
|
95
|
-
</Button>
|
|
96
|
-
<Button variant="ghost" size="icon" className="dy-h-8 dy-w-8" asChild>
|
|
97
|
-
<a href={previewUrl} target="_blank" rel="noreferrer">
|
|
98
|
-
<ExternalLink className="dy-h-3.5 dy-w-3.5" />
|
|
99
|
-
</a>
|
|
100
|
-
</Button>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
<div className="dy-flex-1 dy-flex dy-items-center dy-justify-center dy-p-0 dy-overflow-hidden dy-bg-muted/5">
|
|
105
|
-
<div
|
|
106
|
-
className={`bg-white shadow-[0_20px_50px_rgba(0,0,0,0.1)] transition-all duration-500 overflow-hidden border border-border/40 ${viewMode === 'mobile' ? 'w-[375px] h-[667px]' : 'w-full h-full'
|
|
107
|
-
}`}
|
|
108
|
-
>
|
|
109
|
-
<iframe
|
|
110
|
-
ref={iframeRef}
|
|
111
|
-
src={previewUrl}
|
|
112
|
-
className="dy-border-none dy-transition-transform dy-duration-300"
|
|
113
|
-
style={viewMode === 'desktop' ? {
|
|
114
|
-
width: `${100 / zoom}%`,
|
|
115
|
-
height: `${100 / zoom}%`,
|
|
116
|
-
transform: `scale(${zoom})`,
|
|
117
|
-
transformOrigin: 'top left',
|
|
118
|
-
} : {
|
|
119
|
-
width: '100%',
|
|
120
|
-
height: '100%',
|
|
121
|
-
}}
|
|
122
|
-
title="Live Preview"
|
|
123
|
-
/>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
);
|
|
128
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../../lib/utils"
|
|
3
|
-
|
|
4
|
-
interface FocalPoint {
|
|
5
|
-
x: number;
|
|
6
|
-
y: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
interface FocalPointPickerProps {
|
|
10
|
-
url: string;
|
|
11
|
-
value?: FocalPoint;
|
|
12
|
-
onChange: (value: FocalPoint) => void;
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function FocalPointPicker({ url, value, onChange, className }: FocalPointPickerProps) {
|
|
17
|
-
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
18
|
-
|
|
19
|
-
const focalPoint = value || { x: 50, y: 50 };
|
|
20
|
-
|
|
21
|
-
const handleClick = (e: React.MouseEvent) => {
|
|
22
|
-
if (!containerRef.current) return;
|
|
23
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
24
|
-
const x = Math.round(((e.clientX - rect.left) / rect.width) * 100);
|
|
25
|
-
const y = Math.round(((e.clientY - rect.top) / rect.height) * 100);
|
|
26
|
-
|
|
27
|
-
// Clamp values between 0 and 100
|
|
28
|
-
const clampedX = Math.max(0, Math.min(100, x));
|
|
29
|
-
const clampedY = Math.max(0, Math.min(100, y));
|
|
30
|
-
|
|
31
|
-
onChange({ x: clampedX, y: clampedY });
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="dy-space-y-2">
|
|
36
|
-
<div
|
|
37
|
-
ref={containerRef}
|
|
38
|
-
className={cn("dy-relative dy-cursor-crosshair dy-overflow-hidden dy-rounded-xl dy-border dy-border-border/40 dy-bg-muted/20 dy-group", className)}
|
|
39
|
-
onClick={handleClick}
|
|
40
|
-
>
|
|
41
|
-
<img
|
|
42
|
-
src={url}
|
|
43
|
-
alt="Focal point picker"
|
|
44
|
-
className="dy-w-full dy-h-auto dy-pointer-events-none dy-select-none dy-max-h-[400px] dy-object-contain dy-bg-checkered"
|
|
45
|
-
/>
|
|
46
|
-
|
|
47
|
-
{/* Focal point indicator */}
|
|
48
|
-
<div
|
|
49
|
-
className="dy-absolute dy-w-8 dy-h-8 dy--ml-4 dy--mt-4 dy-border-2 dy-border-white dy-rounded-full dy-shadow-2xl dy-flex dy-items-center dy-justify-center dy-pointer-events-none dy-transition-all dy-duration-200 dy-ease-out"
|
|
50
|
-
style={{ left: `${focalPoint.x}%`, top: `${focalPoint.y}%` }}
|
|
51
|
-
>
|
|
52
|
-
<div className="dy-w-1.5 dy-h-1.5 dy-bg-white dy-rounded-full dy-shadow-sm" />
|
|
53
|
-
<div className="dy-absolute dy-w-full dy-h-px dy-bg-white/40" />
|
|
54
|
-
<div className="dy-absolute dy-h-full dy-w-px dy-bg-white/40" />
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<div className="dy-absolute dy-bottom-3 dy-left-3 dy-bg-black/60 dy-backdrop-blur-md dy-px-2.5 dy-py-1 dy-rounded-lg dy-text-[10px] dy-text-white dy-font-bold dy-tracking-widest dy-border dy-border-white/10 dy-opacity-0 dy-group-hover:dy-opacity-100 dy-transition-opacity">
|
|
58
|
-
X: {focalPoint.x}% / Y: {focalPoint.y}%
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
<p className="dy-text-[10px] dy-text-muted-foreground dy-font-medium dy-px-1">
|
|
62
|
-
Click on the image to set the focal point for smart cropping.
|
|
63
|
-
</p>
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Link } from "react-router-dom"
|
|
2
|
-
import { Pencil, Trash2 } from "lucide-react"
|
|
3
|
-
import { Button } from "../ui/button"
|
|
4
|
-
import { getMediaUrl } from "../../lib/utils"
|
|
5
|
-
|
|
6
|
-
interface MediaCardProps {
|
|
7
|
-
item: any
|
|
8
|
-
baseUrl: string
|
|
9
|
-
onDelete: (id: string) => void
|
|
10
|
-
editPath: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function MediaCard({ item, baseUrl, onDelete, editPath }: MediaCardProps) {
|
|
14
|
-
const url = getMediaUrl(item, baseUrl)
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<div className="dy-group dy-relative dy-aspect-square dy-rounded-2xl dy-overflow-hidden dy-bg-white dy-border dy-border-border/40 dy-shadow-sm hover:dy-shadow-xl hover:dy-border-primary/20 dy-transition-all dy-duration-300">
|
|
18
|
-
<img
|
|
19
|
-
src={url}
|
|
20
|
-
alt={item.filename}
|
|
21
|
-
className="dy-w-full dy-h-full dy-object-cover dy-transition-transform dy-duration-500 dy-group-hover:dy-scale-110"
|
|
22
|
-
/>
|
|
23
|
-
<div className="dy-absolute dy-inset-0 dy-bg-black/40 dy-opacity-0 dy-group-hover:dy-opacity-100 dy-transition-all dy-duration-300 dy-flex dy-items-center dy-justify-center dy-gap-3 dy-backdrop-blur-[2px]">
|
|
24
|
-
<Link to={editPath}>
|
|
25
|
-
<Button size="icon" variant="secondary" className="dy-h-9 dy-w-9 dy-rounded-full dy-bg-white/90 hover:dy-bg-white dy-text-foreground dy-shadow-lg dy-transform dy-translate-y-2 dy-group-hover:dy-translate-y-0 dy-transition-transform dy-duration-300">
|
|
26
|
-
<Pencil className="dy-h-4 dy-w-4" />
|
|
27
|
-
</Button>
|
|
28
|
-
</Link>
|
|
29
|
-
<Button
|
|
30
|
-
size="icon"
|
|
31
|
-
variant="destructive"
|
|
32
|
-
className="dy-h-9 dy-w-9 dy-rounded-full dy-bg-destructive/90 hover:dy-bg-destructive dy-shadow-lg dy-transform dy-translate-y-2 dy-group-hover:dy-translate-y-0 dy-transition-transform dy-duration-300 dy-delay-75"
|
|
33
|
-
onClick={() => onDelete(item.id)}
|
|
34
|
-
>
|
|
35
|
-
<Trash2 className="dy-h-4 dy-w-4" />
|
|
36
|
-
</Button>
|
|
37
|
-
</div>
|
|
38
|
-
<div className="dy-absolute dy-bottom-0 dy-left-0 dy-right-0 dy-p-3 dy-bg-gradient-to-t dy-from-black/80 dy-via-black/40 dy-to-transparent dy-opacity-0 dy-group-hover:dy-opacity-100 dy-transition-opacity dy-duration-300">
|
|
39
|
-
<p className="dy-text-[10px] dy-text-white dy-truncate dy-font-medium">{item.filename}</p>
|
|
40
|
-
<p className="dy-text-[8px] dy-text-white/60 dy-uppercase dy-tracking-wider dy-mt-0.5">{item.mimeType}</p>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
)
|
|
44
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { MediaCard } from "./media-card"
|
|
2
|
-
|
|
3
|
-
interface MediaGridProps {
|
|
4
|
-
items: any[]
|
|
5
|
-
baseUrl: string
|
|
6
|
-
onDelete: (id: string) => void
|
|
7
|
-
slug: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function MediaGrid({ items, baseUrl, onDelete, slug }: MediaGridProps) {
|
|
11
|
-
if (!items || items.length === 0) {
|
|
12
|
-
return (
|
|
13
|
-
<div className="dy-flex dy-flex-col dy-items-center dy-justify-center dy-h-[300px] dy-border-2 dy-border-dashed dy-border-border/60 dy-rounded-3xl dy-bg-muted/5">
|
|
14
|
-
<p className="dy-text-sm dy-text-muted-foreground dy-font-medium">No media assets found</p>
|
|
15
|
-
</div>
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div className="dy-grid dy-grid-cols-2 sm:dy-grid-cols-3 md:dy-grid-cols-4 lg:dy-grid-cols-6 dy-gap-6">
|
|
21
|
-
{items.map((item) => (
|
|
22
|
-
<MediaCard
|
|
23
|
-
key={item.id}
|
|
24
|
-
item={item}
|
|
25
|
-
baseUrl={baseUrl}
|
|
26
|
-
onDelete={onDelete}
|
|
27
|
-
editPath={`/collections/${slug}/edit/${item.id}`}
|
|
28
|
-
/>
|
|
29
|
-
))}
|
|
30
|
-
</div>
|
|
31
|
-
)
|
|
32
|
-
}
|