Spaces:
Running
Running
import React, { useState } from "react"; | |
import { ApiService } from "../utils/apiService"; | |
import { debugLog } from "../utils/config"; | |
const Step1 = ({ | |
apiKey, | |
setApiKey, | |
isApiKeyValid, | |
setIsApiKeyValid, | |
stepNumber, | |
stepTitle, | |
stepIcon, | |
enabled = true, | |
}) => { | |
const [isValidating, setIsValidating] = useState(false); | |
const [validationMessage, setValidationMessage] = useState(""); | |
// Helper function to validate API key format | |
const isValidApiKeyFormat = (key) => { | |
return key.startsWith("sync_"); | |
}; | |
const validateApiKey = async () => { | |
if (!isValidApiKeyFormat(apiKey)) { | |
setValidationMessage( | |
'API key must start with "sync_" and be at least 37 characters long' | |
); | |
setIsApiKeyValid(false); | |
return; | |
} | |
setIsValidating(true); | |
setValidationMessage(""); | |
try { | |
debugLog("Starting API key validation", { | |
apiKey: apiKey.substring(0, 8) + "...", | |
encrypted: "Key will be encrypted before transmission", | |
}); | |
const result = await ApiService.retryRequest(async () => { | |
return await ApiService.validateApiKey(apiKey); | |
}); | |
const isValid = result.success && result.data && result.data.isValid; | |
setIsApiKeyValid(isValid); | |
setValidationMessage( | |
isValid | |
? result.message || "API key validated successfully!" | |
: result.message || "Invalid API key" | |
); | |
debugLog("API key validation completed", { | |
valid: isValid, | |
response: result, | |
}); | |
} catch (error) { | |
debugLog("API key validation failed", error); | |
setValidationMessage( | |
error.message || "Validation failed. Please try again." | |
); | |
setIsApiKeyValid(false); | |
} finally { | |
setIsValidating(false); | |
} | |
}; | |
return ( | |
<div className="step-container fade-in"> | |
<div className="step-header"> | |
<h2> | |
<span className="step-number">{stepNumber}</span> | |
{stepIcon} {stepTitle} | |
</h2> | |
<p> | |
Enter your Hugging Face API key to get started with synthetic data | |
generation. Your key will be securely encrypted before validation. | |
</p> | |
</div> | |
<div className="step-body"> | |
<div className="form-group"> | |
<label htmlFor="apiKey">API Key</label> | |
<input | |
id="apiKey" | |
type="password" | |
className="form-input" | |
placeholder="sync_xxxxxxxxxxxxxxxxxxxxxxx" | |
value={apiKey} | |
onChange={(e) => setApiKey(e.target.value)} | |
disabled={isValidating} | |
/> | |
<small style={{ color: "var(--text-muted)", fontSize: "0.8rem" }}> | |
π‘ Your API key should start with "sync_" and will be encrypted | |
</small> | |
{apiKey && !isValidApiKeyFormat(apiKey) && ( | |
<div className="status-message error"> | |
<div className="status-message-icon">β οΈ</div> | |
<div className="status-message-content"> | |
Invalid format. API key must start with "sync_". | |
</div> | |
</div> | |
)} | |
</div> | |
<button | |
className="btn btn-primary" | |
onClick={validateApiKey} | |
disabled={!apiKey || isValidating} | |
> | |
{isValidating ? ( | |
<> | |
<div className="spinner spinner-small"></div> | |
Validating API Key... | |
</> | |
) : ( | |
<>π Validate API Key</> | |
)} | |
</button> | |
{validationMessage && ( | |
<div | |
className={`status-message ${isApiKeyValid ? "success" : "error"}`} | |
> | |
<div className="status-message-icon"> | |
{isApiKeyValid ? "β " : "β"} | |
</div> | |
<div className="status-message-content">{validationMessage}</div> | |
</div> | |
)} | |
</div> | |
</div> | |
); | |
}; | |
export default Step1; | |