<div class="container-fluid">
      <div class="row justify-content-center">
        <div class="col-12 col-md-10 col-lg-8 col-xl-6 mt-5">
          <p class="lead">
            This demo requires an API key.
            <a target="_blank" href="https://platform.openai.com/"
              >Get yours here</a
            >
          </p>
        </div>
      </div>
    </div>

    <div class="position-absolute top-0 end-0 mt-2 me-3">
      <button
        id="api"
        type="button"
        class="btn btn-info"
        data-bs-toggle="modal"
        data-bs-target="#KeyModal"
      >
        ADD API KEY
      </button>
    </div>
    <div class="container mt-5">
    <div class="modal fade" id="KeyModal" tabindex="-1" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">
              Your API Key remains stored locally in your browser
            </h5>
          </div>
          <div class="modal-body">
            <div class="form-group">
              <label for="apikey">API KEY</label>
              <input type="text" class="form-control" id="apikey" />
            </div>
          </div>
          <div class="modal-footer">
            <button
              type="button"
              class="btn btn-secondary"
              data-bs-dismiss="modal"
            >
              Close
            </button>
            <button type="button" class="btn btn-primary">Save</button>
          </div>
        </div>
      </div>
    </div>
    </div>
    <!-- main -->
    <div class="container mt-5">
      <!-- alert -->
      <div class="row justify-content-center">
        <div class="col-md-8">
          <div
            class="message alert alert-danger text-center"
            role="alert"
            id="message"
          ></div>
        </div>
      </div>
      <!-- Header -->
      <header class="mt-5">
        <h1 class="text-center">AI Image Generator</h1>
        <p class="lead text-center">
          Bring your vision to life with Generative AI. Simply describe what you
          want to see!
        </p>
      </header>

      <!-- Form -->
      <section class="mt-5">
        <form id="generate-form">
          <div class="row">
            <div class="col-md-9">
              <div class="form-group">
                <input
                  type="text"
                  class="form-control py-2 pb-2"
                  id="prompt"
                  placeholder="A cartoon of a cat catching a mouse"
                />
              </div>
            </div>
            <div class="col-md-3">
              <div class="form-group">
                <button
                  type="submit"
                  class="btn btn-primary btn-lg"
                  id="generate"
                >
                  Generate Image
                </button>
              </div>
            </div>
          </div>
        </form>
      </section>

      <!-- spinner -->
      <div class="spinner-border text-danger" role="status" id="spinner">
     </div>

      <!-- Generated Images -->
      <section class="container mt-5">
        <div class="row justify-content-center" id="gallery">
          
          <!-- images will be displayed here -->

        </div>
      </section>
    </div>
  @import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap");

      body {
        font-family: "DM Mono", monospace;
      }
      h1 {
        font-weight: 900;
      }
      p {
        font-weight: 500;
      }
      .message,
      #spinner {
        display: none;
      }
$("#KeyModal").on("shown.bs.modal", function () {
  const saveButton = document.querySelector("#KeyModal .btn-primary");
  const apiKeyInput = document.querySelector("#apikey");

  saveButton.addEventListener("click", function () {
    const apiKeyValue = apiKeyInput.value;
    localStorage.setItem("API_KEY", apiKeyValue);
    $("#KeyModal").modal("hide");
  });
});

const images = [
  "https://essykings.github.io/JavaScript/cat-mouse.png",
  "https://essykings.github.io/JavaScript/image1.png",
  "https://essykings.github.io/JavaScript/image2.png",
  "https://essykings.github.io/JavaScript/image3.png",
  "https://essykings.github.io/JavaScript/image9.png",
  "https://essykings.github.io/JavaScript/image5.png",
  "https://essykings.github.io/JavaScript/image6.png",
  "https://essykings.github.io/JavaScript/cat.png",
];
const imageGallery = document.getElementById("gallery");
const promptInp = document.getElementById("prompt");
promptInp.addEventListener("input", function () {
  imageGallery.innerHTML = "";
});
const message = document.getElementById("message");

const generateForm = document.getElementById("generate-form");
const spinner = document.getElementById("spinner");

generateForm.addEventListener("submit", async function (e) {
  e.preventDefault();
  const prompt = document.getElementById("prompt").value;
  const key = localStorage.getItem("API_KEY");

  if (!prompt) {
    displayMessage("Please enter a prompt");
    return;
  }

  if (!key) {
    displayMessage(
      "Please add your API KEY. The key will be stored locally in your browser."
    );
    return;
  }

  fetchImage(prompt, key);
});


function displayMessage(msg) {
  message.textContent = msg;
  message.style.display = "block";
  setTimeout(function () {
    message.style.display = "none";
  }, 3000);
}

const fetchImage = async (prompt, API_KEY) => {
  const url = "https://api.openai.com/v1/images/generations";
  const options = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${API_KEY}`,
    },
    body: JSON.stringify({
      model: "dall-e-3",
      prompt,
      n: 1,
      size: "1024x1024",
    }),
  };

  try {
    spinner.style.display = "block";
    const response = await fetch(url, options);
    
    if (!response.ok) {
      const error = await response.json();
      const message = error.error.message ? error.error.message : "Failed to fetch image";
      displayMessage(message);
      return;
    }

    const result = await response.json();
    const imageUrl = result.data[0].url;
    
    displayImage(imageUrl);
  } catch (error) {
    displayMessage("There was an error, please try again");
  } finally {
    spinner.style.display = "none";
  }
};


function displayImage(image) {
  
  const imageMarkup = `
  <div class="row justify-content-center">
      <div class="col d-flex justify-content-center">
          <img src="${image}" class="img-fluid" alt="Placeholder Image">
      </div>
  </div>`;

  imageGallery.innerHTML = imageMarkup;
  
}
function displayImages() {
  const imageMarkup = images
    .map((image) => {
      return `
        <div class="col-12 col-sm-6 col-md-3 mb-4 position-relative" id ="image-container ">
          <img src="${image}" class="img-fluid" alt="Placeholder Image">
        </div>
        `;
    })
    .join("");

  imageGallery.innerHTML = imageMarkup;
}

displayImages();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.