# Создай приложение которое позволяет делать пост и нет запросы на урл с параметрами если в ответ приходит json то выводи с помощью jsoneditor

<html lang="ru">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>POST и GET запрос с выводом JSON</title>
  <script src="https://app.aisearch.ru/static/tailwind/tailwind.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/10.2.0/jsoneditor.css" integrity="sha512-iOFdnlwX6UGb55bU5DL0tjWkS/+9jxRxw2KiRzyHMZARASUSwm0nEXBcdqsYni+t3UKJSK7vrwvlL8792/UMjQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/10.2.0/jsoneditor.min.js" integrity="sha512-QL8qeB9ctAtMXXILiMcO83THPl+1UB2N8CBGSNexHL5AQ/PVl14364HO56l2Ct6P8UEKkOS3xkD28FPqPHshBQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <style>
    #jsoneditor {
      height: 400px;
      border: 1px solid #cbd5e1; /* Tailwind ring color */
      border-radius: 0.375rem; /* Tailwind rounded-md */
    }
  </style>
</head>
<body class="bg-gray-50 min-h-screen p-6 font-sans">
  <div class="max-w-4xl mx-auto bg-white rounded-lg shadow-md p-6">
    <h1 class="text-3xl font-semibold mb-6 text-center">Запросы POST и GET с выводом JSON</h1>
    <form id="requestForm" class="space-y-6">
      <div>
        <label for="method" class="block mb-1 font-medium text-gray-700">Метод запроса</label>
        <select id="method" name="method" class="w-full border border-gray-300 rounded-md p-2">
          <option value="GET">GET</option>
          <option value="POST">POST</option>
        </select>
      </div>

      <div>
        <label for="url" class="block mb-1 font-medium text-gray-700">URL</label>
        <input type="url" id="url" name="url" placeholder="https://example.com/api" autocomplete="off" required
          class="w-full border border-gray-300 rounded-md p-2" />
      </div>

      <div id="paramsSection" class="space-y-2">
        <label class="block font-medium text-gray-700">Параметры (ключ - значение)</label>
        <div id="paramsContainer" class="space-y-2">
          <div class="flex space-x-2">
            <input name="paramKey" type="text" placeholder="Ключ" autocomplete="off"
              class="flex-1 border border-gray-300 rounded-md p-2" />
            <input name="paramValue" type="text" placeholder="Значение" autocomplete="off"
              class="flex-1 border border-gray-300 rounded-md p-2" />
            <button type="button" aria-label="Удалить параметр"
              class="text-red-500 hover:text-red-700 focus:outline-none flex items-center" onclick="removeParam(this)">
              <i class="fas fa-minus-circle fa-lg"></i>
            </button>
          </div>
        </div>
        <button type="button" id="addParamBtn"
          class="mt-2 px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white rounded-md focus:outline-none flex items-center gap-2">
          <i class="fas fa-plus"></i> Добавить параметр
        </button>
      </div>

      <div class="flex justify-center">
        <button type="submit"
          class="bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-md font-semibold transition-colors duration-200">
          Отправить запрос
        </button>
      </div>
    </form>

    <section class="mt-8">
      <h2 class="text-xl font-semibold mb-3">Ответ</h2>
      <div id="jsoneditor" aria-label="Редактор JSON ответа"></div>
      <pre id="rawResponse" class="hidden whitespace-pre-wrap max-h-96 overflow-auto bg-gray-100 p-4 rounded-md border border-gray-300"></pre>
    </section>
  </div>

  <script>
    alert('ff');
    const paramsContainer = document.getElementById('paramsContainer');
    document.getElementById('addParamBtn').addEventListener('click', () => {
      const paramDiv = document.createElement('div');
      paramDiv.className = 'flex space-x-2';

      const keyInput = document.createElement('input');
      keyInput.name = 'paramKey';
      keyInput.type = 'text';
      keyInput.placeholder = 'Ключ';
      keyInput.autocomplete = 'off';
      keyInput.className = 'flex-1 border border-gray-300 rounded-md p-2';

      const valueInput = document.createElement('input');
      valueInput.name = 'paramValue';
      valueInput.type = 'text';
      valueInput.placeholder = 'Значение';
      valueInput.autocomplete = 'off';
      valueInput.className = 'flex-1 border border-gray-300 rounded-md p-2';

      const removeBtn = document.createElement('button');
      removeBtn.type = 'button';
      removeBtn.setAttribute('aria-label', 'Удалить параметр');
      removeBtn.className = 'text-red-500 hover:text-red-700 focus:outline-none flex items-center';
      removeBtn.onclick = () => paramDiv.remove();
      removeBtn.innerHTML = '<i class="fas fa-minus-circle fa-lg"></i>';

      paramDiv.appendChild(keyInput);
      paramDiv.appendChild(valueInput);
      paramDiv.appendChild(removeBtn);

      paramsContainer.appendChild(paramDiv);
    });

    function removeParam(button) {
      const div = button.parentElement;
      div.remove();
    }

    const container = document.getElementById('jsoneditor');
    const rawResponse = document.getElementById('rawResponse');
    let jsonEditor = new JSONEditor(container, {
      mode: 'view',
      mainMenuBar: false,
      navigationBar: false,
      statusBar: false,
      onError: (err) => {
        console.error(err);
      }
    });

    document.getElementById('requestForm').addEventListener('submit', async (e) => {
      e.preventDefault();
      jsonEditor.set({});
      rawResponse.classList.add('hidden');
      rawResponse.textContent = '';

      const method = e.target.method.value.toUpperCase();
      let url = e.target.url.value.trim();

      const keys = Array.from(e.target.querySelectorAll('input[name="paramKey"]')).map(i => i.value.trim()).filter(k => k !== '');
      const values = Array.from(e.target.querySelectorAll('input[name="paramValue"]')).map(i => i.value);

      let params = {};
      for (let i = 0; i < keys.length; i++) {
        params[keys[i]] = values[i];
      }

      try {
        let response;
        if (method === 'GET') {
          // append params as query string
          const urlObj = new URL(url);
          Object.keys(params).forEach(key => {
            urlObj.searchParams.append(key, params[key]);
          });
          url = urlObj.toString();
          response = await fetch(url, { method: 'GET' });
        } else if (method === 'POST') {
          // send params as JSON body
          response = await fetch(url, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify(params)
          });
        } else {
          alert('Метод не поддерживается');
          return;
        }

        const contentType = response.headers.get('content-type') || '';
        const text = await response.text();

        try {
          if (contentType.includes('application/json')) {
            const json = JSON.parse(text);
            jsonEditor.set(json);
            rawResponse.classList.add('hidden');
          } else {
            // Не JSON, показать как текст
            rawResponse.textContent = text;
            rawResponse.classList.remove('hidden');
            jsonEditor.set({});
          }
        } catch (err) {
          // Ошибка парсинга JSON - показать сырой текст
          rawResponse.textContent = text;
          rawResponse.classList.remove('hidden');
          jsonEditor.set({});
        }
      } catch (error) {
        jsonEditor.set({});
        rawResponse.textContent = 'Ошибка запроса: ' + error.message;
        rawResponse.classList.remove('hidden');
      }
    });
  </script>
</body>
</html>
