102 lines
3.4 KiB
React
102 lines
3.4 KiB
React
import { File as FileIcon } from '@phosphor-icons/react';
|
|
import { formatBytes } from '../utils/formatBytes.js';
|
|
|
|
const QUALITY_FORMATS = ['jpg', 'jpeg', 'webp', 'avif', 'tiff'];
|
|
const ICON_SIZES = [16, 32, 48, 256, 512];
|
|
const DEFAULT_ICON_SIZE = 256;
|
|
|
|
export function FileConfigCard({ item, index, t, onTargetFormatChange, onQualityChange, onIconSizeChange }) {
|
|
return (
|
|
<li className="file-config-card">
|
|
<div className="file-tile-header">
|
|
<FileIcon size={24} weight="regular" />
|
|
<span className="file-tile-name">{item.file.name}</span>
|
|
<span className="file-tile-size">{formatBytes(item.file.size)}</span>
|
|
</div>
|
|
|
|
{item.targets.length > 0 ? (
|
|
<div className="file-config-controls">
|
|
<div className="format-select-group">
|
|
<select
|
|
className="format-select"
|
|
value={item.targetFormat ?? ''}
|
|
onChange={(event) => onTargetFormatChange(index, event.target.value)}
|
|
>
|
|
{item.targets.map((target) => (
|
|
<option key={target} value={target}>
|
|
{target}
|
|
</option>
|
|
))}
|
|
</select>
|
|
{item.targetFormat && <span className="format-badge">{item.targetFormat.toUpperCase()}</span>}
|
|
</div>
|
|
|
|
{QUALITY_FORMATS.includes(item.targetFormat) && (
|
|
<label>
|
|
{t('quality.label', { value: item.quality })}
|
|
<input
|
|
type="range"
|
|
min="1"
|
|
max="100"
|
|
value={item.quality}
|
|
onChange={(event) => onQualityChange(index, Number(event.target.value))}
|
|
/>
|
|
</label>
|
|
)}
|
|
|
|
{item.targetFormat === 'png' && (
|
|
<label>
|
|
{t('quality.compression', { value: item.quality })}
|
|
<input
|
|
type="range"
|
|
min="0"
|
|
max="9"
|
|
value={item.quality}
|
|
onChange={(event) => onQualityChange(index, Number(event.target.value))}
|
|
/>
|
|
</label>
|
|
)}
|
|
|
|
{item.targetFormat === 'ico' && (
|
|
<label>
|
|
{t('quality.iconSize')}
|
|
<select
|
|
value={item.iconSize ?? DEFAULT_ICON_SIZE}
|
|
onChange={(event) => onIconSizeChange(index, Number(event.target.value))}
|
|
>
|
|
{ICON_SIZES.map((size) => (
|
|
<option key={size} value={size}>
|
|
{size}px
|
|
</option>
|
|
))}
|
|
</select>
|
|
</label>
|
|
)}
|
|
|
|
{item.targetFormat === 'pdf' && (
|
|
<label>
|
|
<input
|
|
type="checkbox"
|
|
checked={item.quality !== null}
|
|
onChange={(event) => onQualityChange(index, event.target.checked ? 90 : null)}
|
|
/>
|
|
{t('quality.compressPdf')}
|
|
{item.quality !== null && (
|
|
<input
|
|
type="range"
|
|
min="1"
|
|
max="100"
|
|
value={item.quality}
|
|
onChange={(event) => onQualityChange(index, Number(event.target.value))}
|
|
/>
|
|
)}
|
|
</label>
|
|
)}
|
|
</div>
|
|
) : (
|
|
<span className="error">{t('hero.unsupportedFormat')}</span>
|
|
)}
|
|
</li>
|
|
);
|
|
}
|