'use client'; import * as React from 'react'; import { ChevronDown, ChevronUp, Sparkles } from 'lucide-react'; import { Card } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Slider } from '@/components/ui/Slider'; import { Select } from '@/components/ui/Select'; import type { ConversionOptions, ConversionFormat } from '@/types/conversion'; interface ConversionOptionsProps { inputFormat: ConversionFormat; outputFormat: ConversionFormat; options: ConversionOptions; onOptionsChange: (options: ConversionOptions) => void; disabled?: boolean; } interface QualityPreset { id: string; name: string; description: string; icon: string; options: ConversionOptions; } export function ConversionOptionsPanel({ inputFormat, outputFormat, options, onOptionsChange, disabled = false, }: ConversionOptionsProps) { const [isExpanded, setIsExpanded] = React.useState(false); const [selectedPreset, setSelectedPreset] = React.useState(null); // Quality presets based on output format category const getPresets = (): QualityPreset[] => { const category = outputFormat.category; if (category === 'video') { return [ { id: 'high-quality', name: 'High Quality', description: 'Best quality, larger file size', icon: '⭐', options: { videoBitrate: '5M', videoCodec: outputFormat.extension === 'webm' ? 'libvpx' : 'libx264', audioBitrate: '192k', audioCodec: outputFormat.extension === 'webm' ? 'libvorbis' : 'aac', }, }, { id: 'balanced', name: 'Balanced', description: 'Good quality, moderate size', icon: '⚖️', options: { videoBitrate: '2M', videoCodec: outputFormat.extension === 'webm' ? 'libvpx' : 'libx264', audioBitrate: '128k', audioCodec: outputFormat.extension === 'webm' ? 'libvorbis' : 'aac', }, }, { id: 'small-file', name: 'Small File', description: 'Smaller size, lower quality', icon: '📦', options: { videoBitrate: '1M', videoCodec: outputFormat.extension === 'webm' ? 'libvpx' : 'libx264', audioBitrate: '96k', audioCodec: outputFormat.extension === 'webm' ? 'libvorbis' : 'aac', }, }, { id: 'web-optimized', name: 'Web Optimized', description: 'Fast loading for web', icon: '🌐', options: { videoBitrate: '1.5M', videoCodec: 'libvpx', audioBitrate: '128k', audioCodec: 'libvorbis', videoResolution: '720x-1', }, }, ]; } else if (category === 'audio') { return [ { id: 'high-quality', name: 'High Quality', description: 'Best audio quality', icon: '⭐', options: { audioBitrate: '320k', audioCodec: outputFormat.extension === 'mp3' ? 'libmp3lame' : 'default', }, }, { id: 'balanced', name: 'Balanced', description: 'Good quality, smaller size', icon: '⚖️', options: { audioBitrate: '192k', audioCodec: outputFormat.extension === 'mp3' ? 'libmp3lame' : 'default', }, }, { id: 'small-file', name: 'Small File', description: 'Minimum file size', icon: '📦', options: { audioBitrate: '128k', audioCodec: outputFormat.extension === 'mp3' ? 'libmp3lame' : 'default', }, }, ]; } else if (category === 'image') { return [ { id: 'high-quality', name: 'High Quality', description: 'Best image quality', icon: '⭐', options: { imageQuality: 95, }, }, { id: 'balanced', name: 'Balanced', description: 'Good quality', icon: '⚖️', options: { imageQuality: 85, }, }, { id: 'web-optimized', name: 'Web Optimized', description: 'Optimized for web', icon: '🌐', options: { imageQuality: 75, }, }, ]; } return []; }; const presets = getPresets(); const handlePresetClick = (preset: QualityPreset) => { setSelectedPreset(preset.id); onOptionsChange({ ...options, ...preset.options }); }; const handleOptionChange = (key: string, value: any) => { setSelectedPreset(null); // Clear preset when manual change onOptionsChange({ ...options, [key]: value }); }; const renderVideoOptions = () => (
{/* Video Codec */} handleOptionChange('videoResolution', value === 'original' ? undefined : value)} options={[ { value: 'original', label: 'Original' }, { value: '1920x-1', label: '1080p (1920x1080)' }, { value: '1280x-1', label: '720p (1280x720)' }, { value: '854x-1', label: '480p (854x480)' }, { value: '640x-1', label: '360p (640x360)' }, ]} disabled={disabled} /> {/* FPS */} handleOptionChange('audioCodec', value === 'default' ? undefined : value)} options={[ { value: 'default', label: 'Auto (Recommended)' }, { value: 'libmp3lame', label: 'MP3 (LAME)' }, { value: 'aac', label: 'AAC' }, { value: 'libvorbis', label: 'Vorbis (OGG)' }, { value: 'libopus', label: 'Opus' }, { value: 'flac', label: 'FLAC (Lossless)' }, ]} disabled={disabled} /> {/* Bitrate */} handleOptionChange('audioBitrate', `${value}k`)} showValue={true} unit="k" disabled={disabled} /> {/* Sample Rate */} handleOptionChange('audioChannels', value === 'original' ? undefined : parseInt(value))} options={[ { value: 'original', label: 'Original' }, { value: '2', label: 'Stereo (2 channels)' }, { value: '1', label: 'Mono (1 channel)' }, ]} disabled={disabled} />
); const renderImageOptions = () => (
{/* Quality */} handleOptionChange('imageQuality', value)} showValue={true} unit="%" disabled={disabled} /> {/* Width */}
handleOptionChange('imageWidth', e.target.value ? parseInt(e.target.value) : undefined)} placeholder="Original" className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm" disabled={disabled} />

Leave empty to keep original

{/* Height */}
handleOptionChange('imageHeight', e.target.value ? parseInt(e.target.value) : undefined)} placeholder="Original" className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm" disabled={disabled} />

Leave empty to maintain aspect ratio

); return ( {/* Presets Section */} {presets.length > 0 && (

Quality Presets

{presets.map((preset) => ( ))}
)} {/* Advanced Options Toggle */} {/* Advanced Options Panel */} {isExpanded && (
{outputFormat.category === 'video' && renderVideoOptions()} {outputFormat.category === 'audio' && renderAudioOptions()} {outputFormat.category === 'image' && renderImageOptions()}
)}
); }