| import React, { useRef, useState } from 'react'; | |
| import { Upload, X, Image as ImageIcon } from 'lucide-react'; | |
| interface ImageUploadProps { | |
| onImageSelect: (image: string | null) => void; | |
| currentImage: string | null; | |
| disabled?: boolean; | |
| } | |
| export const ImageUpload: React.FC<ImageUploadProps> = ({ | |
| onImageSelect, | |
| currentImage, | |
| disabled = false | |
| }) => { | |
| const fileInputRef = useRef<HTMLInputElement>(null); | |
| const [preview, setPreview] = useState<string | null>(currentImage); | |
| const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
| const file = e.target.files?.[0]; | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onloadend = () => { | |
| const result = reader.result as string; | |
| setPreview(result); | |
| onImageSelect(result); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| }; | |
| const handleRemove = () => { | |
| setPreview(null); | |
| onImageSelect(null); | |
| if (fileInputRef.current) { | |
| fileInputRef.current.value = ''; | |
| } | |
| }; | |
| const handleClick = () => { | |
| if (!disabled) { | |
| fileInputRef.current?.click(); | |
| } | |
| }; | |
| return ( | |
| <div> | |
| <label className="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> | |
| <ImageIcon size={16} /> | |
| Resim Yükle | |
| {disabled && <span className="text-gray-400 dark:text-gray-600 text-xs font-normal">(Sadece Gemma 3 12B)</span>} | |
| </label> | |
| <input | |
| ref={fileInputRef} | |
| type="file" | |
| accept="image/*" | |
| onChange={handleFileChange} | |
| className="hidden" | |
| disabled={disabled} | |
| /> | |
| {preview ? ( | |
| <div className="relative inline-block group"> | |
| <img | |
| src={preview} | |
| alt="Preview" | |
| className="max-w-full h-40 object-contain rounded-lg border-2 border-gray-200 dark:border-gray-700" | |
| /> | |
| <button | |
| onClick={handleRemove} | |
| className="absolute top-2 right-2 p-1.5 bg-red-500 hover:bg-red-600 text-white rounded-lg transition-all shadow-lg opacity-0 group-hover:opacity-100" | |
| > | |
| <X size={16} /> | |
| </button> | |
| </div> | |
| ) : ( | |
| <button | |
| onClick={handleClick} | |
| disabled={disabled} | |
| className={`w-full border-2 border-dashed rounded-lg p-6 text-center transition-all ${ | |
| disabled | |
| ? 'border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900 cursor-not-allowed' | |
| : 'border-gray-300 dark:border-gray-700 hover:border-primary-400 dark:hover:border-primary-600 hover:bg-primary-50 dark:hover:bg-primary-900/10 cursor-pointer' | |
| }`} | |
| > | |
| <Upload | |
| className={`mx-auto mb-2 ${disabled ? 'text-gray-300 dark:text-gray-700' : 'text-gray-400 dark:text-gray-500'}`} | |
| size={28} | |
| /> | |
| <p className={`text-sm ${disabled ? 'text-gray-400 dark:text-gray-600' : 'text-gray-600 dark:text-gray-400'}`}> | |
| {disabled ? 'Resim yüklemek için görsel destekli model seçin' : 'Resim yüklemek için tıklayın'} | |
| </p> | |
| {!disabled && ( | |
| <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">PNG, JPG, GIF</p> | |
| )} | |
| </button> | |
| )} | |
| </div> | |
| ); | |
| }; | |