File size: 3,820 Bytes
a3976c3
 
052a316
a3976c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
052a316
 
 
 
 
 
 
a3976c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
052a316
a3976c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// src/components/ProviderDropdown.js
import React, { useState, useRef, useEffect } from 'react';
import { ChevronDown, Cpu, Cloud, Server, Loader2 } from 'lucide-react';
import { useTheme } from '../contexts/ThemeContext';

const ProviderDropdown = ({ currentProvider, onProviderChange, isLoading = false }) => {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef(null);
  const { isDark } = useTheme();

  const providers = [
    {
      id: 'gemini',
      name: 'Gemini',
      description: 'Google\'s Gemini AI',
      icon: Cloud,
      badge: 'Cloud'
    },
    {
      id: 'ollama', 
      name: 'Ollama',
      description: 'Local LLM via Ollama',
      icon: Cpu,
      badge: 'Local'
    },
    {
      id: 'vllm',
      name: 'vLLM',
      description: 'vLLM inference endpoint',
      icon: Server,
      badge: 'API'
    }
  ];

  const currentProviderInfo = providers.find(p => p.id === currentProvider);

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setIsOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, []);

  const handleProviderSelect = (providerId) => {
    if (providerId !== currentProvider && !isLoading) {
      onProviderChange(providerId);
      setIsOpen(false);
    }
  };

  const toggleDropdown = () => {
    if (!isLoading) {
      setIsOpen(!isOpen);
    }
  };

  return (
    <div className="provider-dropdown" ref={dropdownRef}>
      <button 
        className={`provider-button ${isOpen ? 'open' : ''} ${isLoading ? 'loading' : ''}`}
        onClick={toggleDropdown}
        disabled={isLoading}
      >
        <div className="provider-button-content">
          {isLoading ? (
            <Loader2 className="provider-icon spinning" size={16} />
          ) : (
            <currentProviderInfo.icon className="provider-icon" size={16} />
          )}
          <div className="provider-info">
            <span className="provider-name">{currentProviderInfo?.name || 'Unknown'}</span>
            <span className={`provider-badge ${currentProvider}`}>{currentProviderInfo?.badge}</span>
          </div>
        </div>
        <ChevronDown 
          className={`dropdown-arrow ${isOpen ? 'rotated' : ''}`} 
          size={16} 
        />
      </button>

      {isOpen && (
        <div className="provider-dropdown-menu">
          {providers.map((provider) => {
            const Icon = provider.icon;
            const isSelected = provider.id === currentProvider;
            
            return (
              <button
                key={provider.id}
                className={`provider-option ${isSelected ? 'selected' : ''}`}
                onClick={() => handleProviderSelect(provider.id)}
                disabled={isSelected}
              >
                <Icon className="provider-option-icon" size={16} />
                <div className="provider-option-info">
                  <div className="provider-option-header">
                    <span className="provider-option-name">{provider.name}</span>
                    <span className={`provider-option-badge ${provider.id}`}>
                      {provider.badge}
                    </span>
                  </div>
                  <span className="provider-option-description">{provider.description}</span>
                </div>
                {isSelected && (
                  <div className="provider-option-checkmark"></div>
                )}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
};

export default ProviderDropdown;