File size: 4,452 Bytes
a95fdd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState, useEffect } from 'react';
import { Key, Eye, EyeOff, Save, Trash } from 'lucide-react';

export default function Settings() {
  const [apiKey, setApiKey] = useState('');
  const [showKey, setShowKey] = useState(false);
  const [status, setStatus] = useState<string | null>(null);

  useEffect(() => {
    const savedKey = localStorage.getItem('sandbox_gemini_api_key') || '';
    setApiKey(savedKey);
  }, []);

  const handleSave = () => {
    if (apiKey.trim()) {
      localStorage.setItem('sandbox_gemini_api_key', apiKey.trim());
      setStatus('API Key saved successfully!');
    } else {
      localStorage.removeItem('sandbox_gemini_api_key');
      setStatus('API Key cleared.');
    }
    setTimeout(() => setStatus(null), 3000);
  };

  const handleClear = () => {
    localStorage.removeItem('sandbox_gemini_api_key');
    setApiKey('');
    setStatus('API Key cleared.');
    setTimeout(() => setStatus(null), 3000);
  };

  return (
    <div className="w-full h-full bg-[#fdf8e1] p-6 flex flex-col gap-5 select-none font-sans text-ink-black overflow-y-auto custom-scrollbar">
      <div className="flex flex-col gap-2">
        <h3 className="font-headline-md font-bold text-sm m-0 flex items-center gap-2">
          <span className="material-symbols-outlined text-lg text-[#0ea5e9]">key</span>
          CUSTOM GEMINI API CONFIG
        </h3>
        <p className="text-[9px] text-trash-gray font-bold leading-normal m-0 uppercase font-arcade">
          Configure a custom Gemini API key for Sandbox Mode AI evaluations & explanations.
        </p>
      </div>

      <div className="bg-white border-[3px] border-ink-black p-4 shadow-[4px_4px_0px_0px_rgba(30,41,59,1)] flex flex-col gap-4">
        <div>
          <label className="block text-xs font-bold text-ink-black uppercase tracking-wider mb-2 font-headline-md">
            Gemini API Key
          </label>
          <div className="relative">
            <Key className="absolute left-3.5 top-1/2 -translate-y-1/2 w-4 h-4 text-ink-black" />
            <input
              type={showKey ? 'text' : 'password'}
              value={apiKey}
              onChange={(e) => setApiKey(e.target.value)}
              placeholder="AIzaSy..."
              className="w-full bg-white border-[3px] border-ink-black rounded-lg py-2.5 pl-10 pr-10 text-ink-black placeholder-trash-gray focus:outline-none focus:bg-white text-xs font-code-mono shadow-[inset_2px_2px_0px_rgba(0,0,0,0.1)]"
            />
            <button
              type="button"
              onClick={() => setShowKey(!showKey)}
              className="absolute right-3.5 top-1/2 -translate-y-1/2 text-trash-gray hover:text-ink-black cursor-pointer bg-transparent border-0 outline-none"
            >
              {showKey ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
            </button>
          </div>
          <span className="text-[9px] text-trash-gray mt-2 block font-medium leading-normal">
            Your key is stored locally in your browser's localStorage and is only sent to the local server in request headers.
          </span>
        </div>

        {status && (
          <div className="p-3 border-[3px] border-ink-black bg-emerald-100 border-emerald-500 text-emerald-700 text-xs font-bold font-arcade leading-relaxed shadow-[2px_2px_0px_0px_rgba(30,41,59,1)]">
            {status}
          </div>
        )}

        <div className="flex flex-col sm:flex-row gap-3 pt-2 border-t border-slate-200">
          <button
            onClick={handleSave}
            className="flex-1 flex items-center justify-center gap-2 py-2.5 border-[3px] border-ink-black bg-[#ffe24c] hover:bg-yellow-300 text-xs font-bold text-ink-black shadow-[3px_3px_0px_0px_#1E293B] active:translate-y-0.5 active:shadow-none transition-all cursor-pointer text-center uppercase"
          >
            <Save className="w-4 h-4" />
            Save Key
          </button>
          <button
            onClick={handleClear}
            className="flex-1 flex items-center justify-center gap-2 py-2.5 border-[3px] border-ink-black bg-white hover:bg-slate-100 text-xs font-bold text-ink-black shadow-[3px_3px_0px_0px_#1E293B] active:translate-y-0.5 active:shadow-none transition-all cursor-pointer text-center uppercase"
          >
            <Trash className="w-4 h-4 text-rose-500" />
            Clear Key
          </button>
        </div>
      </div>
    </div>
  );
}