Girish Jeswani commited on
Commit
a3976c3
·
1 Parent(s): 9af2387

llm dropdown

Browse files
phd-advisor-frontend/src/components/ProviderDropdown.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // src/components/ProviderDropdown.js
2
+ import React, { useState, useRef, useEffect } from 'react';
3
+ import { ChevronDown, Cpu, Cloud, Loader2 } from 'lucide-react';
4
+ import { useTheme } from '../contexts/ThemeContext';
5
+
6
+ const ProviderDropdown = ({ currentProvider, onProviderChange, isLoading = false }) => {
7
+ const [isOpen, setIsOpen] = useState(false);
8
+ const dropdownRef = useRef(null);
9
+ const { isDark } = useTheme();
10
+
11
+ const providers = [
12
+ {
13
+ id: 'gemini',
14
+ name: 'Gemini',
15
+ description: 'Google\'s Gemini AI',
16
+ icon: Cloud,
17
+ badge: 'Cloud'
18
+ },
19
+ {
20
+ id: 'ollama',
21
+ name: 'Ollama',
22
+ description: 'Local LLM via Ollama',
23
+ icon: Cpu,
24
+ badge: 'Local'
25
+ }
26
+ ];
27
+
28
+ const currentProviderInfo = providers.find(p => p.id === currentProvider);
29
+
30
+ // Close dropdown when clicking outside
31
+ useEffect(() => {
32
+ const handleClickOutside = (event) => {
33
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
34
+ setIsOpen(false);
35
+ }
36
+ };
37
+
38
+ document.addEventListener('mousedown', handleClickOutside);
39
+ return () => {
40
+ document.removeEventListener('mousedown', handleClickOutside);
41
+ };
42
+ }, []);
43
+
44
+ const handleProviderSelect = (providerId) => {
45
+ if (providerId !== currentProvider && !isLoading) {
46
+ onProviderChange(providerId);
47
+ setIsOpen(false);
48
+ }
49
+ };
50
+
51
+ const toggleDropdown = () => {
52
+ if (!isLoading) {
53
+ setIsOpen(!isOpen);
54
+ }
55
+ };
56
+
57
+ return (
58
+ <div className="provider-dropdown" ref={dropdownRef}>
59
+ <button
60
+ className={`provider-button ${isOpen ? 'open' : ''} ${isLoading ? 'loading' : ''}`}
61
+ onClick={toggleDropdown}
62
+ disabled={isLoading}
63
+ >
64
+ <div className="provider-button-content">
65
+ {isLoading ? (
66
+ <Loader2 className="provider-icon spinning" size={16} />
67
+ ) : (
68
+ <currentProviderInfo.icon className="provider-icon" size={16} />
69
+ )}
70
+ <div className="provider-info">
71
+ <span className="provider-name">{currentProviderInfo?.name || 'Unknown'}</span>
72
+ <span className="provider-badge">{currentProviderInfo?.badge}</span>
73
+ </div>
74
+ </div>
75
+ <ChevronDown
76
+ className={`dropdown-arrow ${isOpen ? 'rotated' : ''}`}
77
+ size={16}
78
+ />
79
+ </button>
80
+
81
+ {isOpen && (
82
+ <div className="provider-dropdown-menu">
83
+ {providers.map((provider) => {
84
+ const Icon = provider.icon;
85
+ const isSelected = provider.id === currentProvider;
86
+
87
+ return (
88
+ <button
89
+ key={provider.id}
90
+ className={`provider-option ${isSelected ? 'selected' : ''}`}
91
+ onClick={() => handleProviderSelect(provider.id)}
92
+ disabled={isSelected}
93
+ >
94
+ <Icon className="provider-option-icon" size={16} />
95
+ <div className="provider-option-info">
96
+ <div className="provider-option-header">
97
+ <span className="provider-option-name">{provider.name}</span>
98
+ <span className={`provider-option-badge ${provider.id}`}>
99
+ {provider.badge}
100
+ </span>
101
+ </div>
102
+ <span className="provider-option-description">{provider.description}</span>
103
+ </div>
104
+ {isSelected && (
105
+ <div className="provider-option-checkmark">✓</div>
106
+ )}
107
+ </button>
108
+ );
109
+ })}
110
+ </div>
111
+ )}
112
+ </div>
113
+ );
114
+ };
115
+
116
+ export default ProviderDropdown;