Spaces:
Sleeping
Sleeping
Hackathon Builder
Add BYOK (Bring Your Own Key) feature, Tutorial screen, and fix Docker mv command
6a059ac Download frontend/src/ApiKeyModal.jsx from anil988/CodeBlue-Context: direct link, hf CLI and curl.
- Browser
- Download file 2.86 kB
-
https://huggingface.co/spaces/anil988/CodeBlue-Context/resolve/main/frontend/src/ApiKeyModal.jsx
- Command line
-
hf download hf://spaces/anil988/CodeBlue-Context/frontend/src/ApiKeyModal.jsx
-
curl -L -o ApiKeyModal.jsx https://huggingface.co/spaces/anil988/CodeBlue-Context/resolve/main/frontend/src/ApiKeyModal.jsx
2.86 kB
| import { useState, useEffect } from 'react'; | |
| import { Key, X, CheckCircle } from 'lucide-react'; | |
| export function ApiKeyModal({ onClose }) { | |
| const [key, setKey] = useState(''); | |
| const [saved, setSaved] = useState(false); | |
| useEffect(() => { | |
| const stored = localStorage.getItem('gemini_key'); | |
| if (stored) setKey(stored); | |
| }, []); | |
| const handleSave = () => { | |
| localStorage.setItem('gemini_key', key.trim()); | |
| setSaved(true); | |
| setTimeout(() => { | |
| setSaved(false); | |
| onClose(); | |
| }, 1500); | |
| }; | |
| const handleClear = () => { | |
| localStorage.removeItem('gemini_key'); | |
| setKey(''); | |
| }; | |
| return ( | |
| <div style={{ | |
| position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, | |
| background: 'rgba(6, 13, 26, 0.8)', backdropFilter: 'blur(8px)', | |
| display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 | |
| }}> | |
| <div className="card fade-up" style={{ width: 400, padding: 24, position: 'relative' }}> | |
| <button | |
| onClick={onClose} | |
| style={{ position: 'absolute', top: 16, right: 16, background: 'none', border: 'none', color: 'var(--text-tertiary)', cursor: 'pointer' }} | |
| > | |
| <X size={20} /> | |
| </button> | |
| <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}> | |
| <div style={{ padding: 10, background: 'rgba(191, 90, 242, 0.1)', borderRadius: 8, color: 'var(--purple-ai)' }}> | |
| <Key size={24} /> | |
| </div> | |
| <div> | |
| <h3 style={{ fontSize: 16, fontWeight: 700, margin: 0 }}>Provide Your Brain</h3> | |
| <p style={{ fontSize: 12, color: 'var(--text-secondary)', margin: '4px 0 0' }}>Bring Your Own Key (BYOK) to bypass server limits.</p> | |
| </div> | |
| </div> | |
| <p style={{ fontSize: 12, color: 'var(--text-tertiary)', marginBottom: 20, lineHeight: 1.5 }}> | |
| Our server's free-tier Gemini key might hit rate limits during high hackathon traffic. Paste your own Gemini 2.0 Flash API key here to guarantee lightning-fast performance. (Your key never leaves your browser). | |
| </p> | |
| <input | |
| type="password" | |
| value={key} | |
| onChange={e => setKey(e.target.value)} | |
| placeholder="AIzaSy..." | |
| className="input-dark" | |
| style={{ marginBottom: 16, padding: '12px' }} | |
| /> | |
| <div style={{ display: 'flex', gap: 10 }}> | |
| <button | |
| className="btn-primary" | |
| style={{ flex: 1, background: saved ? 'var(--green-safe)' : 'var(--purple-ai)' }} | |
| onClick={handleSave} | |
| > | |
| {saved ? <><CheckCircle size={16}/> Saved</> : 'Save API Key'} | |
| </button> | |
| {key && ( | |
| <button className="btn-ghost" onClick={handleClear}>Clear</button> | |
| )} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |