import React, { useState, useRef } from "react"; import Papa from "papaparse"; import { ApiService } from "../utils/apiService"; import { config, debugLog } from "../utils/config"; const Step2 = ({ uploadedFile, setUploadedFile, s3Link, setS3Link, fileMetadata, setFileMetadata, stepNumber, stepTitle, stepIcon, enabled = true, // Add API key props for validation apiKey, isApiKeyValid, }) => { const [outputFormat, setOutputFormat] = useState("tabular"); const [isUploading, setIsUploading] = useState(false); const [csvData, setCsvData] = useState(null); const [dragOver, setDragOver] = useState(false); const fileInputRef = useRef(null); const handleFileUpload = async (file) => { // Prevent action if step is disabled if (!enabled) { debugLog("File upload attempted but step is disabled"); return; } if (!file) { alert("No file selected"); return; } if (!file.name.endsWith(".csv")) { alert("Please upload a CSV file. Only CSV files are supported."); return; } // Check file size against configured limit const maxSizeBytes = config.maxFileSizeMB * 1024 * 1024; if (file.size > maxSizeBytes) { alert( `File size (${(file.size / 1024 / 1024).toFixed( 2 )}MB) exceeds maximum allowed size of ${config.maxFileSizeMB}MB` ); return; } // Check if file is empty if (file.size === 0) { alert( "The selected file is empty. Please choose a valid CSV file with data." ); return; } setUploadedFile(file); debugLog("File selected for upload", { name: file.name, size: file.size, type: file.type, }); // Initialize file metadata with file size setFileMetadata({ fileSizeBytes: file.size, sourceFileRows: 0, // Will be updated after CSV parsing }); // Parse CSV for preview Papa.parse(file, { complete: (results) => { if (results.errors && results.errors.length > 0) { debugLog("CSV parsing warnings", results.errors); } if (!results.data || results.data.length === 0) { alert( "The CSV file appears to be empty or invalid. Please check your file and try again." ); setUploadedFile(null); setFileMetadata({ fileSizeBytes: 0, sourceFileRows: 0 }); return; } setCsvData(results.data); // Update file metadata with row count setFileMetadata({ fileSizeBytes: file.size, sourceFileRows: results.data.length, }); debugLog("CSV parsed for preview", { rows: results.data.length, columns: results.data[0] ? Object.keys(results.data[0]).length : 0, }); }, header: true, skipEmptyLines: true, error: (error) => { debugLog("CSV parsing error", error); alert("Error parsing CSV file. Please ensure it's a valid CSV format."); setUploadedFile(null); }, }); // Upload to S3 using ApiService setIsUploading(true); try { debugLog("Starting file upload to S3"); // Use the ApiService with retry logic const result = await ApiService.retryRequest(async () => { return await ApiService.uploadFileToS3(file); }); // Handle different response structures const s3Url = result.s3_link || result.link || result.publicUrl || result.url; setS3Link(s3Url); debugLog("File uploaded successfully", { s3Link: s3Url, result: result, }); } catch (error) { debugLog("File upload failed", error); // More specific error messages let errorMessage = "Failed to upload file. Please try again."; if (error.message.includes("credentials")) { errorMessage = "AWS credentials are not configured properly. Please check your .env.local file and restart the application."; } else if (error.message.includes("bucket")) { errorMessage = "Storage bucket configuration issue. Please check your S3 bucket name in .env.local file."; } else if (error.message.includes("size")) { errorMessage = `File size exceeds the maximum limit of ${config.maxFileSizeMB}MB.`; } else if ( error.message.includes("network") || error.message.includes("fetch") || error.message.includes("CORS") ) { errorMessage = "Network/CORS error. This might be due to S3 bucket CORS configuration or network connectivity issues."; } else if (error.message.includes("AccessDenied")) { errorMessage = "Access denied to S3 bucket. Please check your AWS permissions."; } alert(errorMessage); setUploadedFile(null); setCsvData(null); } finally { setIsUploading(false); } }; const handleDrop = (e) => { // Prevent action if step is disabled if (!enabled) return; e.preventDefault(); setDragOver(false); const files = e.dataTransfer.files; if (files.length > 0) { handleFileUpload(files[0]); } }; const handleDragOver = (e) => { e.preventDefault(); setDragOver(true); }; const handleDragLeave = (e) => { e.preventDefault(); setDragOver(false); }; const renderDataPreview = () => { if (!csvData || csvData.length === 0) return null; // Show more rows for better preview (up to 20 rows) const previewData = csvData.slice(0, 20); const columns = Object.keys(previewData[0]); return (
{col} | ))}
---|
{row[col]} | ))}
Showing first 20 rows of {csvData.length} total rows
)}Choose your output format and upload a CSV file for analysis and synthetic data generation.
Please complete Step 1 (API Key Validation) before uploading files.
CSV format with structured rows and columns
JSON Lines format for advanced use cases
Successfully uploaded and ready for processing
Size: {(uploadedFile.size / 1024 / 1024).toFixed(2)} MB