index.html

46.96 KB
04/10/2025 01:37
HTML
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Data Entry & Management System</title>

  <!-- Thai Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet">

  <!-- Font Awesome for Icons -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

  <style>
    :root {
      --primary-color: #4a6fdc;
      --secondary-color: #f8f9fa;
      --accent-color: #ff6b6b;
      --success-color: #28a745;
      --warning-color: #ffc107;
      --danger-color: #dc3545;
      --text-color: #333;
      --border-color: #ddd;
      --shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      --transition: all 0.3s ease;
    }

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: 'Sarabun', sans-serif;
      background-color: #f5f7fa;
      color: var(--text-color);
      line-height: 1.6;
    }

    .container {
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
    }

    header {
      background-color: white;
      box-shadow: var(--shadow);
      padding: 20px 0;
      margin-bottom: 30px;
    }

    .header-content {
      display: flex;
      justify-content: space-between;
      align-items: center;
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 20px;
    }

    h1 {
      color: var(--primary-color);
      font-weight: 600;
    }

    .tabs {
      display: flex;
      border-bottom: 2px solid var(--border-color);
      margin-bottom: 30px;
    }

    .tab {
      padding: 15px 25px;
      cursor: pointer;
      background: none;
      border: none;
      font-size: 16px;
      font-weight: 500;
      color: #777;
      transition: var(--transition);
      position: relative;
    }

    .tab:hover {
      color: var(--primary-color);
    }

    .tab.active {
      color: var(--primary-color);
    }

    .tab.active::after {
      content: '';
      position: absolute;
      bottom: -2px;
      left: 0;
      width: 100%;
      height: 2px;
      background-color: var(--primary-color);
    }

    .tab-content {
      display: none;
      animation: fadeIn 0.5s;
    }

    .tab-content.active {
      display: block;
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    .card {
      background-color: white;
      border-radius: 8px;
      box-shadow: var(--shadow);
      padding: 25px;
      margin-bottom: 20px;
    }

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      padding-bottom: 15px;
      border-bottom: 1px solid var(--border-color);
    }

    .card-title {
      font-size: 20px;
      font-weight: 600;
      color: var(--primary-color);
    }

    .btn {
      padding: 10px 15px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
      font-weight: 500;
      transition: var(--transition);
      display: inline-flex;
      align-items: center;
      gap: 8px;
    }

    .btn-primary {
      background-color: var(--primary-color);
      color: white;
    }

    .btn-primary:hover {
      background-color: #3a5fc7;
    }

    .btn-success {
      background-color: var(--success-color);
      color: white;
    }

    .btn-success:hover {
      background-color: #218838;
    }

    .btn-danger {
      background-color: var(--danger-color);
      color: white;
    }

    .btn-danger:hover {
      background-color: #c82333;
    }

    .btn-secondary {
      background-color: var(--secondary-color);
      color: var(--text-color);
    }

    .btn-secondary:hover {
      background-color: #e9ecef;
    }

    .form-group {
      margin-bottom: 20px;
    }

    label {
      display: block;
      margin-bottom: 8px;
      font-weight: 500;
    }

    input,
    select,
    textarea {
      width: 100%;
      padding: 10px 15px;
      border: 1px solid var(--border-color);
      border-radius: 4px;
      font-family: inherit;
      font-size: 14px;
      transition: var(--transition);
    }

    input:focus,
    select:focus,
    textarea:focus {
      outline: none;
      border-color: var(--primary-color);
      box-shadow: 0 0 0 2px rgba(74, 111, 220, 0.2);
    }

    .form-row {
      display: flex;
      gap: 20px;
    }

    .form-col {
      flex: 1;
    }

    .json-output {
      background-color: #f8f9fa;
      border: 1px solid var(--border-color);
      border-radius: 4px;
      padding: 15px;
      font-family: monospace;
      font-size: 14px;
      white-space: pre-wrap;
      max-height: 400px;
      overflow-y: auto;
    }

    .form-element {
      background-color: var(--secondary-color);
      border-radius: 4px;
      padding: 15px;
      margin-bottom: 15px;
      position: relative;
    }

    .element-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 10px;
    }

    .element-type {
      font-weight: 600;
      color: var(--primary-color);
    }

    .element-actions {
      display: flex;
      gap: 10px;
    }

    .icon-btn {
      background: none;
      border: none;
      cursor: pointer;
      color: #777;
      font-size: 16px;
      transition: var(--transition);
    }

    .icon-btn:hover {
      color: var(--primary-color);
    }

    .icon-btn.delete:hover {
      color: var(--danger-color);
    }

    .data-table {
      width: 100%;
      border-collapse: collapse;
    }

    .data-table th,
    .data-table td {
      padding: 12px 15px;
      text-align: left;
      border-bottom: 1px solid var(--border-color);
    }

    .data-table th {
      background-color: var(--secondary-color);
      font-weight: 600;
    }

    .data-table tr:hover {
      background-color: #f8f9fa;
    }

    .table-actions {
      display: flex;
      gap: 10px;
    }

    .notification {
      position: fixed;
      top: 20px;
      right: 20px;
      padding: 15px 20px;
      border-radius: 4px;
      color: white;
      font-weight: 500;
      box-shadow: var(--shadow);
      z-index: 1000;
      transform: translateX(120%);
      transition: transform 0.3s ease;
    }

    .notification.show {
      transform: translateX(0);
    }

    .notification.success {
      background-color: var(--success-color);
    }

    .notification.error {
      background-color: var(--danger-color);
    }

    .notification.warning {
      background-color: var(--warning-color);
    }

    .modal {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      z-index: 999;
      align-items: center;
      justify-content: center;
    }

    .modal.show {
      display: flex;
    }

    .modal-content {
      background-color: white;
      border-radius: 8px;
      padding: 25px;
      max-width: 600px;
      width: 90%;
      max-height: 80vh;
      overflow-y: auto;
    }

    .modal-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
    }

    .modal-title {
      font-size: 20px;
      font-weight: 600;
      color: var(--primary-color);
    }

    .close-btn {
      background: none;
      border: none;
      font-size: 24px;
      cursor: pointer;
      color: #777;
    }

    .close-btn:hover {
      color: var(--danger-color);
    }

    .validation-message {
      color: var(--danger-color);
      font-size: 12px;
      margin-top: 5px;
      display: none;
    }

    .validation-message.show {
      display: block;
    }

    .checkbox-group,
    .radio-group {
      display: flex;
      flex-wrap: wrap;
      gap: 15px;
    }

    .checkbox-item,
    .radio-item {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .file-upload {
      position: relative;
      display: inline-block;
      cursor: pointer;
      width: 100%;
    }

    .file-upload input[type=file] {
      position: absolute;
      left: -9999px;
    }

    .file-upload-label {
      display: block;
      padding: 10px 15px;
      border: 1px dashed var(--border-color);
      border-radius: 4px;
      text-align: center;
      transition: var(--transition);
    }

    .file-upload-label:hover {
      border-color: var(--primary-color);
      background-color: rgba(74, 111, 220, 0.05);
    }

    @media (max-width: 768px) {
      .form-row {
        flex-direction: column;
        gap: 0;
      }

      .tabs {
        overflow-x: auto;
      }

      .table-actions {
        flex-direction: column;
        gap: 5px;
      }

      .data-table {
        font-size: 14px;
      }

      .data-table th,
      .data-table td {
        padding: 8px 10px;
      }
    }
  </style>
</head>

<body>
  <header>
    <div class="header-content">
      <h1><i class="fas fa-database"></i> Data Entry & Management System</h1>
      <div class="header-actions">
        <button class="btn btn-secondary" onclick="exportData()">
          <i class="fas fa-download"></i> Export Data
        </button>
      </div>
    </div>
  </header>

  <div class="container">
    <div class="tabs">
      <button class="tab active" onclick="switchTab('form-builder')">
        <i class="fas fa-wrench"></i> Form Builder
      </button>
      <button class="tab" onclick="switchTab('form-renderer')">
        <i class="fas fa-file-alt"></i> Form Renderer
      </button>
      <button class="tab" onclick="switchTab('data-management')">
        <i class="fas fa-table"></i> Data Management
      </button>
    </div>

    <!-- Form Builder Tab -->
    <div id="form-builder" class="tab-content active">
      <div class="card">
        <div class="card-header">
          <h2 class="card-title">Form Builder</h2>
          <button class="btn btn-primary" onclick="addElement()">
            <i class="fas fa-plus"></i> Add Element
          </button>
        </div>

        <div id="form-elements-container">
          <!-- Form elements will be added here dynamically -->
        </div>

        <div class="form-group">
          <button class="btn btn-success" onclick="generateJSON()">
            <i class="fas fa-code"></i> Generate JSON Schema
          </button>
          <button class="btn btn-secondary" onclick="loadSampleForm()">
            <i class="fas fa-file-import"></i> Load Sample Form
          </button>
        </div>

        <div id="json-output-container" style="display: none;">
          <h3>Generated JSON Schema:</h3>
          <div id="json-output" class="json-output"></div>
        </div>
      </div>
    </div>

    <!-- Form Renderer Tab -->
    <div id="form-renderer" class="tab-content">
      <div class="card">
        <div class="card-header">
          <h2 class="card-title">Form Renderer</h2>
          <button class="btn btn-secondary" onclick="loadSampleSchema()">
            <i class="fas fa-file-import"></i> Load Sample Schema
          </button>
        </div>

        <div class="form-group">
          <label for="schema-input">Form Schema (JSON):</label>
          <textarea id="schema-input" rows="10" placeholder="Paste your form schema JSON here..."></textarea>
        </div>

        <div class="form-group">
          <button class="btn btn-primary" onclick="renderForm()">
            <i class="fas fa-play"></i> Render Form
          </button>
        </div>

        <div id="rendered-form-container" style="display: none;">
          <h3>Rendered Form:</h3>
          <form id="rendered-form">
            <!-- Form will be rendered here -->
          </form>
          <div class="form-group">
            <button type="button" class="btn btn-success" onclick="submitForm()">
              <i class="fas fa-save"></i> Submit Form
            </button>
            <button type="button" class="btn btn-secondary" onclick="resetForm()">
              <i class="fas fa-redo"></i> Reset
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- Data Management Tab -->
    <div id="data-management" class="tab-content">
      <div class="card">
        <div class="card-header">
          <h2 class="card-title">Data Management</h2>
          <button class="btn btn-primary" onclick="refreshData()">
            <i class="fas fa-sync-alt"></i> Refresh
          </button>
        </div>

        <div id="data-table-container">
          <table class="data-table">
            <thead id="table-header">
              <!-- Table headers will be generated here -->
            </thead>
            <tbody id="table-body">
              <!-- Table rows will be generated here -->
            </tbody>
          </table>

          <div id="no-data-message" style="text-align: center; padding: 30px; display: none;">
            <i class="fas fa-inbox" style="font-size: 48px; color: #ccc; margin-bottom: 15px;"></i>
            <p>No data available. Submit a form to see data here.</p>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Edit Modal -->
  <div id="edit-modal" class="modal">
    <div class="modal-content">
      <div class="modal-header">
        <h3 class="modal-title">Edit Data</h3>
        <button class="close-btn" onclick="closeEditModal()">&times;</button>
      </div>
      <div class="modal-body">
        <form id="edit-form">
          <!-- Edit form will be generated here -->
        </form>
        <div class="form-group">
          <button type="button" class="btn btn-success" onclick="saveEdit()">
            <i class="fas fa-save"></i> Save Changes
          </button>
          <button type="button" class="btn btn-secondary" onclick="closeEditModal()">
            <i class="fas fa-times"></i> Cancel
          </button>
        </div>
      </div>
    </div>
  </div>

  <!-- Notification -->
  <div id="notification" class="notification"></div>

  <script>
    // Global variables
    let formElements = [];
    let currentSchema = null;
    let formData = [];
    let editingIndex = -1;

    // Initialize the application
    document.addEventListener('DOMContentLoaded', function() {
      // Load sample data on page load
      loadSampleData();
    });

    // Tab switching
    function switchTab(tabId) {
      // Hide all tab contents
      document.querySelectorAll('.tab-content').forEach(content => {
        content.classList.remove('active');
      });

      // Remove active class from all tabs
      document.querySelectorAll('.tab').forEach(tab => {
        tab.classList.remove('active');
      });

      // Show selected tab content
      document.getElementById(tabId).classList.add('active');

      // Add active class to clicked tab
      event.target.classList.add('active');

      // Refresh data if switching to data management tab
      if (tabId === 'data-management') {
        refreshData();
      }
    }

    // Form Builder Functions
    function addElement() {
      const elementId = 'element-' + Date.now();
      const element = {
        id: elementId,
        type: 'text',
        label: 'New Field',
        name: 'new_field',
        placeholder: 'Enter value',
        required: false,
        validation: {}
      };

      formElements.push(element);
      renderFormElements();
    }

    function renderFormElements() {
      const container = document.getElementById('form-elements-container');
      container.innerHTML = '';

      formElements.forEach((element, index) => {
        const elementDiv = document.createElement('div');
        elementDiv.className = 'form-element';
        elementDiv.id = element.id;

        elementDiv.innerHTML = `
                    <div class="element-header">
                        <span class="element-type">${element.type.charAt(0).toUpperCase() + element.type.slice(1)} Field</span>
                        <div class="element-actions">
                            <button class="icon-btn" onclick="moveElement(${index}, 'up')">
                                <i class="fas fa-arrow-up"></i>
                            </button>
                            <button class="icon-btn" onclick="moveElement(${index}, 'down')">
                                <i class="fas fa-arrow-down"></i>
                            </button>
                            <button class="icon-btn delete" onclick="deleteElement(${index})">
                                <i class="fas fa-trash"></i>
                            </button>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-col">
                            <div class="form-group">
                                <label>Field Type</label>
                                <select onchange="updateElementType(${index}, this.value)">
                                    <option value="text" ${element.type === 'text' ? 'selected' : ''}>Text</option>
                                    <option value="textarea" ${element.type === 'textarea' ? 'selected' : ''}>Textarea</option>
                                    <option value="number" ${element.type === 'number' ? 'selected' : ''}>Number</option>
                                    <option value="date" ${element.type === 'date' ? 'selected' : ''}>Date</option>
                                    <option value="select" ${element.type === 'select' ? 'selected' : ''}>Select</option>
                                    <option value="checkbox" ${element.type === 'checkbox' ? 'selected' : ''}>Checkbox</option>
                                    <option value="radio" ${element.type === 'radio' ? 'selected' : ''}>Radio</option>
                                    <option value="file" ${element.type === 'file' ? 'selected' : ''}>File Upload</option>
                                </select>
                            </div>
                        </div>
                        <div class="form-col">
                            <div class="form-group">
                                <label>Field Label</label>
                                <input type="text" value="${element.label}" onchange="updateElementProperty(${index}, 'label', this.value)">
                            </div>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-col">
                            <div class="form-group">
                                <label>Field Name</label>
                                <input type="text" value="${element.name}" onchange="updateElementProperty(${index}, 'name', this.value)">
                            </div>
                        </div>
                        <div class="form-col">
                            <div class="form-group">
                                <label>Placeholder</label>
                                <input type="text" value="${element.placeholder}" onchange="updateElementProperty(${index}, 'placeholder', this.value)">
                            </div>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-col">
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" ${element.required ? 'checked' : ''} onchange="updateElementProperty(${index}, 'required', this.checked)">
                                    Required
                                </label>
                            </div>
                        </div>
                        <div class="form-col">
                            <div class="form-group">
                                <button class="btn btn-secondary" onclick="toggleValidationOptions(${index})">
                                    <i class="fas fa-cog"></i> Validation Options
                                </button>
                            </div>
                        </div>
                    </div>
                    <div id="validation-${index}" class="validation-options" style="display: none; margin-top: 15px;">
                        <div class="form-row">
                            <div class="form-col">
                                <div class="form-group">
                                    <label>Min Length</label>
                                    <input type="number" value="${element.validation.minLength || ''}" onchange="updateValidationProperty(${index}, 'minLength', this.value)">
                                </div>
                            </div>
                            <div class="form-col">
                                <div class="form-group">
                                    <label>Max Length</label>
                                    <input type="number" value="${element.validation.maxLength || ''}" onchange="updateValidationProperty(${index}, 'maxLength', this.value)">
                                </div>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-col">
                                <div class="form-group">
                                    <label>Min Value</label>
                                    <input type="number" value="${element.validation.min || ''}" onchange="updateValidationProperty(${index}, 'min', this.value)">
                                </div>
                            </div>
                            <div class="form-col">
                                <div class="form-group">
                                    <label>Max Value</label>
                                    <input type="number" value="${element.validation.max || ''}" onchange="updateValidationProperty(${index}, 'max', this.value)">
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <label>Pattern (Regex)</label>
                            <input type="text" value="${element.validation.pattern || ''}" onchange="updateValidationProperty(${index}, 'pattern', this.value)">
                        </div>
                        <div class="form-group">
                            <label>
                                <input type="checkbox" ${element.validation.email ? 'checked' : ''} onchange="updateValidationProperty(${index}, 'email', this.checked)">
                                Email Validation
                            </label>
                        </div>
                        ${element.type === 'select' || element.type === 'radio' ? `
                        <div class="form-group">
                            <label>Options (comma-separated)</label>
                            <input type="text" value="${element.options ? element.options.join(', ') : ''}" onchange="updateElementProperty(${index}, 'options', this.value.split(',').map(opt => opt.trim()))">
                        </div>
                        ` : ''}
                    </div>
                `;

        container.appendChild(elementDiv);
      });
    }

    function updateElementType(index, type) {
      formElements[index].type = type;
      renderFormElements();
    }

    function updateElementProperty(index, property, value) {
      formElements[index][property] = value;
    }

    function updateValidationProperty(index, property, value) {
      if (!formElements[index].validation) {
        formElements[index].validation = {};
      }

      if (value === '') {
        delete formElements[index].validation[property];
      } else {
        formElements[index].validation[property] = property === 'minLength' || property === 'maxLength' || property === 'min' || property === 'max' ?
          (value ? parseInt(value) : undefined) : value;
      }
    }

    function toggleValidationOptions(index) {
      const validationDiv = document.getElementById(`validation-${index}`);
      validationDiv.style.display = validationDiv.style.display === 'none' ? 'block' : 'none';
    }

    function moveElement(index, direction) {
      if (direction === 'up' && index > 0) {
        [formElements[index], formElements[index - 1]] = [formElements[index - 1], formElements[index]];
      } else if (direction === 'down' && index < formElements.length - 1) {
        [formElements[index], formElements[index + 1]] = [formElements[index + 1], formElements[index]];
      }
      renderFormElements();
    }

    function deleteElement(index) {
      formElements.splice(index, 1);
      renderFormElements();
    }

    function generateJSON() {
      const schema = {
        formTitle: "Generated Form",
        formDescription: "This form was generated using the Form Builder",
        elements: formElements
      };

      const jsonOutput = document.getElementById('json-output');
      jsonOutput.textContent = JSON.stringify(schema, null, 2);

      document.getElementById('json-output-container').style.display = 'block';

      showNotification('Form schema generated successfully!', 'success');
    }

    function loadSampleForm() {
      formElements = [
        {
          id: 'element-1',
          type: 'text',
          label: 'First Name',
          name: 'first_name',
          placeholder: 'Enter your first name',
          required: true,
          validation: {
            minLength: 2,
            maxLength: 50
          }
        },
        {
          id: 'element-2',
          type: 'text',
          label: 'Last Name',
          name: 'last_name',
          placeholder: 'Enter your last name',
          required: true,
          validation: {
            minLength: 2,
            maxLength: 50
          }
        },
        {
          id: 'element-3',
          type: 'email',
          label: 'Email',
          name: 'email',
          placeholder: 'Enter your email',
          required: true,
          validation: {
            email: true
          }
        },
        {
          id: 'element-4',
          type: 'number',
          label: 'Age',
          name: 'age',
          placeholder: 'Enter your age',
          required: true,
          validation: {
            min: 18,
            max: 120
          }
        },
        {
          id: 'element-5',
          type: 'date',
          label: 'Birth Date',
          name: 'birth_date',
          placeholder: '',
          required: false,
          validation: {}
        },
        {
          id: 'element-6',
          type: 'select',
          label: 'Country',
          name: 'country',
          placeholder: 'Select your country',
          required: true,
          validation: {},
          options: ['Thailand', 'United States', 'United Kingdom', 'Canada', 'Australia', 'Other']
        },
        {
          id: 'element-7',
          type: 'checkbox',
          label: 'Interests',
          name: 'interests',
          placeholder: '',
          required: false,
          validation: {},
          options: ['Sports', 'Music', 'Travel', 'Reading', 'Technology']
        },
        {
          id: 'element-8',
          type: 'textarea',
          label: 'Comments',
          name: 'comments',
          placeholder: 'Enter your comments',
          required: false,
          validation: {
            maxLength: 500
          }
        }
      ];

      renderFormElements();
      showNotification('Sample form loaded successfully!', 'success');
    }

    // Form Renderer Functions
    function loadSampleSchema() {
      const sampleSchema = {
        formTitle: "User Registration Form",
        formDescription: "Please fill out this form to register",
        elements: [
          {
            id: "element-1",
            type: "text",
            label: "First Name",
            name: "first_name",
            placeholder: "Enter your first name",
            required: true,
            validation: {
              minLength: 2,
              maxLength: 50
            }
          },
          {
            id: "element-2",
            type: "text",
            label: "Last Name",
            name: "last_name",
            placeholder: "Enter your last name",
            required: true,
            validation: {
              minLength: 2,
              maxLength: 50
            }
          },
          {
            id: "element-3",
            type: "email",
            label: "Email",
            name: "email",
            placeholder: "Enter your email",
            required: true,
            validation: {
              email: true
            }
          },
          {
            id: "element-4",
            type: "number",
            label: "Age",
            name: "age",
            placeholder: "Enter your age",
            required: true,
            validation: {
              min: 18,
              max: 120
            }
          },
          {
            id: "element-5",
            type: "date",
            label: "Birth Date",
            name: "birth_date",
            placeholder: "",
            required: false,
            validation: {}
          },
          {
            id: "element-6",
            type: "select",
            label: "Country",
            name: "country",
            placeholder: "Select your country",
            required: true,
            validation: {},
            options: ["Thailand", "United States", "United Kingdom", "Canada", "Australia", "Other"]
          },
          {
            id: "element-7",
            type: "checkbox",
            label: "Interests",
            name: "interests",
            placeholder: "",
            required: false,
            validation: {},
            options: ["Sports", "Music", "Travel", "Reading", "Technology"]
          },
          {
            id: "element-8",
            type: "textarea",
            label: "Comments",
            name: "comments",
            placeholder: "Enter your comments",
            required: false,
            validation: {
              maxLength: 500
            }
          }
        ]
      };

      document.getElementById('schema-input').value = JSON.stringify(sampleSchema, null, 2);
      showNotification('Sample schema loaded!', 'success');
    }

    function renderForm() {
      const schemaInput = document.getElementById('schema-input').value;

      try {
        currentSchema = JSON.parse(schemaInput);

        const formContainer = document.getElementById('rendered-form');
        formContainer.innerHTML = '';

        currentSchema.elements.forEach(element => {
          const formGroup = document.createElement('div');
          formGroup.className = 'form-group';

          let fieldHtml = '';

          switch (element.type) {
            case 'text':
            case 'email':
            case 'number':
            case 'date':
              fieldHtml = `
                                <label for="${element.name}">${element.label}${element.required ? ' *' : ''}</label>
                                <input type="${element.type}" id="${element.name}" name="${element.name}" placeholder="${element.placeholder}" ${element.required ? 'required' : ''}>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;

            case 'textarea':
              fieldHtml = `
                                <label for="${element.name}">${element.label}${element.required ? ' *' : ''}</label>
                                <textarea id="${element.name}" name="${element.name}" placeholder="${element.placeholder}" ${element.required ? 'required' : ''}></textarea>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;

            case 'select':
              fieldHtml = `
                                <label for="${element.name}">${element.label}${element.required ? ' *' : ''}</label>
                                <select id="${element.name}" name="${element.name}" ${element.required ? 'required' : ''}>
                                    <option value="">${element.placeholder}</option>
                                    ${element.options.map(option => `<option value="${option}">${option}</option>`).join('')}
                                </select>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;

            case 'checkbox':
              fieldHtml = `
                                <label>${element.label}${element.required ? ' *' : ''}</label>
                                <div class="checkbox-group">
                                    ${element.options.map(option => `
                                        <div class="checkbox-item">
                                            <input type="checkbox" id="${element.name}_${option}" name="${element.name}" value="${option}">
                                            <label for="${element.name}_${option}">${option}</label>
                                        </div>
                                    `).join('')}
                                </div>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;

            case 'radio':
              fieldHtml = `
                                <label>${element.label}${element.required ? ' *' : ''}</label>
                                <div class="radio-group">
                                    ${element.options.map(option => `
                                        <div class="radio-item">
                                            <input type="radio" id="${element.name}_${option}" name="${element.name}" value="${option}">
                                            <label for="${element.name}_${option}">${option}</label>
                                        </div>
                                    `).join('')}
                                </div>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;

            case 'file':
              fieldHtml = `
                                <label for="${element.name}">${element.label}${element.required ? ' *' : ''}</label>
                                <div class="file-upload">
                                    <input type="file" id="${element.name}" name="${element.name}" ${element.required ? 'required' : ''}>
                                    <label for="${element.name}" class="file-upload-label">
                                        <i class="fas fa-cloud-upload-alt"></i> Choose File
                                    </label>
                                </div>
                                <div id="${element.name}-error" class="validation-message"></div>
                            `;
              break;
          }

          formGroup.innerHTML = fieldHtml;
          formContainer.appendChild(formGroup);
        });

        document.getElementById('rendered-form-container').style.display = 'block';
        showNotification('Form rendered successfully!', 'success');
      } catch (error) {
        showNotification('Invalid JSON schema: ' + error.message, 'error');
      }
    }

    function validateForm() {
      if (!currentSchema) return false;

      let isValid = true;

      currentSchema.elements.forEach(element => {
        const field = document.getElementsByName(element.name)[0];
        const errorElement = document.getElementById(`${element.name}-error`);

        if (!field) return;

        let value = '';

        if (element.type === 'checkbox') {
          const checkboxes = document.getElementsByName(element.name);
          value = Array.from(checkboxes)
            .filter(cb => cb.checked)
            .map(cb => cb.value)
            .join(', ');
        } else if (element.type === 'file') {
          value = field.files.length > 0 ? field.files[0].name : '';
        } else {
          value = field.value.trim();
        }

        // Reset error message
        errorElement.textContent = '';
        errorElement.classList.remove('show');

        // Check if required
        if (element.required && !value) {
          errorElement.textContent = `${element.label} is required`;
          errorElement.classList.add('show');
          isValid = false;
          return;
        }

        // Skip validation if field is empty and not required
        if (!value) return;

        // Apply validation rules
        if (element.validation) {
          // Min length
          if (element.validation.minLength && value.length < element.validation.minLength) {
            errorElement.textContent = `${element.label} must be at least ${element.validation.minLength} characters`;
            errorElement.classList.add('show');
            isValid = false;
            return;
          }

          // Max length
          if (element.validation.maxLength && value.length > element.validation.maxLength) {
            errorElement.textContent = `${element.label} must be no more than ${element.validation.maxLength} characters`;
            errorElement.classList.add('show');
            isValid = false;
            return;
          }

          // Min value
          if (element.validation.min && parseFloat(value) < element.validation.min) {
            errorElement.textContent = `${element.label} must be at least ${element.validation.min}`;
            errorElement.classList.add('show');
            isValid = false;
            return;
          }

          // Max value
          if (element.validation.max && parseFloat(value) > element.validation.max) {
            errorElement.textContent = `${element.label} must be no more than ${element.validation.max}`;
            errorElement.classList.add('show');
            isValid = false;
            return;
          }

          // Pattern
          if (element.validation.pattern) {
            const regex = new RegExp(element.validation.pattern);
            if (!regex.test(value)) {
              errorElement.textContent = `${element.label} format is invalid`;
              errorElement.classList.add('show');
              isValid = false;
              return;
            }
          }

          // Email
          if (element.validation.email) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(value)) {
              errorElement.textContent = `${element.label} must be a valid email address`;
              errorElement.classList.add('show');
              isValid = false;
              return;
            }
          }
        }
      });

      return isValid;
    }

    function submitForm() {
      if (!validateForm()) {
        showNotification('Please fix the errors in the form', 'error');
        return;
      }

      const formDataObj = {};

      currentSchema.elements.forEach(element => {
        const field = document.getElementsByName(element.name)[0];

        if (!field) return;

        let value = '';

        if (element.type === 'checkbox') {
          const checkboxes = document.getElementsByName(element.name);
          value = Array.from(checkboxes)
            .filter(cb => cb.checked)
            .map(cb => cb.value)
            .join(', ');
        } else if (element.type === 'file') {
          value = field.files.length > 0 ? field.files[0].name : '';
        } else {
          value = field.value.trim();
        }

        formDataObj[element.name] = value;
      });

      // Add timestamp
      formDataObj.id = Date.now();
      formDataObj.submittedAt = new Date().toISOString();

      // Save to mock database
      formData.push(formDataObj);
      localStorage.setItem('formData', JSON.stringify(formData));

      showNotification('Form submitted successfully!', 'success');

      // Reset form
      document.getElementById('rendered-form').reset();
    }

    function resetForm() {
      document.getElementById('rendered-form').reset();

      // Clear all validation messages
      document.querySelectorAll('.validation-message').forEach(element => {
        element.textContent = '';
        element.classList.remove('show');
      });
    }

    // Data Management Functions
    function loadSampleData() {
      const storedData = localStorage.getItem('formData');

      if (storedData) {
        formData = JSON.parse(storedData);
      } else {
        // Load sample data if no data is stored
        formData = [
          {
            id: 1,
            first_name: "John",
            last_name: "Doe",
            email: "john.doe@example.com",
            age: "30",
            birth_date: "1993-05-15",
            country: "United States",
            interests: "Sports, Music",
            comments: "Looking forward to using this system!",
            submittedAt: "2023-07-15T10:30:00.000Z"
          },
          {
            id: 2,
            first_name: "Jane",
            last_name: "Smith",
            email: "jane.smith@example.com",
            age: "28",
            birth_date: "1995-09-22",
            country: "United Kingdom",
            interests: "Travel, Reading",
            comments: "Great form design!",
            submittedAt: "2023-07-16T14:45:00.000Z"
          }
        ];

        localStorage.setItem('formData', JSON.stringify(formData));
      }
    }

    function refreshData() {
      const tableHeader = document.getElementById('table-header');
      const tableBody = document.getElementById('table-body');
      const noDataMessage = document.getElementById('no-data-message');

      // Clear existing table
      tableHeader.innerHTML = '';
      tableBody.innerHTML = '';

      if (formData.length === 0) {
        noDataMessage.style.display = 'block';
        return;
      }

      noDataMessage.style.display = 'none';

      // Get column names from the first data object
      const columns = Object.keys(formData[0]);

      // Create table headers
      const headerRow = document.createElement('tr');

      // Add ID column
      const idHeader = document.createElement('th');
      idHeader.textContent = 'ID';
      headerRow.appendChild(idHeader);

      // Add other columns (excluding submittedAt for cleaner view)
      columns.forEach(column => {
        if (column !== 'id' && column !== 'submittedAt') {
          const th = document.createElement('th');
          th.textContent = column.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
          headerRow.appendChild(th);
        }
      });

      // Add actions column
      const actionsHeader = document.createElement('th');
      actionsHeader.textContent = 'Actions';
      headerRow.appendChild(actionsHeader);

      tableHeader.appendChild(headerRow);

      // Create table rows
      formData.forEach((item, index) => {
        const row = document.createElement('tr');

        // Add ID cell
        const idCell = document.createElement('td');
        idCell.textContent = item.id;
        row.appendChild(idCell);

        // Add other cells
        columns.forEach(column => {
          if (column !== 'id' && column !== 'submittedAt') {
            const cell = document.createElement('td');
            cell.textContent = item[column] || '-';
            row.appendChild(cell);
          }
        });

        // Add actions cell
        const actionsCell = document.createElement('td');
        actionsCell.innerHTML = `
                    <div class="table-actions">
                        <button class="btn btn-secondary" onclick="viewData(${index})">
                            <i class="fas fa-eye"></i> View
                        </button>
                        <button class="btn btn-primary" onclick="editData(${index})">
                            <i class="fas fa-edit"></i> Edit
                        </button>
                        <button class="btn btn-danger" onclick="deleteData(${index})">
                            <i class="fas fa-trash"></i> Delete
                        </button>
                    </div>
                `;
        row.appendChild(actionsCell);

        tableBody.appendChild(row);
      });
    }

    function viewData(index) {
      const item = formData[index];

      let content = '<div style="max-height: 400px; overflow-y: auto;">';

      Object.keys(item).forEach(key => {
        if (key !== 'id') {
          content += `
                        <div class="form-group">
                            <label>${key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}:</label>
                            <div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px;">${item[key] || '-'}</div>
                        </div>
                    `;
        }
      });

      content += '</div>';

      document.getElementById('edit-form').innerHTML = content;
      document.getElementById('edit-modal').classList.add('show');
    }

    function editData(index) {
      editingIndex = index;
      const item = formData[index];

      let formHtml = '';

      Object.keys(item).forEach(key => {
        if (key !== 'id' && key !== 'submittedAt') {
          formHtml += `
                        <div class="form-group">
                            <label for="edit-${key}">${key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}:</label>
                            <input type="text" id="edit-${key}" value="${item[key] || ''}">
                        </div>
                    `;
        }
      });

      document.getElementById('edit-form').innerHTML = formHtml;
      document.getElementById('edit-modal').classList.add('show');
    }

    function saveEdit() {
      if (editingIndex === -1) return;

      const item = formData[editingIndex];

      Object.keys(item).forEach(key => {
        if (key !== 'id' && key !== 'submittedAt') {
          const field = document.getElementById(`edit-${key}`);
          if (field) {
            item[key] = field.value;
          }
        }
      });

      // Update the data in localStorage
      localStorage.setItem('formData', JSON.stringify(formData));

      closeEditModal();
      refreshData();
      showNotification('Data updated successfully!', 'success');
    }

    function closeEditModal() {
      document.getElementById('edit-modal').classList.remove('show');
      editingIndex = -1;
    }

    function deleteData(index) {
      if (confirm('Are you sure you want to delete this data?')) {
        formData.splice(index, 1);
        localStorage.setItem('formData', JSON.stringify(formData));
        refreshData();
        showNotification('Data deleted successfully!', 'success');
      }
    }

    function exportData() {
      const dataStr = JSON.stringify(formData, null, 2);
      const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);

      const exportFileDefaultName = 'form_data_' + new Date().toISOString().slice(0, 10) + '.json';

      const linkElement = document.createElement('a');
      linkElement.setAttribute('href', dataUri);
      linkElement.setAttribute('download', exportFileDefaultName);
      linkElement.click();

      showNotification('Data exported successfully!', 'success');
    }

    function showNotification(message, type) {
      const notification = document.getElementById('notification');
      notification.textContent = message;
      notification.className = 'notification ' + type;
      notification.classList.add('show');

      setTimeout(() => {
        notification.classList.remove('show');
      }, 3000);
    }
  </script>
</body>

</html>