Spaces:
Running
Running
File size: 5,998 Bytes
56bf851 adeec93 56bf851 adeec93 56bf851 adeec93 56bf851 adeec93 |
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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
import React, { useState, useEffect } from "react";
import "./App.css";
import Step1 from "./components/Step1";
import Step2 from "./components/Step2";
import Step3 from "./components/Step3";
import Step4 from "./components/Step4";
import { config as appConfig, debugLog } from "./utils/config";
import { ApiService } from "./utils/apiService";
// Make ApiService available globally for debugging
if (process.env.NODE_ENV === "development") {
window.ApiService = ApiService;
}
function App() {
const [apiKey, setApiKey] = useState("");
const [isApiKeyValid, setIsApiKeyValid] = useState(false); // Explicitly initialized to false
const [uploadedFile, setUploadedFile] = useState(null);
const [s3Link, setS3Link] = useState("");
const [fileMetadata, setFileMetadata] = useState({
fileSizeBytes: 0,
sourceFileRows: 0,
});
const [config, setConfig] = useState({
numRows: appConfig.defaultNumRecords,
targetColumn: "",
});
const [generatedDataLink, setGeneratedDataLink] = useState("");
// Check for previously stored and valid API key on app load
useEffect(() => {
const checkStoredApiKey = async () => {
try {
debugLog("Checking for stored API key on app initialization");
const storedKeyStatus = await ApiService.verifyStoredApiKey();
if (storedKeyStatus.valid) {
setIsApiKeyValid(true);
debugLog("Valid stored API key found", storedKeyStatus);
} else {
setIsApiKeyValid(false);
debugLog("No valid stored API key", storedKeyStatus);
}
} catch (error) {
debugLog("Error checking stored API key", error);
setIsApiKeyValid(false);
}
};
checkStoredApiKey();
}, []);
// Log app initialization in debug mode
useEffect(() => {
debugLog("Syncora app initialized", {
defaultNumRecords: appConfig.defaultNumRecords,
maxFileSizeMB: appConfig.maxFileSizeMB,
apiBaseUrl: appConfig.apiBaseUrl,
});
}, []);
const steps = [
{ number: 1, title: "API Key Validation", component: Step1, icon: "π" },
{ number: 2, title: "Upload Files", component: Step2, icon: "π" },
{ number: 3, title: "Configuration", component: Step3, icon: "βοΈ" },
{ number: 4, title: "Generate Data", component: Step4, icon: "π" },
];
// Helper function to check if a step should be enabled
const isStepEnabled = (stepNumber) => {
switch (stepNumber) {
case 1:
return true; // Step 1 is always enabled
case 2:
const step2Enabled = isApiKeyValid;
debugLog(`Step 2 enabled check: ${step2Enabled}`, {
isApiKeyValid,
apiKeyLength: apiKey.length,
hasApiKey: !!apiKey,
});
return step2Enabled; // Step 2 enabled when API key is valid
case 3:
return isApiKeyValid && uploadedFile && s3Link; // Step 3 enabled when file is uploaded
case 4:
return isApiKeyValid && uploadedFile && s3Link && config.targetColumn; // Step 4 enabled when config is complete
default:
return false;
}
};
const renderStep = (stepNumber) => {
const step = steps[stepNumber - 1];
const StepComponent = step.component;
const enabled = isStepEnabled(stepNumber);
return (
<div className={`step-wrapper ${enabled ? "enabled" : "disabled"}`}>
<StepComponent
apiKey={apiKey}
setApiKey={setApiKey}
isApiKeyValid={isApiKeyValid}
setIsApiKeyValid={setIsApiKeyValid}
uploadedFile={uploadedFile}
setUploadedFile={setUploadedFile}
s3Link={s3Link}
setS3Link={setS3Link}
fileMetadata={fileMetadata}
setFileMetadata={setFileMetadata}
config={config}
setConfig={setConfig}
generatedDataLink={generatedDataLink}
setGeneratedDataLink={setGeneratedDataLink}
stepNumber={stepNumber}
stepTitle={step.title}
stepIcon={step.icon}
enabled={enabled}
/>
</div>
);
};
return (
<div className="App">
<header className="app-header">
<div className="header-content">
<div>
<h1>Syncora</h1>
<p>AI-Powered Data Generation Platform</p>
</div>
<div className="progress-indicator">
{steps.map((step, index) => {
const stepNumber = step.number;
const isEnabled = isStepEnabled(stepNumber);
const isCompleted =
stepNumber < steps.length
? isStepEnabled(stepNumber + 1)
: stepNumber === 4 && generatedDataLink;
return (
<div
key={step.number}
className={`progress-step ${
isCompleted
? "completed"
: isEnabled
? "active"
: "disabled"
}`}
title={`Step ${step.number}: ${step.title}`}
/>
);
})}
</div>
</div>
</header>
<div className="main-container">
{/* Left Column */}
<div className="steps-column">
{/* Step 1 */}
<div className="step-content">{renderStep(1)}</div>
{/* Step 2 */}
<div className="step-content">{renderStep(2)}</div>
</div>
{/* Right Column */}
<div className="steps-column">
{/* Step 3 */}
<div className="step-content">{renderStep(3)}</div>
{/* Step 4 */}
<div className="step-content">{renderStep(4)}</div>
</div>
</div>
{/* Floating Help Button */}
<button
className="floating-help"
onClick={() => window.open("https://docs.syncora.ai/help", "_blank")}
title="Get Help"
>
?
</button>
</div>
);
}
export default App;
|