Spaces:
Running
Running
| import React, { useState } from 'react'; | |
| import { Key, FolderGit2, CheckCircle2, AlertCircle, Database, Box, Layout } from 'lucide-react'; | |
| import { HFConfig, RepoType } from '../types'; | |
| interface ConfigPanelProps { | |
| config: HFConfig; | |
| onConfigChange: (newConfig: HFConfig) => void; | |
| } | |
| export const ConfigPanel: React.FC<ConfigPanelProps> = ({ config, onConfigChange }) => { | |
| const [showToken, setShowToken] = useState(false); | |
| const handleTokenChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
| onConfigChange({ ...config, token: e.target.value }); | |
| }; | |
| const handleRepoChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
| onConfigChange({ ...config, repo: e.target.value }); | |
| }; | |
| const handleTypeChange = (type: RepoType) => { | |
| onConfigChange({ ...config, repoType: type }); | |
| }; | |
| const isValid = config.token.length > 0 && config.repo.includes('/'); | |
| return ( | |
| <div className="bg-white p-6 rounded-xl shadow-sm border border-gray-100"> | |
| <h2 className="text-xl font-semibold mb-4 text-gray-800 flex items-center gap-2"> | |
| <Key className="w-5 h-5 text-yellow-500" /> | |
| Authentication & Target | |
| </h2> | |
| <div className="space-y-5"> | |
| {/* Repo Type Selector */} | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-2"> | |
| Repository Type | |
| </label> | |
| <div className="flex bg-gray-100 p-1 rounded-lg"> | |
| <button | |
| onClick={() => handleTypeChange('model')} | |
| className={`flex-1 flex items-center justify-center gap-2 py-2 text-sm font-medium rounded-md transition-all ${ | |
| config.repoType === 'model' | |
| ? 'bg-white text-gray-900 shadow-sm' | |
| : 'text-gray-500 hover:text-gray-700' | |
| }`} | |
| > | |
| <Box className="w-4 h-4" /> | |
| Model | |
| </button> | |
| <button | |
| onClick={() => handleTypeChange('dataset')} | |
| className={`flex-1 flex items-center justify-center gap-2 py-2 text-sm font-medium rounded-md transition-all ${ | |
| config.repoType === 'dataset' | |
| ? 'bg-white text-red-600 shadow-sm' | |
| : 'text-gray-500 hover:text-gray-700' | |
| }`} | |
| > | |
| <Database className="w-4 h-4" /> | |
| Dataset | |
| </button> | |
| <button | |
| onClick={() => handleTypeChange('space')} | |
| className={`flex-1 flex items-center justify-center gap-2 py-2 text-sm font-medium rounded-md transition-all ${ | |
| config.repoType === 'space' | |
| ? 'bg-white text-blue-600 shadow-sm' | |
| : 'text-gray-500 hover:text-gray-700' | |
| }`} | |
| > | |
| <Layout className="w-4 h-4" /> | |
| Space | |
| </button> | |
| </div> | |
| </div> | |
| {/* Token Input */} | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-1"> | |
| Hugging Face Access Token (Write) | |
| </label> | |
| <div className="relative"> | |
| <input | |
| type={showToken ? "text" : "password"} | |
| value={config.token} | |
| onChange={handleTokenChange} | |
| placeholder="hf_..." | |
| className="w-full pl-10 pr-12 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 focus:border-transparent outline-none transition-all" | |
| /> | |
| <Key className="absolute left-3 top-2.5 w-4 h-4 text-gray-400" /> | |
| <button | |
| type="button" | |
| onClick={() => setShowToken(!showToken)} | |
| className="absolute right-3 top-2.5 text-xs font-semibold text-gray-500 hover:text-gray-700" | |
| > | |
| {showToken ? "HIDE" : "SHOW"} | |
| </button> | |
| </div> | |
| <p className="mt-1 text-xs text-gray-500"> | |
| Get your token from <a href="https://huggingface.co/settings/tokens" target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:underline">HF Settings</a>. Ensure it has <strong>WRITE</strong> permissions. | |
| </p> | |
| </div> | |
| {/* Repo Input */} | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-1"> | |
| Repository ID | |
| </label> | |
| <div className="relative"> | |
| <input | |
| type="text" | |
| value={config.repo} | |
| onChange={handleRepoChange} | |
| placeholder={config.repoType === 'space' ? "username/space-name" : (config.repoType === 'dataset' ? "username/dataset-name" : "username/model-name")} | |
| className="w-full pl-10 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-yellow-400 focus:border-transparent outline-none transition-all" | |
| /> | |
| <FolderGit2 className="absolute left-3 top-2.5 w-4 h-4 text-gray-400" /> | |
| </div> | |
| <p className="mt-1 text-xs text-gray-500"> | |
| Targeting: <span className="font-semibold capitalize">{config.repoType}</span>. Example: <code>jdoe/my-{config.repoType}</code> | |
| </p> | |
| </div> | |
| <div className={`flex items-center gap-2 text-sm p-3 rounded-lg ${isValid ? 'bg-green-50 text-green-700 border border-green-100' : 'bg-gray-50 text-gray-500 border border-gray-200'}`}> | |
| {isValid ? <CheckCircle2 className="w-4 h-4" /> : <AlertCircle className="w-4 h-4" />} | |
| {isValid ? `Ready to upload to ${config.repoType}` : "Enter a valid token and repo ID to start."} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| }; | |