Spaces:
Running
Running
| import React, { useState, useEffect } from "react"; | |
| import Papa from "papaparse"; | |
| import { config as envConfig, debugLog } from "../utils/config"; | |
| const Step3 = ({ | |
| uploadedFile, | |
| fileMetadata, | |
| config, | |
| setConfig, | |
| stepNumber, | |
| stepTitle, | |
| stepIcon, | |
| enabled = true, | |
| // Add validation props | |
| apiKey, | |
| isApiKeyValid, | |
| s3Link, | |
| }) => { | |
| const [columns, setColumns] = useState([]); | |
| useEffect(() => { | |
| if (uploadedFile) { | |
| debugLog("Parsing uploaded file for columns", { | |
| fileName: uploadedFile.name, | |
| }); | |
| // Parse the uploaded file to get column names | |
| Papa.parse(uploadedFile, { | |
| complete: (results) => { | |
| if (results.data.length > 0) { | |
| const headers = Object.keys(results.data[0]); | |
| setColumns(headers); | |
| debugLog("Columns extracted from file", { columns: headers }); | |
| // Set first column as default target if not already set | |
| if (!config.targetColumn && headers.length > 0) { | |
| setConfig((prev) => ({ | |
| ...prev, | |
| targetColumn: headers[0], | |
| fileSizeBytes: fileMetadata?.fileSizeBytes || 0, | |
| sourceFileRows: fileMetadata?.sourceFileRows || 0, | |
| })); | |
| } | |
| // Set default number of rows from environment config if not already set | |
| if (!config.numRows || config.numRows === 100) { | |
| setConfig((prev) => ({ | |
| ...prev, | |
| numRows: envConfig.defaultNumRecords, | |
| fileSizeBytes: fileMetadata?.fileSizeBytes || 0, | |
| sourceFileRows: fileMetadata?.sourceFileRows || 0, | |
| })); | |
| debugLog("Set default number of rows", { | |
| numRows: envConfig.defaultNumRecords, | |
| }); | |
| } | |
| } | |
| }, | |
| header: true, | |
| skipEmptyLines: true, | |
| }); | |
| } | |
| }, [ | |
| uploadedFile, | |
| config.targetColumn, | |
| config.numRows, | |
| setConfig, | |
| fileMetadata?.fileSizeBytes, | |
| fileMetadata?.sourceFileRows, | |
| ]); | |
| const handleNumRowsChange = (e) => { | |
| // Prevent action if step is disabled | |
| if (!enabled) return; | |
| const numRows = parseInt(e.target.value, 10); | |
| debugLog("Number of rows changed", { numRows }); | |
| setConfig((prev) => ({ | |
| ...prev, | |
| numRows: numRows, | |
| fileSizeBytes: fileMetadata?.fileSizeBytes || 0, | |
| sourceFileRows: fileMetadata?.sourceFileRows || 0, | |
| })); | |
| }; | |
| const handleTargetColumnChange = (e) => { | |
| // Prevent action if step is disabled | |
| if (!enabled) return; | |
| const targetColumn = e.target.value; | |
| debugLog("Target column changed", { targetColumn }); | |
| setConfig((prev) => ({ | |
| ...prev, | |
| targetColumn: targetColumn, | |
| fileSizeBytes: fileMetadata?.fileSizeBytes || 0, | |
| sourceFileRows: fileMetadata?.sourceFileRows || 0, | |
| })); | |
| }; | |
| return ( | |
| <div className="step-container fade-in"> | |
| <div className="step-header"> | |
| <h2> | |
| <span className="step-number">{stepNumber}</span> | |
| {stepIcon} {stepTitle} | |
| </h2> | |
| <p> | |
| Configure the parameters for your synthetic data generation process | |
| </p> | |
| </div> | |
| <div className="step-body"> | |
| <div className="config-section"> | |
| <h3> | |
| <span className="config-icon">π</span> | |
| Data Generation Settings | |
| </h3> | |
| <div className="form-group"> | |
| <label htmlFor="numRows">Number of Rows to Generate</label> | |
| <div className="slider-container"> | |
| <input | |
| id="numRows" | |
| type="range" | |
| min="10" | |
| max="1000" | |
| step="10" | |
| value={config.numRows} | |
| onChange={handleNumRowsChange} | |
| className="slider" | |
| disabled={false} | |
| /> | |
| <div className="slider-value">{config.numRows} rows</div> | |
| </div> | |
| </div> | |
| <div className="form-group"> | |
| <label htmlFor="targetColumn">Target Column</label> | |
| <select | |
| id="targetColumn" | |
| className="form-input" | |
| value={config.targetColumn} | |
| onChange={handleTargetColumnChange} | |
| disabled={columns.length === 0} | |
| > | |
| <option value="">Select a target column...</option> | |
| {columns.map((column, index) => ( | |
| <option key={index} value={column}> | |
| {column} | |
| </option> | |
| ))} | |
| </select> | |
| </div> | |
| </div> | |
| {columns.length > 0 && ( | |
| <div className="config-section"> | |
| <h3> | |
| <span className="config-icon">π</span> | |
| Available Columns ({columns.length}) | |
| </h3> | |
| <div | |
| style={{ | |
| display: "flex", | |
| flexWrap: "wrap", | |
| gap: "0.5rem", | |
| marginTop: "1rem", | |
| }} | |
| > | |
| {columns.map((column, index) => ( | |
| <span | |
| key={index} | |
| style={{ | |
| background: | |
| config.targetColumn === column | |
| ? "var(--primary-color)" | |
| : "var(--bg-tertiary)", | |
| color: | |
| config.targetColumn === column | |
| ? "white" | |
| : "var(--text-secondary)", | |
| padding: "0.5rem 0.75rem", | |
| borderRadius: "6px", | |
| fontSize: "0.8rem", | |
| fontWeight: "500", | |
| border: | |
| config.targetColumn === column | |
| ? "none" | |
| : "1px solid var(--border-color)", | |
| }} | |
| > | |
| {column} | |
| </span> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default Step3; | |