DAM File Picker Component Guide
This guide covers the FilePicker component, a sophisticated file management system that integrates with the DAM (Digital Asset Management) system. This component replaces Filestack implementations and provides multiple upload methods with advanced features.
Overview
The FilePicker is a modal-based component that provides a unified interface for file selection, upload, and management. It supports multiple upload methods, integrates with the DAM system, and includes advanced features like shareable media creation.
Core Features
The FilePicker component provides four main tabs for different file management needs:
- Upload Tab - Computer upload and URL download
- Library Tab - Browse existing DAM assets
- Media Tab - Browse existing shareable media (optional)
- Unsplash Tab - Search and select from Unsplash images
Upload Methods & Tabs
Upload Tab
The Upload tab provides two primary methods for adding files:
Computer Upload
- Drag & Drop Functionality: Users can drag files directly onto the upload area
- File Browser: Click to browse and select files from the device
- File Validation: Automatic validation of file types, sizes, and formats
- Progress Tracking: Real-time upload progress indication
- Automatic File Routing:
- Text files use traditional upload
- All other files use ImageKit direct upload for better performance
URL Upload
- Web URL Download: Download files directly from web URLs
- Automatic Processing: Files are processed and uploaded to the DAM system
- Validation: URL validation and file type detection
Library Tab (DAM)
The Library tab provides access to existing DAM assets:
- Hierarchical Navigation: Browse assets using ltree navigation with dot notation
- Search and Filter: Advanced search and filtering capabilities
- Variant Selection: Select from multiple formats/sizes for assets with variants
- No Upload Functionality: Selection only - no new uploads
- Asset Organization: Navigate through organized asset categories
DAM Navigation Examples
company_id.images.asset_code // Specific asset company_id.* // All items under company company_id.images.* // All images under company
Media Tab (Optional)
The Media tab allows browsing existing shareable media:
- Media Browser: Browse existing shareable media
- Search by Title: Search functionality with pagination
- Visual Previews: Image previews for media items
- Domain Integration: Used for attaching media to domain areas like events
- Reuse Content: Select from previously created media
Unsplash Tab
The Unsplash tab provides integration with Unsplash's image library:
- Image Search: Search and select from Unsplash images
- API Integration: Direct integration with Unsplash API
- High-Quality Images: Access to professional stock photography
- Direct Download: Images are downloaded and processed automatically
Component Props & Configuration
FilePickerProps Interface
interface FilePickerProps { isOpen: boolean onClose: () => void onFilesSelected: (files: FilePickerResult[]) => void config?: FilePickerConfig showMediaTab?: boolean showUnsplashTab?: boolean allowShareableMediaCreation?: boolean }
FilePickerConfig Interface
interface FilePickerConfig { accept?: string[] // MIME types or file extensions maxFiles?: number // Maximum number of files maxSize?: number // Maximum file size in bytes multiple?: boolean // Allow multiple file selection }
Configuration Examples
Single Image Only
const config: FilePickerConfig = { accept: ["image/*"], maxFiles: 1, maxSize: 5 * 1024 * 1024 // 5MB }
Multiple Documents
const config: FilePickerConfig = { accept: ["application/pdf", ".doc", ".docx"], maxFiles: 10, maxSize: 10 * 1024 * 1024 // 10MB }
No Restrictions
const config: FilePickerConfig = { maxFiles: undefined, accept: undefined, maxSize: undefined }
Return Value Structure
FilePickerResult Interface
interface FilePickerResult { id: string name: string url: string type: 'asset' | 'media' | 'unsplash' metadata?: { size?: number mimeType?: string dimensions?: { width: number; height: number } alt?: string } shareableMediaOptions?: ShareableMediaOptions }
ShareableMediaOptions Interface
interface ShareableMediaOptions { title: string description?: string productIds?: string[] themeTemplateId?: string countryTargeting?: string[] ctaType?: 'button' | 'cart' ctaText?: string }
Usage Examples
Basic Usage
import { FilePicker } from '@/components/FilePicker' function MyComponent() { const [isPickerOpen, setIsPickerOpen] = useState(false) const [selectedFiles, setSelectedFiles] = useState<FilePickerResult[]>([]) const handleFilesSelected = (files: FilePickerResult[]) => { setSelectedFiles(files) setIsPickerOpen(false) } return ( <> <button onClick={() => setIsPickerOpen(true)}> Select Files </button> <FilePicker isOpen={isPickerOpen} onClose={() => setIsPickerOpen(false)} onFilesSelected={handleFilesSelected} config={{ accept: ["image/*"], maxFiles: 5, maxSize: 10 * 1024 * 1024 }} /> </> ) }
With React Hook Form Integration
import { useForm, Controller } from 'react-hook-form' import { FilePicker } from '@/components/FilePicker' function ProductForm() { const { control, handleSubmit } = useForm() return ( <form onSubmit={handleSubmit(onSubmit)}> <Controller name="productImages" control={control} render={({ field }) => ( <FilePicker isOpen={field.value?.isOpen || false} onClose={() => field.onChange({ ...field.value, isOpen: false })} onFilesSelected={(files) => { field.onChange({ ...field.value, files, isOpen: false }) }} config={{ accept: ["image/*"], maxFiles: 10 }} /> )} /> </form> ) }
With Media Tab
<FilePicker isOpen={isPickerOpen} onClose={() => setIsPickerOpen(false)} onFilesSelected={handleFilesSelected} showMediaTab={true} config={{ accept: ["image/*", "video/*"], maxFiles: 1 }} />
With Shareable Media Creation
<FilePicker isOpen={isPickerOpen} onClose={() => setIsPickerOpen(false)} onFilesSelected={handleFilesSelected} allowShareableMediaCreation={true} showMediaTab={true} config={{ accept: ["image/*"], maxFiles: 1 }} />
Advanced Features
DAM Integration
The FilePicker integrates deeply with the DAM system:
Asset Storage Structure
{company_id}.{category}.{asset_code}
Ltree Navigation
- Dot Notation:
company_id.images.asset_code
- Wildcard Support:
company_id.*
(all items under company) - Hierarchical Browsing: Navigate through organized asset categories
Variant Selection
- Assets with multiple formats/sizes show variant options
- Users can select the most appropriate variant for their use case
- Automatic optimization based on context
Shareable Media Creation
The component supports a two-step process for creating shareable media:
- File Selection: Choose files from any tab
- Media Details: Configure media options including:
- Title and description
- Product associations
- Theme template selection
- Country targeting
- CTA configuration (button/cart types)
File Routing
The component intelligently routes files based on type:
- Text Files: Use traditional upload for better compatibility
- All Other Files: Use ImageKit direct upload for better performance and features
Environment Variables
The following environment variables are required:
# ImageKit Configuration NEXT_PUBLIC_IMAGEKIT_URL_ENDPOINT=your_imagekit_url_endpoint NEXT_PUBLIC_IMAGEKIT_PUBLIC_KEY=your_imagekit_public_key NEXT_PUBLIC_IMAGEKIT_PRIVATE_KEY=your_imagekit_private_key # Unsplash Integration NEXT_PUBLIC_UNSPLASH_ACCESS_KEY=your_unsplash_access_key
API Endpoints
The FilePicker component uses these API endpoints:
DAM Endpoints
POST /api/dam/assets
- Upload new assetsPOST /api/dam/query
- Browse DAM library with ltree queries
External APIs
- Unsplash API - Search and download images
- ImageKit API - Direct file uploads and transformations
Testing & Development
POC Page
A proof-of-concept page is available at /poc/file-picker
for testing different configurations and features.
Component Architecture
The component uses separate hooks for each upload method:
useUploadTab
- Handles computer and URL uploadsuseLibraryTab
- Manages DAM asset browsinguseMediaTab
- Handles shareable media selectionuseUnsplashTab
- Manages Unsplash integration
Error Handling
- Comprehensive validation for file types and sizes
- Network error handling with retry mechanisms
- User-friendly error messages
- Graceful fallbacks for failed operations
Component Architecture
File Structure
components/ ├── FilePicker/ │ ├── index.tsx # Main component │ ├── FilePickerModal.tsx # Modal wrapper │ ├── tabs/ │ │ ├── UploadTab.tsx # Upload functionality │ │ ├── LibraryTab.tsx # DAM browsing │ │ ├── MediaTab.tsx # Shareable media │ │ └── UnsplashTab.tsx # Unsplash integration │ ├── hooks/ │ │ ├── useUploadTab.ts # Upload logic │ │ ├── useLibraryTab.ts # DAM logic │ │ ├── useMediaTab.ts # Media logic │ │ └── useUnsplashTab.ts # Unsplash logic │ └── types.ts # TypeScript interfaces
Dependencies
Key Dependencies
@tanstack/react-query
- Data fetching and cachingreact-hook-form
- Form handling@hookform/resolvers/zod
- Form validationzod
- Schema validationreact-dropzone
- Drag-and-drop functionality@fluid-app/fluid-ui
- UI components@fortawesome/react-fontawesome
- Icons
Best Practices
Implementation
- Always handle the
onFilesSelected
callback - Use appropriate configuration for file type restrictions
- Implement proper error handling
- Consider file size limits for better UX
User Experience
- Use the media tab for reusing existing content
- Leverage DAM library for organized asset management
- Provide clear feedback during uploads
- Use appropriate file size limits
Performance
- Use ImageKit direct upload for non-text files
- Implement proper caching for DAM queries
- Optimize image uploads with appropriate compression
- Use pagination for large media libraries
Common Use Cases
Profile Pictures
<FilePicker config={{ accept: ["image/*"], maxFiles: 1, maxSize: 2 * 1024 * 1024 // 2MB }} />
Document Attachments
<FilePicker config={{ accept: ["application/pdf", ".doc", ".docx"], maxFiles: 10, maxSize: 10 * 1024 * 1024 // 10MB }} />
Media Galleries
<FilePicker showMediaTab={true} config={{ accept: ["image/*", "video/*"], maxFiles: 20 }} />
Event Media
<FilePicker showMediaTab={true} config={{ accept: ["image/*"], maxFiles: 1 }} />
Content Creation
<FilePicker allowShareableMediaCreation={true} showMediaTab={true} showUnsplashTab={true} config={{ accept: ["image/*"], maxFiles: 1 }} />
Troubleshooting
Common Issues
File Upload Failures
- Check file size limits: Ensure files don't exceed configured limits
- Verify file types: Check that file types are in the accepted list
- Network connectivity: Ensure stable internet connection
- ImageKit configuration: Verify ImageKit credentials and endpoints
DAM Navigation Issues
- Ltree syntax: Ensure proper dot notation for navigation
- Permissions: Check user permissions for DAM access
- Asset existence: Verify assets exist in the specified path
Unsplash API Errors
- API key: Verify
NEXT_PUBLIC_UNSPLASH_ACCESS_KEY
is set - Rate limits: Check Unsplash API rate limits
- Network issues: Ensure external API access is available
ImageKit Upload Problems
- Credentials: Verify ImageKit public and private keys
- Endpoint: Check ImageKit URL endpoint configuration
- File routing: Ensure proper file type routing logic
Form Validation Errors
- Required fields: Check that all required fields are provided
- Data types: Verify data types match expected schemas
- Validation rules: Review Zod validation schemas
Debug Information
Enable browser developer tools to monitor:
- Network requests to DAM and ImageKit APIs
- Form submission data and validation
- JavaScript console errors
- React Query cache and state
- Component state and props
Development Tools
- POC Page: Use
/poc/file-picker
for testing - React DevTools: Monitor component state and props
- Network Tab: Track API requests and responses
- Console Logs: Check for JavaScript errors and warnings
API Integration
The FilePicker component integrates with:
- DAM System: For asset storage and management
- ImageKit: For file uploads and transformations
- Unsplash API: For stock image access
- Fluid API: For shareable media management
For API-level integration details, refer to the DAM Upload Endpoints Guide.