diff --git a/.gitignore b/.gitignore
index e427ff3..5147d85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
node_modules/
*/node_modules/
*/build/
+/.env
diff --git a/api.php b/api.php
new file mode 100644
index 0000000..4c3d1a2
--- /dev/null
+++ b/api.php
@@ -0,0 +1,177 @@
+ 'OpenAI API key not configured.'];
+ }
+
+ $prompt = "I have two CSV files. I want to convert the input file to the output file format.\n\n";
+ $prompt .= "Here is a sample of the input CSV file:\n---\n" . $inputSample . "\n---\n\n";
+ $prompt .= "Here is a sample of the output CSV file:\n---\n" . $outputSample . "\n---\n\n";
+ $prompt .= "Please generate a PHP script that contains a single function `convert_csv($input_file_path, $output_file_path)`.\n";
+ $prompt .= "This function should read the data from the `$input_file_path`, transform it into the format of the output sample, and write the result to `$output_file_path`.\n";
+ $prompt .= "The script should handle CSV headers correctly. Do not include any explanations, just the raw PHP code starting with ` 'gpt-5',
+ 'messages' => [
+ [
+ 'role' => 'user',
+ 'content' => $prompt
+ ]
+ ]
+ ];
+
+ $ch = curl_init('https://api.openai.com/v1/chat/completions');
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
+ 'Content-Type: application/json',
+ 'Authorization: Bearer ' . $apiKey
+ ]);
+
+ $response = curl_exec($ch);
+ $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ curl_close($ch);
+
+ if ($httpcode != 200) {
+ return ['error' => 'Failed to connect to OpenAI API. Response: ' . $response];
+ }
+
+ $result = json_decode($response, true);
+
+ if (isset($result['choices'][0]['message']['content'])) {
+ $php_code = $result['choices'][0]['message']['content'];
+ // Clean up the response to get only the code
+ if (strpos($php_code, '```php') !== false) {
+ $php_code = substr($php_code, strpos($php_code, '```php') + 5);
+ $php_code = substr($php_code, 0, strrpos($php_code, '```'));
+ }
+ if (strpos($php_code, ' true, 'code' => $php_code];
+ }
+
+ return ['error' => 'Could not extract PHP code from OpenAI response.', 'details' => $result];
+}
+
+load_env(__DIR__ . '/.env');
+$action = $_POST['action'] ?? $_GET['action'] ?? '';
+
+if ($action === 'build_mapping') {
+ if (!isset($_FILES['inputSample']) || !isset($_FILES['outputSample'])) {
+ echo json_encode(['success' => false, 'error' => 'Input and output sample files are required.']);
+ exit;
+ }
+
+ $inputTmpPath = $_FILES['inputSample']['tmp_name'];
+ $outputTmpPath = $_FILES['outputSample']['tmp_name'];
+
+ $inputSampleContent = get_csv_sample($inputTmpPath);
+ $outputSampleContent = get_csv_sample($outputTmpPath);
+
+ if ($inputSampleContent === null || $outputSampleContent === null) {
+ echo json_encode(['success' => false, 'error' => 'Failed to read sample files.']);
+ exit;
+ }
+
+ $result = call_openai_api($inputSampleContent, $outputSampleContent);
+
+ if (isset($result['error'])) {
+ echo json_encode(['success' => false, 'error' => $result['error'], 'details' => $result['details'] ?? null]);
+ exit;
+ }
+
+ $mappingDir = __DIR__ . '/mappings';
+ if (!is_dir($mappingDir)) {
+ mkdir($mappingDir, 0775, true);
+ }
+ $mappingFile = 'mappings/mapping_' . time() . '.php';
+ file_put_contents($mappingFile, $result['code']);
+
+ echo json_encode(['success' => true, 'mapping_file' => $mappingFile]);
+ exit;
+}
+
+if ($action === 'convert') {
+ if (!isset($_FILES['fullInputFile']) || !isset($_POST['mappingFile'])) {
+ echo json_encode(['success' => false, 'error' => 'Input file and mapping file are required.']);
+ exit;
+ }
+
+ $mappingFile = $_POST['mappingFile'];
+ if (!file_exists($mappingFile)) {
+ echo json_encode(['success' => false, 'error' => 'Mapping file not found.']);
+ exit;
+ }
+
+ require_once $mappingFile;
+
+ if (!function_exists('convert_csv')) {
+ echo json_encode(['success' => false, 'error' => 'Invalid mapping file: convert_csv function not found.']);
+ exit;
+ }
+
+ $inputTmpPath = $_FILES['fullInputFile']['tmp_name'];
+ $outputDir = __DIR__ . '/outputs';
+ if (!is_dir($outputDir)) {
+ mkdir($outputDir, 0775, true);
+ }
+ $outputFile = $outputDir . '/converted_' . time() . '.csv';
+
+ try {
+ convert_csv($inputTmpPath, $outputFile);
+ echo json_encode(['success' => true, 'download_url' => basename($outputFile)]);
+ } catch (Exception $e) {
+ echo json_encode(['success' => false, 'error' => 'Error during conversion: ' . $e->getMessage()]);
+ }
+ exit;
+}
+
+
+echo json_encode(['success' => false, 'error' => 'No action specified.']);
\ No newline at end of file
diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..19816b6
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,53 @@
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ background-color: #f8f9fa;
+ color: #333;
+}
+
+.container {
+ max-width: 960px;
+}
+
+.card {
+ border: none;
+ border-radius: 0.75rem;
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
+ transition: transform 0.2s ease-in-out;
+}
+
+.card:hover {
+ transform: translateY(-5px);
+}
+
+.card-title {
+ font-weight: 600;
+}
+
+.btn {
+ border-radius: 0.5rem;
+ padding: 0.75rem 1.25rem;
+ font-weight: 600;
+ transition: all 0.2s ease-in-out;
+}
+
+.btn-primary {
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+
+.btn-primary:hover {
+ background-color: #0b5ed7;
+ border-color: #0a58ca;
+}
+
+.form-control {
+ border-radius: 0.5rem;
+}
+
+header {
+ border-bottom: 1px solid #e9ecef;
+}
+
+footer {
+ border-top: 1px solid #e9ecef;
+}
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..ad989d5
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,94 @@
+document.addEventListener('DOMContentLoaded', function () {
+ const mappingForm = document.getElementById('mappingForm');
+ const convertForm = document.getElementById('convertForm');
+
+ const inputSample = document.getElementById('inputSample');
+ const outputSample = document.getElementById('outputSample');
+ const buildMappingBtn = document.getElementById('buildMappingBtn');
+
+ const fullInputFile = document.getElementById('fullInputFile');
+ const convertBtn = document.getElementById('convertBtn');
+
+ const convertSection = document.getElementById('convertSection');
+ const convertResult = document.getElementById('convertResult');
+ const mappingFileInput = document.getElementById('mappingFile');
+
+ function checkMappingFiles() {
+ buildMappingBtn.disabled = !(inputSample.files.length > 0 && outputSample.files.length > 0);
+ }
+
+ function checkConvertFile() {
+ convertBtn.disabled = !(fullInputFile.files.length > 0);
+ }
+
+ inputSample.addEventListener('change', checkMappingFiles);
+ outputSample.addEventListener('change', checkMappingFiles);
+ fullInputFile.addEventListener('change', checkConvertFile);
+
+ mappingForm.addEventListener('submit', function (e) {
+ e.preventDefault();
+ buildMappingBtn.disabled = true;
+ buildMappingBtn.innerHTML = ' Building...';
+
+ const formData = new FormData(this);
+ formData.append('action', 'build_mapping');
+
+ fetch('api.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ if (data.success) {
+ alert('Mapping built successfully!');
+ mappingFileInput.value = data.mapping_file;
+ convertSection.classList.remove('d-none');
+ } else {
+ let errorMsg = 'Error building mapping: ' + data.error;
+ if(data.details) {
+ errorMsg += '\nDetails: ' + JSON.stringify(data.details);
+ }
+ alert(errorMsg);
+ }
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ alert('An error occurred while building the mapping.');
+ })
+ .finally(() => {
+ buildMappingBtn.disabled = false;
+ buildMappingBtn.innerHTML = 'Build Mapping';
+ });
+ });
+
+ convertForm.addEventListener('submit', function (e) {
+ e.preventDefault();
+ convertBtn.disabled = true;
+ convertBtn.innerHTML = ' Converting...';
+ convertResult.innerHTML = '';
+
+ const formData = new FormData(this);
+ formData.append('action', 'convert');
+
+ fetch('api.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ if (data.success) {
+ convertResult.innerHTML = `
`;
+ } else {
+ convertResult.innerHTML = `Error: ${data.error}
`;
+ }
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ convertResult.innerHTML = `An unexpected error occurred.
`;
+ })
+ .finally(() => {
+ convertBtn.disabled = false;
+ convertBtn.innerHTML = 'Convert';
+ });
+ });
+});
\ No newline at end of file
diff --git a/converter.py b/converter.py
new file mode 100644
index 0000000..9630dc0
--- /dev/null
+++ b/converter.py
@@ -0,0 +1 @@
+# This is a placeholder for the Python converter script.
\ No newline at end of file
diff --git a/index.php b/index.php
index 7205f3d..97524a7 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,95 @@
-
-
+
-
-
- New Style
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Data Mapping Tool
+
+
+
+
+
+
+
+
+
+
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
+
+
+
+
+
+
+
+
1Build Mapping
+
Provide input and output sample files (CSV or XLSX) to generate a mapping configuration using AI.
+
+
+
+
+
+
+
+
2Convert Data
+
Use the generated mapping to convert your full input file.
+
+
+
+
+
+
+
+
+
+
+
+
-
+