AIWeddingFittingRoom / components /FilterSelector.tsx
Lianjx's picture
Upload 71 files
459775e verified
import React from 'react';
import { Palette, Sun, Moon, Coffee, Droplet, Zap, Maximize, Aperture, Sparkles, Cloud } from 'lucide-react';
import { Language } from '../types';
import { TRANSLATIONS } from '../constants/translations';
export interface ImageFilter {
id: string;
name: string;
css: string; // CSS filter string
icon?: React.ReactNode;
}
export const FILTERS: ImageFilter[] = [
{ id: 'none', name: 'Original', css: 'none', icon: <Palette className="w-4 h-4" /> },
{ id: 'bw', name: 'B&W', css: 'grayscale(100%)', icon: <Aperture className="w-4 h-4" /> },
{ id: 'sepia', name: 'Sepia', css: 'sepia(100%)', icon: <Coffee className="w-4 h-4" /> },
{ id: 'vintage', name: 'Vintage', css: 'sepia(0.4) contrast(1.2) brightness(0.9)', icon: <Droplet className="w-4 h-4" /> },
{ id: 'soft', name: 'Soft', css: 'brightness(1.1) contrast(0.9) saturate(0.8)', icon: <Sun className="w-4 h-4" /> },
{ id: 'dramatic', name: 'Dramatic', css: 'contrast(1.4) saturate(0.2)', icon: <Zap className="w-4 h-4" /> },
{ id: 'golden', name: 'Golden', css: 'sepia(0.3) saturate(1.4) contrast(1.1)', icon: <Maximize className="w-4 h-4" /> },
{ id: 'glow', name: 'Glow', css: 'brightness(1.1) saturate(1.2) contrast(0.9)', icon: <Sparkles className="w-4 h-4" /> },
{ id: 'dark', name: 'Dark Mode', css: 'brightness(0.8) contrast(1.2) saturate(1.1) hue-rotate(-15deg)', icon: <Moon className="w-4 h-4" /> },
];
interface FilterSelectorProps {
selectedFilter: string;
onSelect: (filterId: string) => void;
blurAmount: number;
onBlurChange: (amount: number) => void;
disabled: boolean;
language: Language;
}
export const FilterSelector: React.FC<FilterSelectorProps> = ({
selectedFilter,
onSelect,
blurAmount,
onBlurChange,
disabled,
language
}) => {
const t = TRANSLATIONS[language];
return (
<div className="w-full space-y-4">
{/* Filters Row */}
<div>
<div className="flex items-center gap-2 mb-2">
<Palette className="w-4 h-4 text-gray-500" />
<h4 className="text-sm font-bold text-gray-700">{t.colorFilters}</h4>
</div>
<div className="flex flex-wrap gap-2">
{FILTERS.map((filter) => (
<button
key={filter.id}
onClick={() => onSelect(filter.id)}
disabled={disabled}
className={`
flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium border transition-all
${selectedFilter === filter.id
? 'bg-rose-50 border-rose-500 text-rose-700 shadow-sm'
: 'bg-white border-gray-200 text-gray-600 hover:border-rose-200 hover:bg-gray-50'}
${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
`}
>
{filter.icon}
{filter.name}
</button>
))}
</div>
</div>
{/* Blur Slider Row */}
<div className="pt-2">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<Cloud className="w-4 h-4 text-gray-500" />
<h4 className="text-sm font-bold text-gray-700">{t.bgBlur}</h4>
</div>
<span className="text-xs font-mono text-gray-500 bg-gray-100 px-2 py-0.5 rounded">
{blurAmount.toFixed(1)}px
</span>
</div>
<div className="flex items-center gap-4">
<input
type="range"
min="0"
max="10"
step="0.5"
value={blurAmount}
onChange={(e) => onBlurChange(parseFloat(e.target.value))}
disabled={disabled}
className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-rose-500"
/>
</div>
<p className="text-[10px] text-gray-400 mt-1">
{t.bgBlurDesc}
</p>
</div>
</div>
);
};