Spaces:
Running
Running
File size: 3,951 Bytes
56bf851 |
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
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;
|