@gallop.software/studio 0.1.0 → 0.1.2
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/StudioUI-5I3O5VF7.js +1382 -0
- package/dist/StudioUI-5I3O5VF7.js.map +1 -0
- package/dist/StudioUI-BBXJCQ3O.mjs +1382 -0
- package/dist/StudioUI-BBXJCQ3O.mjs.map +1 -0
- package/dist/index.d.mts +2 -10
- package/dist/index.d.ts +2 -10
- package/dist/index.js +102 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +102 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/dist/StudioUI-4ST2P6R7.mjs +0 -991
- package/dist/StudioUI-4ST2P6R7.mjs.map +0 -1
- package/dist/StudioUI-BH7PWCKH.js +0 -991
- package/dist/StudioUI-BH7PWCKH.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/StudioUI.tsx","../src/components/StudioContext.tsx","../src/components/StudioToolbar.tsx","../src/components/StudioBreadcrumb.tsx","../src/components/StudioFileGrid.tsx","../src/components/StudioFileList.tsx","../src/components/StudioPreview.tsx","../src/components/StudioSettings.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useCallback, useState } from 'react'\nimport { StudioContext } from './StudioContext'\nimport { StudioToolbar } from './StudioToolbar'\nimport { StudioBreadcrumb } from './StudioBreadcrumb'\nimport { StudioFileGrid } from './StudioFileGrid'\nimport { StudioFileList } from './StudioFileList'\nimport { StudioPreview } from './StudioPreview'\nimport { StudioSettings } from './StudioSettings'\nimport type { FileItem, StudioMeta } from '../types'\n\ninterface StudioUIProps {\n onClose: () => void\n}\n\n/**\n * Main Studio UI - contains all panels and manages internal state\n * Rendered inside the modal via lazy loading\n */\nexport function StudioUI({ onClose }: StudioUIProps) {\n // Internal state management (moved from useStudioState)\n const [currentPath, setCurrentPathInternal] = useState('public')\n const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set())\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid')\n const [meta, setMeta] = useState<StudioMeta | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n const navigateUp = useCallback(() => {\n if (currentPath === 'public') return\n const parts = currentPath.split('/')\n parts.pop()\n setCurrentPathInternal(parts.join('/') || 'public')\n setSelectedItems(new Set())\n }, [currentPath])\n\n const setCurrentPath = useCallback((path: string) => {\n setCurrentPathInternal(path)\n setSelectedItems(new Set())\n }, [])\n\n const toggleSelection = useCallback((path: string) => {\n setSelectedItems((prev) => {\n const next = new Set(prev)\n if (next.has(path)) {\n next.delete(path)\n } else {\n next.add(path)\n }\n return next\n })\n }, [])\n\n const selectAll = useCallback((items: FileItem[]) => {\n setSelectedItems(new Set(items.map((item) => item.path)))\n }, [])\n\n const clearSelection = useCallback(() => {\n setSelectedItems(new Set())\n }, [])\n\n // Handle escape key\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose()\n }\n },\n [onClose]\n )\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyDown)\n document.body.style.overflow = 'hidden'\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n document.body.style.overflow = ''\n }\n }, [handleKeyDown])\n\n // Context value - isOpen is always true when this component is mounted\n const contextValue = {\n isOpen: true,\n openStudio: () => {},\n closeStudio: onClose,\n toggleStudio: onClose,\n currentPath,\n setCurrentPath,\n navigateUp,\n selectedItems,\n toggleSelection,\n selectAll,\n clearSelection,\n viewMode,\n setViewMode,\n meta,\n setMeta,\n isLoading,\n setIsLoading,\n }\n\n return (\n <StudioContext.Provider value={contextValue}>\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-gray-200\">\n <h1 className=\"text-xl font-semibold text-gray-900\">Studio</h1>\n <div className=\"flex items-center gap-2\">\n <StudioSettings />\n <button\n onClick={onClose}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\n aria-label=\"Close Studio\"\n >\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Toolbar */}\n <StudioToolbar />\n\n {/* Breadcrumb */}\n <StudioBreadcrumb />\n\n {/* Content */}\n <div className=\"flex-1 flex overflow-hidden\">\n {/* File browser */}\n <div className=\"flex-1 overflow-auto p-4\">\n {viewMode === 'grid' ? <StudioFileGrid /> : <StudioFileList />}\n </div>\n\n {/* Preview panel */}\n <StudioPreview />\n </div>\n </div>\n </StudioContext.Provider>\n )\n}\n\nfunction CloseIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"w-5 h-5 text-gray-500\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\n// Default export for lazy loading\nexport default StudioUI\n","'use client'\n\nimport { createContext, useContext } from 'react'\nimport type { FileItem, StudioMeta } from '../types'\n\n/**\n * Studio state interface\n * State is managed by StudioUI and provided to all child components\n */\nexport interface StudioState {\n isOpen: boolean\n openStudio: () => void\n closeStudio: () => void\n toggleStudio: () => void\n\n // Navigation\n currentPath: string\n setCurrentPath: (path: string) => void\n navigateUp: () => void\n\n // Selection\n selectedItems: Set<string>\n toggleSelection: (path: string) => void\n selectAll: (items: FileItem[]) => void\n clearSelection: () => void\n\n // View\n viewMode: 'grid' | 'list'\n setViewMode: (mode: 'grid' | 'list') => void\n\n // Meta\n meta: StudioMeta | null\n setMeta: (meta: StudioMeta) => void\n\n // Loading\n isLoading: boolean\n setIsLoading: (loading: boolean) => void\n}\n\nconst defaultState: StudioState = {\n isOpen: false,\n openStudio: () => {},\n closeStudio: () => {},\n toggleStudio: () => {},\n currentPath: 'public',\n setCurrentPath: () => {},\n navigateUp: () => {},\n selectedItems: new Set(),\n toggleSelection: () => {},\n selectAll: () => {},\n clearSelection: () => {},\n viewMode: 'grid',\n setViewMode: () => {},\n meta: null,\n setMeta: () => {},\n isLoading: false,\n setIsLoading: () => {},\n}\n\nexport const StudioContext = createContext<StudioState>(defaultState)\n\n/**\n * Hook to access Studio state from child components\n */\nexport function useStudio() {\n return useContext(StudioContext)\n}\n","'use client'\n\nimport { useCallback } from 'react'\nimport { useStudio } from './StudioContext'\n\n/**\n * Toolbar with action buttons\n */\nexport function StudioToolbar() {\n const { selectedItems, viewMode, setViewMode, clearSelection } = useStudio()\n\n const handleUpload = useCallback(() => {\n // TODO: Implement upload\n console.log('Upload clicked')\n }, [])\n\n const handleReprocess = useCallback(() => {\n // TODO: Implement reprocess\n console.log('Reprocess clicked', selectedItems)\n }, [selectedItems])\n\n const handleDelete = useCallback(() => {\n // TODO: Implement delete\n console.log('Delete clicked', selectedItems)\n }, [selectedItems])\n\n const handleSyncCdn = useCallback(() => {\n // TODO: Implement CDN sync\n console.log('Sync CDN clicked', selectedItems)\n }, [selectedItems])\n\n const handleScan = useCallback(() => {\n // TODO: Implement scan\n console.log('Scan clicked')\n }, [])\n\n const hasSelection = selectedItems.size > 0\n\n return (\n <div className=\"flex items-center justify-between px-6 py-3 bg-gray-50 border-b border-gray-200\">\n <div className=\"flex items-center gap-2\">\n {/* Upload */}\n <ToolbarButton onClick={handleUpload} icon=\"upload\" label=\"Upload\" />\n\n {/* Reprocess */}\n <ToolbarButton\n onClick={handleReprocess}\n icon=\"refresh\"\n label=\"Reprocess\"\n disabled={!hasSelection}\n />\n\n {/* Delete */}\n <ToolbarButton\n onClick={handleDelete}\n icon=\"trash\"\n label=\"Delete\"\n disabled={!hasSelection}\n variant=\"danger\"\n />\n\n {/* Sync CDN */}\n <ToolbarButton\n onClick={handleSyncCdn}\n icon=\"cloud\"\n label=\"Sync CDN\"\n disabled={!hasSelection}\n />\n\n {/* Scan */}\n <ToolbarButton onClick={handleScan} icon=\"scan\" label=\"Scan\" />\n </div>\n\n <div className=\"flex items-center gap-4\">\n {/* Selection count */}\n {hasSelection && (\n <span className=\"text-sm text-gray-600\">\n {selectedItems.size} selected\n <button\n onClick={clearSelection}\n className=\"ml-2 text-purple-600 hover:underline\"\n >\n Clear\n </button>\n </span>\n )}\n\n {/* View toggle */}\n <div className=\"flex items-center bg-white border border-gray-200 rounded-lg overflow-hidden\">\n <button\n onClick={() => setViewMode('grid')}\n className={`p-2 ${viewMode === 'grid' ? 'bg-purple-100 text-purple-700' : 'text-gray-500 hover:bg-gray-50'}`}\n aria-label=\"Grid view\"\n >\n <GridIcon />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={`p-2 ${viewMode === 'list' ? 'bg-purple-100 text-purple-700' : 'text-gray-500 hover:bg-gray-50'}`}\n aria-label=\"List view\"\n >\n <ListIcon />\n </button>\n </div>\n </div>\n </div>\n )\n}\n\ninterface ToolbarButtonProps {\n onClick: () => void\n icon: 'upload' | 'refresh' | 'trash' | 'cloud' | 'scan'\n label: string\n disabled?: boolean\n variant?: 'default' | 'danger'\n}\n\nfunction ToolbarButton({\n onClick,\n icon,\n label,\n disabled,\n variant = 'default',\n}: ToolbarButtonProps) {\n const baseStyles =\n 'flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors'\n const variantStyles =\n variant === 'danger'\n ? 'text-red-600 hover:bg-red-50 disabled:text-red-300'\n : 'text-gray-700 hover:bg-white disabled:text-gray-400'\n\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`${baseStyles} ${variantStyles} ${disabled ? 'cursor-not-allowed' : ''}`}\n >\n <IconComponent icon={icon} />\n {label}\n </button>\n )\n}\n\nfunction IconComponent({ icon }: { icon: string }) {\n const className = 'w-4 h-4'\n\n switch (icon) {\n case 'upload':\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12\"\n />\n </svg>\n )\n case 'refresh':\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n )\n case 'trash':\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n )\n case 'cloud':\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\"\n />\n </svg>\n )\n case 'scan':\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n )\n default:\n return null\n }\n}\n\nfunction GridIcon() {\n return (\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z\"\n />\n </svg>\n )\n}\n\nfunction ListIcon() {\n return (\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 6h16M4 10h16M4 14h16M4 18h16\"\n />\n </svg>\n )\n}\n","'use client'\n\nimport { useStudio } from './StudioContext'\n\n/**\n * Breadcrumb navigation bar\n */\nexport function StudioBreadcrumb() {\n const { currentPath, setCurrentPath, navigateUp } = useStudio()\n\n const parts = currentPath.split('/').filter(Boolean)\n\n const handleClick = (index: number) => {\n const newPath = parts.slice(0, index + 1).join('/')\n setCurrentPath(newPath)\n }\n\n return (\n <div className=\"flex items-center gap-2 px-6 py-2 bg-white border-b border-gray-100\">\n {/* Back button */}\n {currentPath !== 'public' && (\n <button\n onClick={navigateUp}\n className=\"p-1 hover:bg-gray-100 rounded transition-colors\"\n aria-label=\"Go back\"\n >\n <svg\n className=\"w-4 h-4 text-gray-500\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n )}\n\n {/* Breadcrumb trail */}\n <nav className=\"flex items-center gap-1 text-sm\">\n {parts.map((part, index) => (\n <span key={index} className=\"flex items-center gap-1\">\n {index > 0 && <span className=\"text-gray-300\">/</span>}\n <button\n onClick={() => handleClick(index)}\n className={`px-1 py-0.5 rounded hover:bg-gray-100 transition-colors ${\n index === parts.length - 1\n ? 'text-gray-900 font-medium'\n : 'text-gray-500 hover:text-gray-700'\n }`}\n >\n {part}\n </button>\n </span>\n ))}\n </nav>\n </div>\n )\n}\n","'use client'\n\nimport { useEffect, useState } from 'react'\nimport { useStudio } from './StudioContext'\nimport type { FileItem } from '../types'\n\n/**\n * Grid view of files and folders\n */\nexport function StudioFileGrid() {\n const { currentPath, setCurrentPath, selectedItems, toggleSelection } =\n useStudio()\n const [items, setItems] = useState<FileItem[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n async function loadItems() {\n setLoading(true)\n try {\n const response = await fetch(\n `/api/studio/list?path=${encodeURIComponent(currentPath)}`\n )\n if (response.ok) {\n const data = await response.json()\n setItems(data.items || [])\n }\n } catch (error) {\n console.error('Failed to load items:', error)\n }\n setLoading(false)\n }\n loadItems()\n }, [currentPath])\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600\" />\n </div>\n )\n }\n\n if (items.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center h-64 text-gray-500\">\n <svg\n className=\"w-12 h-12 mb-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n <p>No files in this folder</p>\n <p className=\"text-sm\">Upload images to get started</p>\n </div>\n )\n }\n\n // Sort: folders first, then files\n const sortedItems = [...items].sort((a, b) => {\n if (a.type === 'folder' && b.type !== 'folder') return -1\n if (a.type !== 'folder' && b.type === 'folder') return 1\n return a.name.localeCompare(b.name)\n })\n\n return (\n <div className=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4\">\n {sortedItems.map((item) => (\n <GridItem\n key={item.path}\n item={item}\n isSelected={selectedItems.has(item.path)}\n onSelect={() => toggleSelection(item.path)}\n onOpen={() => {\n if (item.type === 'folder') {\n setCurrentPath(item.path)\n }\n }}\n />\n ))}\n </div>\n )\n}\n\ninterface GridItemProps {\n item: FileItem\n isSelected: boolean\n onSelect: () => void\n onOpen: () => void\n}\n\nfunction GridItem({ item, isSelected, onSelect, onOpen }: GridItemProps) {\n const isFolder = item.type === 'folder'\n\n return (\n <div\n className={`relative group rounded-lg border-2 overflow-hidden cursor-pointer transition-all ${\n isSelected\n ? 'border-purple-500 bg-purple-50'\n : 'border-transparent hover:border-gray-200 bg-gray-50'\n }`}\n onDoubleClick={onOpen}\n >\n {/* Checkbox */}\n <div className=\"absolute top-2 left-2 z-10\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={onSelect}\n onClick={(e) => e.stopPropagation()}\n className=\"w-4 h-4 rounded border-gray-300 text-purple-600 focus:ring-purple-500\"\n />\n </div>\n\n {/* CDN badge */}\n {item.cdnSynced && (\n <div className=\"absolute top-2 right-2 z-10\">\n <span className=\"bg-green-100 text-green-700 text-xs px-1.5 py-0.5 rounded-full\">\n CDN\n </span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"aspect-square flex items-center justify-center p-4\">\n {isFolder ? (\n <FolderIcon />\n ) : (\n <img\n src={item.path.replace('public', '')}\n alt={item.name}\n className=\"max-w-full max-h-full object-contain rounded\"\n loading=\"lazy\"\n />\n )}\n </div>\n\n {/* Label */}\n <div className=\"px-2 py-1.5 bg-white border-t\">\n <p className=\"text-xs text-gray-700 truncate\" title={item.name}>\n {item.name}\n </p>\n {item.size && (\n <p className=\"text-xs text-gray-400\">\n {formatFileSize(item.size)}\n </p>\n )}\n </div>\n </div>\n )\n}\n\nfunction FolderIcon() {\n return (\n <svg\n className=\"w-16 h-16 text-yellow-400\"\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z\" />\n </svg>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","'use client'\n\nimport { useEffect, useState } from 'react'\nimport { useStudio } from './StudioContext'\nimport type { FileItem } from '../types'\n\n/**\n * List view of files and folders\n */\nexport function StudioFileList() {\n const { currentPath, setCurrentPath, selectedItems, toggleSelection } =\n useStudio()\n const [items, setItems] = useState<FileItem[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n async function loadItems() {\n setLoading(true)\n try {\n const response = await fetch(\n `/api/studio/list?path=${encodeURIComponent(currentPath)}`\n )\n if (response.ok) {\n const data = await response.json()\n setItems(data.items || [])\n }\n } catch (error) {\n console.error('Failed to load items:', error)\n }\n setLoading(false)\n }\n loadItems()\n }, [currentPath])\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600\" />\n </div>\n )\n }\n\n if (items.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center h-64 text-gray-500\">\n <p>No files in this folder</p>\n </div>\n )\n }\n\n // Sort: folders first, then files\n const sortedItems = [...items].sort((a, b) => {\n if (a.type === 'folder' && b.type !== 'folder') return -1\n if (a.type !== 'folder' && b.type === 'folder') return 1\n return a.name.localeCompare(b.name)\n })\n\n return (\n <table className=\"w-full\">\n <thead>\n <tr className=\"text-left text-xs text-gray-500 uppercase tracking-wider\">\n <th className=\"w-8 pb-2\"></th>\n <th className=\"pb-2\">Name</th>\n <th className=\"pb-2 w-24\">Size</th>\n <th className=\"pb-2 w-32\">Dimensions</th>\n <th className=\"pb-2 w-24\">CDN</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {sortedItems.map((item) => (\n <ListRow\n key={item.path}\n item={item}\n isSelected={selectedItems.has(item.path)}\n onSelect={() => toggleSelection(item.path)}\n onOpen={() => {\n if (item.type === 'folder') {\n setCurrentPath(item.path)\n }\n }}\n />\n ))}\n </tbody>\n </table>\n )\n}\n\ninterface ListRowProps {\n item: FileItem\n isSelected: boolean\n onSelect: () => void\n onOpen: () => void\n}\n\nfunction ListRow({ item, isSelected, onSelect, onOpen }: ListRowProps) {\n const isFolder = item.type === 'folder'\n\n return (\n <tr\n className={`cursor-pointer transition-colors ${\n isSelected ? 'bg-purple-50' : 'hover:bg-gray-50'\n }`}\n onDoubleClick={onOpen}\n >\n <td className=\"py-2\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={onSelect}\n onClick={(e) => e.stopPropagation()}\n className=\"w-4 h-4 rounded border-gray-300 text-purple-600 focus:ring-purple-500\"\n />\n </td>\n <td className=\"py-2\">\n <div className=\"flex items-center gap-2\">\n {isFolder ? (\n <svg\n className=\"w-5 h-5 text-yellow-400\"\n fill=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z\" />\n </svg>\n ) : (\n <svg\n className=\"w-5 h-5 text-gray-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n )}\n <span className=\"text-sm text-gray-900\">{item.name}</span>\n </div>\n </td>\n <td className=\"py-2 text-sm text-gray-500\">\n {item.size ? formatFileSize(item.size) : '--'}\n </td>\n <td className=\"py-2 text-sm text-gray-500\">\n {item.dimensions\n ? `${item.dimensions.width}x${item.dimensions.height}`\n : '--'}\n </td>\n <td className=\"py-2\">\n {item.cdnSynced ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-green-700\">\n <svg className=\"w-3 h-3\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n Synced\n </span>\n ) : (\n <span className=\"text-xs text-gray-400\">--</span>\n )}\n </td>\n </tr>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","'use client'\n\nimport { useStudio } from './StudioContext'\n\n/**\n * Preview panel for selected image\n */\nexport function StudioPreview() {\n const { selectedItems, meta } = useStudio()\n\n // Only show preview for single selection\n if (selectedItems.size !== 1) {\n return null\n }\n\n const selectedPath = Array.from(selectedItems)[0]\n\n // Extract the image key from the path (e.g., \"public/images/hero.jpg\" -> \"hero.jpg\")\n const imageKey = selectedPath\n .replace(/^public\\/images\\//, '')\n .replace(/^public\\/originals\\//, '')\n\n const imageData = meta?.images?.[imageKey]\n\n return (\n <div className=\"w-80 border-l border-gray-200 bg-gray-50 p-4 overflow-auto\">\n <h3 className=\"text-sm font-medium text-gray-900 mb-4\">Preview</h3>\n\n {/* Image preview */}\n <div className=\"bg-white rounded-lg border border-gray-200 p-2 mb-4\">\n <img\n src={selectedPath.replace('public', '')}\n alt=\"Preview\"\n className=\"w-full h-auto rounded\"\n />\n </div>\n\n {/* File info */}\n <div className=\"space-y-3\">\n <InfoRow label=\"Filename\" value={selectedPath.split('/').pop() || ''} />\n\n {imageData && (\n <>\n <InfoRow\n label=\"Original\"\n value={`${imageData.original.width}x${imageData.original.height}`}\n />\n <InfoRow\n label=\"File size\"\n value={formatFileSize(imageData.original.fileSize)}\n />\n\n <div className=\"pt-2 border-t border-gray-200\">\n <p className=\"text-xs font-medium text-gray-500 mb-2\">\n Generated sizes\n </p>\n {Object.entries(imageData.sizes).map(([size, data]) => (\n <InfoRow\n key={size}\n label={size}\n value={`${data.width}x${data.height}`}\n />\n ))}\n </div>\n\n {imageData.cdn?.synced && (\n <div className=\"pt-2 border-t border-gray-200\">\n <p className=\"text-xs font-medium text-gray-500 mb-2\">CDN</p>\n <div className=\"flex items-center gap-2 text-xs text-green-600\">\n <svg\n className=\"w-4 h-4\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n Synced to CDN\n </div>\n <button\n onClick={() => {\n navigator.clipboard.writeText(\n `${imageData.cdn?.baseUrl}${imageData.sizes.full.path}`\n )\n }}\n className=\"mt-2 text-xs text-purple-600 hover:underline\"\n >\n Copy CDN URL\n </button>\n </div>\n )}\n\n {imageData.blurhash && (\n <div className=\"pt-2 border-t border-gray-200\">\n <InfoRow label=\"Blurhash\" value={imageData.blurhash} truncate />\n <div\n className=\"mt-2 h-8 rounded\"\n style={{ backgroundColor: imageData.dominantColor }}\n title={`Dominant color: ${imageData.dominantColor}`}\n />\n </div>\n )}\n </>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"mt-4 pt-4 border-t border-gray-200 space-y-2\">\n <button className=\"w-full px-3 py-2 text-sm text-gray-700 bg-white border border-gray-200 rounded-lg hover:bg-gray-50 transition-colors\">\n Rename\n </button>\n <button className=\"w-full px-3 py-2 text-sm text-red-600 bg-white border border-gray-200 rounded-lg hover:bg-red-50 transition-colors\">\n Delete\n </button>\n </div>\n </div>\n )\n}\n\nfunction InfoRow({\n label,\n value,\n truncate,\n}: {\n label: string\n value: string\n truncate?: boolean\n}) {\n return (\n <div className=\"flex justify-between text-xs\">\n <span className=\"text-gray-500\">{label}</span>\n <span\n className={`text-gray-900 ${truncate ? 'truncate max-w-32' : ''}`}\n title={truncate ? value : undefined}\n >\n {value}\n </span>\n </div>\n )\n}\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","'use client'\n\nimport { useState } from 'react'\n\n/**\n * Settings button and panel\n */\nexport function StudioSettings() {\n const [isOpen, setIsOpen] = useState(false)\n\n return (\n <>\n <button\n onClick={() => setIsOpen(true)}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\n aria-label=\"Settings\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"w-5 h-5 text-gray-500\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z\" />\n </svg>\n </button>\n\n {isOpen && <SettingsPanel onClose={() => setIsOpen(false)} />}\n </>\n )\n}\n\nfunction SettingsPanel({ onClose }: { onClose: () => void }) {\n return (\n <div className=\"fixed inset-0 z-[10000] flex items-center justify-center\">\n {/* Backdrop */}\n <div className=\"absolute inset-0 bg-black/30\" onClick={onClose} />\n\n {/* Panel */}\n <div className=\"relative bg-white rounded-xl shadow-xl w-full max-w-lg p-6\">\n <div className=\"flex items-center justify-between mb-6\">\n <h2 className=\"text-lg font-semibold\">Settings</h2>\n <button\n onClick={onClose}\n className=\"p-1 hover:bg-gray-100 rounded-lg\"\n >\n <svg\n className=\"w-5 h-5 text-gray-500\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"space-y-6\">\n {/* Cloudflare R2 */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-900 mb-3\">\n Cloudflare R2\n </h3>\n <p className=\"text-xs text-gray-500 mb-3\">\n Configure in .env.local file:\n </p>\n <div className=\"bg-gray-50 rounded-lg p-3 font-mono text-xs text-gray-600 space-y-1\">\n <div>CLOUDFLARE_R2_ACCOUNT_ID</div>\n <div>CLOUDFLARE_R2_ACCESS_KEY_ID</div>\n <div>CLOUDFLARE_R2_SECRET_ACCESS_KEY</div>\n <div>CLOUDFLARE_R2_BUCKET_NAME</div>\n <div>CLOUDFLARE_R2_PUBLIC_URL</div>\n </div>\n </section>\n\n {/* Custom CDN URL */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-900 mb-3\">\n Custom CDN URL\n </h3>\n <p className=\"text-xs text-gray-500 mb-3\">\n Override the default R2 URL with a custom domain:\n </p>\n <input\n type=\"text\"\n placeholder=\"https://cdn.yourdomain.com\"\n className=\"w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-500\"\n />\n </section>\n\n {/* Thumbnail sizes */}\n <section>\n <h3 className=\"text-sm font-medium text-gray-900 mb-3\">\n Thumbnail Sizes\n </h3>\n <div className=\"grid grid-cols-3 gap-3\">\n <div>\n <label className=\"text-xs text-gray-500\">Small</label>\n <input\n type=\"number\"\n defaultValue={300}\n className=\"w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-500\"\n />\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">Medium</label>\n <input\n type=\"number\"\n defaultValue={700}\n className=\"w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-500\"\n />\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">Large</label>\n <input\n type=\"number\"\n defaultValue={1400}\n className=\"w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-500\"\n />\n </div>\n </div>\n </section>\n </div>\n\n <div className=\"mt-6 flex justify-end gap-3\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg\"\n >\n Cancel\n </button>\n <button className=\"px-4 py-2 text-sm text-white bg-purple-600 hover:bg-purple-700 rounded-lg\">\n Save Changes\n </button>\n </div>\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["useEffect","useCallback","useState","jsx","jsxs","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","formatFileSize","jsx","jsxs","formatFileSize","useState","Fragment","jsx","jsxs","jsx","jsxs","useState","useCallback","useEffect"]}
|