File size: 4,804 Bytes
a94ab76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import React, { useState, KeyboardEvent, useRef } from 'react';
import { Send, Loader2, Plus, X } from 'lucide-react';

interface ChatInputProps {
  onSend: (message: string) => void;
  disabled?: boolean;
  isLoading?: boolean;
  onImageSelect?: (image: string | null) => void;
  currentImage?: string | null;
  supportsImages?: boolean;
}

export const ChatInput: React.FC<ChatInputProps> = ({ 
  onSend, 
  disabled = false, 
  isLoading = false,
  onImageSelect,
  currentImage,
  supportsImages = false
}) => {
  const [input, setInput] = useState('');
  const [preview, setPreview] = useState<string | null>(currentImage || null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleSend = () => {
    if (input.trim() && !disabled && !isLoading) {
      onSend(input.trim());
      setInput('');
    }
  };

  const handleKeyPress = (e: KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };

  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 handleRemoveImage = () => {
    setPreview(null);
    onImageSelect?.(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  // Update preview when currentImage changes
  React.useEffect(() => {
    setPreview(currentImage || null);
  }, [currentImage]);

  return (
    <div className="w-full max-w-4xl mx-auto">
      {/* Image Preview */}
      {preview && (
        <div className="mb-3 relative inline-block">
          <img
            src={preview}
            alt="Preview"
            className="max-w-xs h-32 object-contain rounded-lg border border-gray-300 dark:border-gray-700"
          />
          <button
            onClick={handleRemoveImage}
            className="absolute -top-2 -right-2 p-1 bg-red-500 hover:bg-red-600 text-white rounded-full transition-all shadow-lg"
          >
            <X size={14} />
          </button>
        </div>
      )}
      
      <div className="relative flex items-center gap-2 bg-white dark:bg-gray-800 rounded-3xl shadow-lg border border-gray-200 dark:border-gray-700 px-3 py-3 transition-all focus-within:shadow-xl focus-within:border-primary-500 dark:focus-within:border-primary-600">
        {/* Hidden File Input */}
        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          onChange={handleFileChange}
          className="hidden"
          disabled={!supportsImages}
        />
        
        {/* Plus Button for Image Upload */}
        <button
          onClick={() => fileInputRef.current?.click()}
          disabled={!supportsImages}
          className={`flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center transition-all ${
            supportsImages
              ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400'
              : 'text-gray-300 dark:text-gray-600 cursor-not-allowed'
          }`}
          title={supportsImages ? "Resim yükle" : "Bu model resim desteklemiyor"}
        >
          <Plus size={20} />
        </button>

        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={handleKeyPress}
          placeholder="Herhangi bir şey sor"
          rows={1}
          disabled={disabled || isLoading}
          className="flex-1 bg-transparent text-gray-900 dark:text-gray-100 resize-none border-none focus:outline-none focus:ring-0 placeholder:text-gray-400 dark:placeholder:text-gray-500 disabled:cursor-not-allowed"
          style={{ minHeight: '24px', maxHeight: '120px' }}
          onInput={(e) => {
            const target = e.target as HTMLTextAreaElement;
            target.style.height = 'auto';
            target.style.height = Math.min(target.scrollHeight, 120) + 'px';
          }}
        />
        <button
          onClick={handleSend}
          disabled={!input.trim() || disabled || isLoading}
          className="flex-shrink-0 w-8 h-8 bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 disabled:bg-gray-100 dark:disabled:bg-gray-800 disabled:cursor-not-allowed rounded-lg flex items-center justify-center transition-all"
        >
          {isLoading ? (
            <Loader2 size={18} className="animate-spin text-gray-600 dark:text-gray-400" />
          ) : (
            <Send size={18} className="text-gray-600 dark:text-gray-300" />
          )}
        </button>
      </div>

    </div>
  );
};