The complete code of  App.jsx, CodeEditor.jsx and Preview.jsx files for my generate and preview react apps is as follows. The code generation is flawless but the preview is not working despite trying various methods. I am also providing the vite.config file. Pls look into it:

import React, { useState } from 'react';
import axios from 'axios';
import CodeEditor from './components/CodeEditor';
import Preview from './components/Preview';
import './App.scss';

// Configure axios instance
const api = axios.create({
  baseURL: 'http://localhost:5000',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Initial code template
const initialCode = `import React from 'react';

function App() {
  return (
    <div>
      <h1>Hello, World!</h1>
    </div>
  );
}

export default App;`.trim();

function App() {
  const [code, setCode] = useState(initialCode);
  const [prompt, setPrompt] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  const handleCodeChange = (newValue) => {
    if (typeof newValue === 'string') {
      // Ensure proper React imports and exports
      let processedCode = newValue.trim();
      if (!processedCode.includes('import React')) {
        processedCode = `import React from 'react';\n\n${processedCode}`;
      }
      if (!processedCode.includes('export default App')) {
        processedCode = `${processedCode}\n\nexport default App;`;
      }
      setCode(processedCode);
      setError(null);
    }
  };

  const handlePromptChange = (e) => {
    setPrompt(e.target.value);
    setError(null);
  };

  const generateCode = async () => {
    if (!prompt.trim()) {
      setError('Please enter a prompt');
      return;
    }

    try {
      setIsLoading(true);
      setError(null);

      const response = await api.post('/generateCode', {
        prompt: `Create a React component that ${prompt.trim()}. The component should be named App and must include 'import React from "react"' at the start and 'export default App' at the end. Return only the code without any explanation.`,
      });

      console.log('Raw response:', response.data);

      if (response.status === 200 && response.data) {
        const generatedCode = response.data.code;

        if (typeof generatedCode === 'string') {
          // Clean up and process the code
          let cleanCode = generatedCode
            .replace(/```(jsx?|typescript|react)?\n/g, '')
            .replace(/```\n?$/g, '')
            .trim();

          // Ensure React import
          if (!cleanCode.includes('import React')) {
            cleanCode = `import React from 'react';\n\n${cleanCode}`;
          }

          // Ensure export statement
          if (!cleanCode.includes('export default App')) {
            cleanCode += '\n\nexport default App;';
          }

          // Ensure the code has a function named App
          if (!cleanCode.includes('function App') && !cleanCode.includes('const App')) {
            cleanCode = cleanCode.replace(/function\s+([A-Za-z0-9_]+)/, 'function App');
          }

          setCode(cleanCode);
        } else {
          throw new Error('Invalid code format received');
        }
      } else {
        throw new Error('Empty response from server');
      }
    } catch (err) {
      console.error('Full error object:', err);

      let errorMessage = 'Failed to generate code';

      if (err.response) {
        errorMessage =
          err.response.data?.error ||
          err.response.data?.message ||
          `Server error: ${err.response.status}`;
        console.error('Server error details:', err.response.data);
      } else if (err.request) {
        errorMessage =
          'No response from server. Please check if the server is running.';
        console.error('No response received:', err.request);
      } else {
        errorMessage = err.message;
        console.error('Request setup error:', err.message);
      }

      setError(errorMessage);
    } finally {
      setIsLoading(false);
    }
  };

  const handleKeyPress = (e) => {
    if (e.key === 'Enter' && !isLoading && prompt.trim()) {
      generateCode();
    }
  };

  return (
    <div className="app-container">
      <div className="control-panel">
        <div className="input-group">
          <input
            type="text"
            value={prompt}
            onChange={handlePromptChange}
            onKeyPress={handleKeyPress}
            placeholder="Describe the React component you want to create..."
            disabled={isLoading}
            className="prompt-input"
          />
          <button
            onClick={generateCode}
            disabled={isLoading || !prompt.trim()}
            className={`generate-button ${isLoading ? 'loading' : ''}`}
          >
            {isLoading ? 'Generating...' : 'Generate Code'}
          </button>
        </div>

        {error && (
          <div className="error-message" role="alert">
            {error}
          </div>
        )}
      </div>

      <div className="editor-preview-container">
        <div className="editor-container">
          <h2>Code Editor</h2>
          <div className="editor-wrapper">
            <CodeEditor code={code} onChange={handleCodeChange} />
          </div>
        </div>
        <div className="preview-container">
          <h2>Preview</h2>
          <div className="preview-wrapper">
            <Preview code={code} />
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

// Modified CodeEditor.jsx
import React from 'react';
import Editor from '@monaco-editor/react';

function CodeEditor({ code, onChange }) {
  const defaultCode = `import React from 'react';

function App() {
  return (
    <div>
      <h1>Hello, World!</h1>
    </div>
  );
}

export default App;`;

  return (
    <Editor
      height="100%"
      defaultLanguage="javascript"
      value={code || defaultCode}
      onChange={onChange}
      theme="vs-dark"
      options={{
        minimap: { enabled: false },
        automaticLayout: true,
        scrollBeyondLastLine: false,
        fontSize: 14,
        formatOnPaste: true,
        formatOnType: true,
        wordWrap: 'on',
        tabSize: 2,
        insertSpaces: true,
        lineNumbers: 'on',
        roundedSelection: false,
        scrollBeyondLastLine: false,
        readOnly: false,
        cursorStyle: 'line',
      }}
    />
  );
}

export default CodeEditor;

import React from 'react';
import CodePreview from '@uiw/react-code-preview';

function Preview({ code }) {
  // Process the code to ensure it's in the correct format
  const processedCode = `
import React from 'react';
import ReactDOM from 'react-dom/client';

${code}

const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(<App />);
`.trim();

  return (
    <div style={{ height: '100%', border: '1px solid #ddd' }}>
      <CodePreview
        code={processedCode}
        dependencies={{
          react: React,
          'react-dom': ReactDOM
        }}
        noCode={true}  // Hide the code editor in preview
        bgWhite={true} // White background
        style={{ height: '100%' }}
      />
    </div>
  );
}

export default Preview;

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
    host: true,
    headers: {
      "Cross-Origin-Opener-Policy": "same-origin",
      "Cross-Origin-Embedder-Policy": "credentialless",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type, Authorization",
    },
    proxy: {
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    },
  },
  optimizeDeps: {
    include: ['@codesandbox/sandpack-react'],
    esbuildOptions: {
      target: 'esnext'
    }
  },
  build: {
    sourcemap: true,
    target: 'esnext',
    outDir: 'dist',
    assetsDir: 'assets',
    rollupOptions: {
      input: {
        main: path.resolve(__dirname, 'index.html')
      }
    }
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  }
});