Build a chartGPT clone with TailwindCSS and JavaScript

Build a chartGPT clone with TailwindCSS and JavaScript

How to build a chartGPT clone app

·

20 min read

Hello Dev, in today's project, we are going to be building a chartGPT clone App using TailwindCSS and JavaScript.

Here is the demo of the complete project.

chartGTP clone app with TailwindCSS and JavaScript

you can also download the full project files on GitHub.

Stacked used

We are going to be making use of three different stacks. This includes;

  • Vite: a bundler, to help us set up our project and server for development

  • Tailwindcss: A utility frontend framework for CSS and

  • JavaScript

Prerequisite

Before you attempt this project, you should be familiar with

Project set up

Now that we know what we'll be working with, let's get the project set up.

Vite set up

Create a folder on your desktop and name it Project.

  • Drag and drop it onto VSCode.

  • Next, go to the Terminal section and select New Terminal or press Ctrl + ` (backtick) to open up a new Terminal.

  • Next, type npm create vite@latest and hit enter

  • Next, type chartGTP Demo as the project name and hit enter

  • Next, hit enter to use chartGTP Demo as the package name

  • Next, hit enter to select the Vanilla option on the command prompt

  • Next, hit enter to select JavaScript

  • Next, wait for vite to install and setup the JavaScript environment

Now we have successfully set up JavaScript as indicated above from the VS Code explorer.

You will notice we now have a folder called chartGPT Demo with some files in it.

The next thing we are going to do is follow the instruction on the command prompt to properly install the vite server for development and build process.

  • Firstly type cd "chartGPT Demo" and hit enter to change the directory (note that we use quotes to pass the values that contain space as an argument) to the chartGTP demo folder where our source files are located.

  • Next type npm install and hit enter to install node modules for vite.

  • Now type npm run dev and hit enter to lunch the vite dev server.

From the screenshot above we have the node_modules folder where all the node packages are stored and any other future packages, we are going to install. Also directly from the command line, we have a localhost:5173 as our local host.

Now to lunch the server press Ctrl and then click the port number 5173. This will open up your default browser as shown below.

Tailwindcss set up

Now that we have vite set up and running, the next thing is to install Tailwindcss. Since we are making use of vite.js as our build tool, the best method according to the Tailwindcss Docs is to install Tailwindcss as a PostCSS plugin.

Now follow the process below to stall and set up Tailwindcss

While the vite dev server is still running press Ctrl + C to stop the server and return the command prompt to the project folder.

Next, type npm install -D tailwindcss postcss autoprefixer and then hit enter to install tailwindcss and PostCSS autoprefixer.

  • Next, type npx tailwindcss init and hit enter to generate tailwind.config.cjs file

    From the screenshot, notice we now have a new file named tailwind.config.cjs.

  • Next, create a new file and name it as postcss.config.cjs. Click to open the file and add the tailwindcss and autoprefixer to your postcss.config.js file, or wherever PostCSS is configured in your project.

      module.exports = {
        plugins: {
          tailwindcss: {},
          autoprefixer: {},
        }
      }
    
  • Next, go to the tailwind.config.cjs , click to open, then copy and paste the code below to Configure your template paths and save.

      module.exports = {
        content: [
          "./*.{html,js}"
        ],
        theme: {
          extend: {},
        },
        plugins: [],
      }
    
  • Next, highlight all the CSS code in the style.css file and delete it, then copy and Add the Tailwind directives to your style.css file.

      @tailwind base;
      @tailwind components;
      @tailwind utilities;
    
  • Next, type npm run dev on the terminal and hit enter to start up the build process.

  • Next press Ctrl and click on the localhost number port 5173 to lunch the browser

    From the browser output, notice the change of style from the previous time we launched the browser. This indicates that we now have tailwind successfully installed.

    Structuring the index file

    Now that we have TailwindCSS installed, let's set up the file structure.

  • Create a folder called resources inside the ChartGPT Demo folder.

  • Create two new folders called imgs and pages inside the resources folder respectively.

  • Download the project files from GitHub and copy the SVGs files to the imgs folder as indicated below.

  • Under the pages folder create three files and name them as follows home.html, login.html and signup.html .

  • Your folder structure should look just like the screenshot above. Now delete the counter.js and javascript.svg file.

  • Go to the main.js file and remove the code template, leaving only the import './style.css' rule.

  • Now click on the index.html file

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <link rel="icon" type="image/svg+xml" href="/resources/img/ChatGPT-Green.svg" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>ChartGPT clone APP Demo</title>
        </head>
        <body>
    
        <script type="module" src="/main.js"></script>
        </body>
      </html>
    

Now set up your HTML boilerplate as indicated above

From the browser output, notice we now have the chartGTP icon on the tap bar.

<body class="bg-slate-800">
    <main id="mainPage" class="w-screen h-screen flex justify-center items-center">
      <!-- The Main Section of the page -->
      <section>
        <aside class="flex">
          <!-- ChartGPT Logo -->
          <section>
            <div class="flex justify-center">
              <img src="/resources/imgs/ChatGPT-White.svg" alt="" class="w-8">
            </div>
            <div id="welcomeText">
              <p class="mt-4 text-center text-white text-sm">Welcome to ChartGPT</p>
              <p class="mt-4 text-white text-sm text-center">Log in with your OpenAi account to continue</p>
            </div>
          </section>
        </aside>
        <aside class="mt-4 flex justify-center">
          <a href="/resources/pages/login.html"
            class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-3 rounded-md text-sm mr-2">Log in</a>
          <a href="/resources/pages/signup.html"
            class="bg-teal-500 hover:bg-teal-600 text-white py-2 px-3 rounded-md text-sm">Sign up</a>
        </aside>
      </section>
    </main>
  <script type="module" src="/main.js"></script>
  </body>

From the code sample above, we set the browser viewport to a width and high of 100vw and 100vh respectively. This gave us the space to position the HTML elements at the center of the page.

the <main> the tag serves as the parent tag of all the tags in the index.html document and as a result, we gave it the tailwind class of w-screen h-screen flex justify-center items-center as follows.

Browser Output

Now that the landing page is done, let's create the login and the signup page.

From the pages the folder where we have all the html documents (login.html, signup.html, home.html) located, we need to export the files directly from the tailwind.config.cjs file.

To do this go to the tailwind.config.cjs file and click to open, set the following file path as indicated below.

module.exports = {
  content: [
      "./*.{html,js}",
    "./resources/pages/login.html",
    "./resources/pages/signup.html",
    "./resources/pages/home.html"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Login page

We have completed the first landing page, and it looks the like the regular ChartGPT we all know. In this section, we are going to link the Log in button to the login.html the page we created earlier so that when a user clicks on the login button it takes them to the login page.

Go to the login.html file under pages folder

Type and run the code below

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/resources/imgs/ChatGPT-Green.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ChartGPT | Login</title>
    <meta name="author" content="Alex Anie">
</head>

<style>
    .toast {
        color: orangered;
        font-family: calibri;
        font-weight: bolder;
        font-style: italic;
        position: relative;
    }
</style>

The code above, explains the <head> section of the login page while the CSS rule within the <style> tag is going to be manipulated with JavaScript, now let's see the body.

Type and run the code below.

<body>
    <main class="w-screen flex justify-center">
        <section>
            <!-- Logo Sectioon -->
            <header class="flex justify-center mt-8">
                <img src="/resources/imgs/ChatGPT-Black.svg" alt="" class="w-12">
            </header>

            <!-- Welcome text -->
            <section class="mt-16">
                <h1 class="text-center text-3xl font-bold text-slate-800">Welcome back</h1>
            </section>

            <!-- input tag for email Adress -->
            <section class="">
                <input type="text" placeholder="Email address" class="block w-full h-12 outline-none border-[1.5px] border-slate-300 rounded-sm px-4 mt-4 focus:border-teal-500 placeholder:text-slate-500 placeholder:text-lg">

                <!-- Contnue Button -->
                <a href="/resources/pages/home.html" class="block mt-8 py-4 px-4 bg-teal-500 hover:bg-teal-600 transition-all ease-linear duration-500 text-white rounded-sm text-center" >Continue</a>
            </section>

            <!-- alread have an account [Old users] -->
            <section>
                <p class="mt-2 text-center text-sm">Already have an account? <a href="/resources/pages/signup.html" class="text-teal-500">Sign up</a></p>
                <p>
                    <span id="lineLeft" class="inline-block w-[40%] h-[1px] bg-slate-400"></span> 
                    <!-- <hr /> -->
                    <span class="text-sm relative top-1 px-[1em]">OR</span>
                    <span id="lineRight" class="inline-block w-[40%] h-[1px] bg-slate-400"></span>
                    <!-- <hr /> -->
                </p>
            </section>

            <!-- With with Google or MicroSoft -->
            <section class="mt-8">
                <a target="_blank"  href="https://login.live.com/oauth20_authorize.srf?client_id=7de44aed-c069-4216-a99c-45957f6c4f17&scope=openid+profile+email+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.Read&redirect_uri=https%3a%2f%2fauth0.openai.com%2flogin%2fcallback&response_type=code&state=ZKJ_lJpN-MNKiuGjqTP0fNEIK7QAs7Dz&prompt=login&uaid=637b190176dc410aac576e82c70544f5&msproxy=1&issuer=mso&tenant=consumers&ui_locales=en-US&epct=AQABAAAAAAD--DLA3VO7QrddgJg7WevrZa69udgqAtPldHOL_tIeMaOCbA_6vduqaKSm9OSV7NiBG6syXXVc3A0w5oduhI4Joc_n9IPhkTNihPhhLl59RSDTYGicHdJlaQUz0Ap_FLt1TVtvrtF-a-bVjWG8pXAmmip9VGRWki6e5pWOwkk1jgET9Fpf0s3h1Ckaj7L54FEpNG_fXSpkN1q3-IpTIJX0Eo1Isg9oCtwI1_aTkTsRHSAA&jshs=0#" 

class="block text-sm w-full border-[1.5px] border-slate-400 rounded-t-sm py-4 px-6 hover:bg-slate-200">

<img src="/resources/imgs/microsoft.svg" alt="Microsoft logo" class="w-6 inline-block pr-1"> Continue with Microsoft Account</a>

<a target="_blank"  href="https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?login_hint&prompt=login&response_type=code&redirect_uri=https%3A%2F%2Fauth0.openai.com%2Flogin%2Fcallback&scope=email%20profile&state=L5A9Hk6vb6KkUX6Q5SMjpL7r5mG-STMB&client_id=799222349882-ne3i0s9jdm5s0p7ll2d7tlsi1vc1halt.apps.googleusercontent.com&service=lso&o2v=1&flowName=GeneralOAuthFlow" 

class="block text-sm w-full border-[1.5px] border-slate-400 rounded-t-sm py-4 px-6 mt-4 hover:bg-slate-200">

<img src="/resources/imgs/google-logo.svg" alt="Google logo" class="w-6 inline-block pr-1"> Continue Google 
               </a>
            </section>
        </section>
    </main>

    <script type="module" src="/main.js"></script>
</body>

The code example above is divided into six sections.

  • The logo section: here we linked the ChartGPT SVG logo to the img tag and center it on the page.

  • Welcome text: here we apply a welcome back text.

  • Email Address: here we create an email form

  • Continue Button: here we link login.html to home.html page.

  • Signup: here we link a login.html to signup.html

  • Continue with Microsoft and Google: here we create an external link for both Microsoft and Google user signup options.

Browser output

From the browser output, we have the login page finally set up, if you click on any of the continue or sign up bottom this will take you to an empty page, this is because we have not implemented any code to the two pages.

However Continue with a Microsoft Account or Continue with a google account we take us to an external link, in a new tab.

The new tab is implemented with the target="_blank" property and value.

Signup page

The signup page is very similar to the login page. All we have to do is update the welcome section and change the signup link to login

Try the code below.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/resources/imgs/ChatGPT-Green.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ChartGPT | sign up</title>
    <meta name="author" content="Alex Anie">
    <!-- <script src="https://cdn.tailwindcss.com"></script> -->
</head>

<style>
    .toast {
        color: orangered;
        font-family: calibri;
        font-weight: bolder;
        font-style: italic;
        position: relative;
    }
</style>

<body>
    <main class="w-screen flex justify-center">
        <section>
            <!-- Logo Sectioon -->
            <header class="flex justify-center mt-8">
                <img src="/resources/img/ChatGPT-Black.svg" alt="" class="w-12">
            </header>

            <!-- Account Creation Information -->
            <section class="mt-16">
                <h1 class="text-center text-3xl font-bold text-slate-800">Create your account</h1>
                <p class="mt-4 text-center text-sm">Please note that phone verification is require for</p>
                <p class="text-center text-sm">signup. Your number will only be used to verify</p>
                <p class="text-center text-sm">your identity for security purposes</p>
            </section>

            <!-- input tag for email Adress -->
            <section class="">
                <input id="email" type="text" placeholder="Email address"
                    class="block w-full h-12 outline-none border-[1.5px] border-slate-300 rounded-sm px-4 mt-4 focus:border-teal-500 placeholder:text-slate-500 placeholder:text-lg">

                <span id="floatMessage"></span>

                <!-- Contnue Button -->
                <a href="/resources/pages/home.html"
                    class="block mt-6 py-4 px-4 bg-teal-500 hover:bg-teal-600 transition-all ease-linear duration-500 text-white rounded-sm text-center">Continue</a>
            </section>

            <!-- alread have an account [Old users] -->
            <section>
                <p class="mt-2 text-center text-sm">Already have an account? <a href="/resources/pages/login.html"
                        class="text-teal-500">Log in</a>
                </p>
                <p>
                    <span id="lineLeft" class="inline-block w-[40%] h-[1px] bg-slate-400"></span>
                    <!-- <hr /> -->
                    <span class="text-sm relative top-1 px-[1em]">OR</span>
                    <span id="lineRight" class="inline-block w-[40%] h-[1px] bg-slate-400"></span>
                    <!-- <hr /> -->
                </p>
            </section>

            <!-- With with Google or MicroSoft -->
            <section class="mt-8">
                <a target="_blank" href="https://login.live.com/oauth20_authorize.srf?client_id=7de44aed-c069-4216-a99c-45957f6c4f17&scope=openid+profile+email+https%3a%2f%2fgraph.microsoft.com%2fUser.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.Read&redirect_uri=https%3a%2f%2fauth0.openai.com%2flogin%2fcallback&response_type=code&state=ZKJ_lJpN-MNKiuGjqTP0fNEIK7QAs7Dz&prompt=login&uaid=637b190176dc410aac576e82c70544f5&msproxy=1&issuer=mso&tenant=consumers&ui_locales=en-US&epct=AQABAAAAAAD--DLA3VO7QrddgJg7WevrZa69udgqAtPldHOL_tIeMaOCbA_6vduqaKSm9OSV7NiBG6syXXVc3A0w5oduhI4Joc_n9IPhkTNihPhhLl59RSDTYGicHdJlaQUz0Ap_FLt1TVtvrtF-a-bVjWG8pXAmmip9VGRWki6e5pWOwkk1jgET9Fpf0s3h1Ckaj7L54FEpNG_fXSpkN1q3-IpTIJX0Eo1Isg9oCtwI1_aTkTsRHSAA&jshs=0#"
                    class="block text-sm w-full border-[1.5px] border-slate-400 rounded-t-sm py-4 px-6 hover:bg-slate-200">
                    <img src="/resources/img/microsoft.svg" alt="Microsoft logo" class="w-6 inline-block pr-1">
                    Continue with Microsoft Account
                </a>
                <a target="_blank" href="https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?login_hint&prompt=login&response_type=code&redirect_uri=https%3A%2F%2Fauth0.openai.com%2Flogin%2Fcallback&scope=email%20profile&state=L5A9Hk6vb6KkUX6Q5SMjpL7r5mG-STMB&client_id=799222349882-ne3i0s9jdm5s0p7ll2d7tlsi1vc1halt.apps.googleusercontent.com&service=lso&o2v=1&flowName=GeneralOAuthFlow"
                    class="block text-sm w-full border-[1.5px] border-slate-400 rounded-t-sm py-4 px-6 mt-4 hover:bg-slate-200">
                    <img src="/resources/img/google-logo.svg" alt="Google logo" class="w-6 inline-block pr-1"> Continue
                    Google
                </a>
            </section>
        </section>
    </main>

    <script type="module" src="/main.js"></script>
</body>

</html>

Browser Output

From the browser output, we updated the welcome heading and paragraph text and we also change the signup button to login button

Home page

The home section is divided into two sections, one of which are models that are loaded immediately after the page loads and then the main home page that displays the navigation, buttons and search box for our website.

Now let's see how to create the models.

Model landing page

Before we start creating the models, we have to create a background overlay for the model, so the model can be positioned directly above the overlay.

Now let's create the model overlay.

<div id="overlay" class="w-[100vw] h-[100vh] bg-black opacity-80 absolute z-[-1]"></div>

The tailwind class of z-[-1] is equal to z-index: -1; in vanilla CSS. This will help take the overlay to the back of the model.

Browser output

From the browser output, we have a dark overlay. Now let's create our model. If you've used chartGPT before now you will notice that the model is three in one.

Here is a simple demo.

So we are going to build the three models and then use JavaScript to add interactivity so that we can switch between the models using buttons.

Model One

Directly below the overlay tag, we are going to create a div tag, to wrap around the three models.

Type the code below

<div id="wrapper" class="w-[100vw] h-[100vh]  justify-center items-center">
<!--THE THREE MODEL GOES HERE-->
</div>

The next thing to do is to create the first model and nest it inside the <div> tag with an id of wrapper. This tag will serve as the parent tag for the three models we will be building.

  <!-- FIRST MODEL -->
        <main id="modelFirst" class="w-[30%] bg-[#1c1d22] text-white text-sm py-4 px-4 rounded-md">
            <section>
                <!-- Header section -->
                <header>
                    <h1 class="text-xl font-bold my-2">ChatGPT</h1>
                    <hr class="border-[1px] border-[#525361]" />
                </header>

                <!-- Body Section -->
                <div>
                    <p class="font-bold mt-4">This is a free research preview.</p>
                    <div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
                        <div class="text-[1.5em] mr-4 mt-2">🔬</div>
                        <div>Our goal is to get external feedback in order to improve our systems and make them safer.</div>
                    </div>

                    <div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
                        <div class="text-[1.5em] mr-4 mt-8">🚨</div>
                        <div>While we have safeguards in place, the system may occasionally generate incorrect or misleading
                            information and produce
                            offensive or biased content. It is not intended to give advice</div>
                    </div>
                </div>

                <!-- button section -->
                <div class="flex justify-end">
                    <button id="modelBtnFirst"
                        class=" bg-[#32333b] rounded-md p-2 mt-4 mb-2 border-[1px] border-[#525361]">Next</button>
                </div>
            </section>
        </main> <!--End of First Section-->

Browser output

From the browser output, we now have our first model.

Model Two

The second model is exactly like the previous one we've done.

Type and run the code below.

 <!-- SECOND MODEL -->
        <main id="modelSecond" class=" w-[30%] bg-[#1c1d22] text-white text-sm py-4 px-4 rounded-md">
            <section>
                <!-- Header section -->
                <header>
                    <h1 class="text-xl font-bold my-2">ChatGPT</h1>
                    <hr class="border-[1px] border-[#525361]" />
                </header>

                <!-- Body Section -->
                <div>
                    <p class="font-bold mt-4">How we collect data</p>
                    <div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
                        <div class="text-[1.5em] mr-4 mt-2">🦾</div>
                        <div>Conversations may be reviewed by our AI trainers to improve our systems.</div>
                    </div>
<div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
  <div class="text-[1.5em] mr-4 mt-2">🔐</div>
   <div>Please don't share any sensitive information in your conversations.</div>
 </div>
 </div>

                <!-- button section -->
                <div class="flex justify-between">
                    <button id="modelBtnSecondBack"
                        class="bg-[#32333b] rounded-md p-2 mt-4 mb-2 border-[1px] border-[#525361]">Back</button>

                    <button id="modelBtnSecondNext"
                        class=" bg-[#32333b] rounded-md p-2 mt-4 mb-2 border-[1px] border-[#525361]">Next</button>
                </div>
            </section>
        </main> <!--End of second section-->

Browser output

From the browser output, we have the two models side by side. This is because we already set the parent element to flex.

Model Three

Now let's see how to add the third model.

Type and run the code below.

<!-- THIRD SECTION -->
        <main id="modelThird" class=" w-[30%] bg-[#1c1d22] text-white text-sm py-4 px-4 rounded-md">
            <section>
                <!-- Header section -->
                <header>
                    <h1 class="text-xl font-bold my-2">ChatGPT</h1>
                    <hr class="border-[1px] border-[#525361]" />
                </header>

                <!-- Body Section -->
                <div>
                    <p class="font-bold mt-4">We'd love your feedback!</p>
                    <div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
                        <div class="text-[1.5em] mr-4 mt-2">👍</div>
                        <div>This system is optimized for dialogue. Let us know if a particular response was good or
                            unhelpful.
                        </div>
                    </div>

                    <div class="flex justify-center bg-[#32333b] rounded-md p-2 mt-2">
                        <div class="text-[1.5em] mr-4 mt-2">💬</div>
                        <div>Share your feedback in our
                            <a href="https://discord.com/invite/openai" target="_blank" class="font-bold">Discoud server</a>
                        </div>
                    </div>
                </div>

                <!-- button section -->
                <div class="flex justify-between">
                    <button id="modelBtnThirdBack"
                        class="bg-[#32333b] rounded-md p-2 mt-4 mb-2 border-[1px] border-[#525361]">Back</button>

                    <button id="modelBtnThirdDone"
                        class="bg-teal-500 rounded-md p-2 mt-4 mb-2 border-[1px] border-[#525361]">Done</button>
                </div>
            </section>
        </main><!--The End of the Third Section-->

Browser Output

From the browser output, we have three models stacked beside each other. However, our main goal is to position model one in the center of the page and use the back and next buttons to toggle between the other two models

Now we are done with the first section, let's go to the next section. Before that, we have to set the models and the overlay to hidden so that we can use JavaScript DOMContentLoaded to set the overlay and model to block as soon as the HTML is loaded.

So the overlay, div and the parent tag (main tag) of the model should be set to hidden.

Consider the code example below.

<!--Add "hidden" to this class-->
<!--The overlay tag-->
<div id="overlay" class="hidden w-[100vw] h-[100vh] bg-black opacity-80 absolute z-[-1]"></div>

<!-- Change "flex" to "hidden"-->
<div id="wrapper" class="hidden w-[100vw] h-[100vh]  justify-center items-center">

<!-- The first model pop -->
<main id="modelFirst" class="hidden w-[30%] bg-[#1c1d22] text-white text-sm py-4 px-4 rounded-md">

The code sample above should be used as a reference, to know where the hidden class should be placed within the elements.

Browser output

From the browser output, we have an empty page display. This is because the element has been removed from the document tree.

The next step is to create the main home page layout and then style it.

The main home page

The home page is made up of two sections, the left and the right to be specific. The left is the navigation of the page while the right search and hero section.

THE LEFT SECTION:

Type and run the code below.

  <!-- The Home Page Left section-->
<main>
 <div id="" class="flex flex-row">
 <aside id="sideBarLeft" class="w-[20%] bg-[#1c1d22] text-white pl-4 pr-2"> <hr /> 
  <section> 
     <section>
                 <!-- Delete Icon and Section [START]-->
<a href="" class="text-sm block mb-4 hover:bg-[#242633] py-4 px-2 hover:rounded-md"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 inline-block mr-2"> <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
</svg>Clear conversation </a>

                        <!-- Light and Dark Mode Icon-->
<a href="" class="text-sm block mb-4  hover:bg-[#242633] py-4 px-2 hover:rounded-md">
 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 inline-block mr-2"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" /> </svg>
Light Mode </a>

                        <!-- Discord Icon -->
<a href="https://discord.com/invite/openai" target="_blank" class="text-sm block mb-4  hover:bg-[#242633] py-4 px-2 hover:rounded-md">
<img src="/resources/imgs/discord white.svg" alt="" class="w-4 h-4 inline-block mr-2 text-white">
OpenAI Discord </a>

                   <!-- Learn more and update Icon -->
<a href="https://help.openai.com/en/collections/3742473-chatgpt" target="_blank" class="text-sm block mb-4  hover:bg-[#242633] py-4 px-2 hover:rounded-md"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 inline-block mr-2"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" /> </svg> Updates & FAQ </a>

                        <!-- Log out section -->
<a href="/index.html" class="text-sm block mb-4  hover:bg-[#242633] py-4 px-2 hover:rounded-md"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 inline-block mr-2"> <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9" /> </svg> Log out </a>
 </section>
</section>
</aside>

Browser Output

From the browser output, we have the page navigation set to the left of the page.

Now let's create the right section.

THE RIGHT SECTION:

Type and run the code below.

<!--end of the left section-->

            <!-- [RIGHT ====== BAR]||(Alex Anie) -->
            <!-- Right Side Bar section -->
            <section id="sideBarLeft" class="w-[80%] h-screen bg-[#33374d]  text-white text-sm pt-[8em]">
                <main class="flex justify-center w-[70%] mx-auto">
                    <section>
                        <div class="flex justify-center text-[2.5em] font-medium mb-[2em]">
                            <h1>ChatGPT</h1>
                        </div>

                        <!-- Example Section -->
 <div>
 <div class="grid grid-cols-3 gap-3">
<main class="grid gap-y-3">
  <section>
     <div class="flex justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
  stroke-width="1.5" stroke="currentColor" class="w-8 h-8">
 <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
  </svg> </div>
 <p class="text-center text-xl">Examples</p> </section> <section class="bg-[#4d5168] rounded-md"> <a href=""
 class="text-center inline-block py-2 px-1 hover:bg-[#15161f]  hover:rounded-md">"Explain quantum computing in simple terms" →</a>
 </section> <section class="bg-[#4d5168] rounded-md"> <a href=""
   class="text-center inline-block py-2 px-1 hover:bg-[#15161f]  hover:rounded-md">"Got any creative ideas for a 10 year old's birthday?" →</a> </section>
 <section class="bg-[#4d5168] rounded-md">
  <a href="" class="text-center inline-block py-2 px-1 hover:bg-[#15161f]  hover:rounded-md">"How do I make an HTTP request in JavaScript" →</a>
 </section>
 </main>

                                <!-- Capability Section -->
<main class="grid gap-y-3">
 <section>
<div class="flex justify-center">
 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
 stroke-width="1.5" stroke="currentColor" class="w-8 h-8">
 <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" />
 </svg>
 </div>
 <p class="text-center text-xl">Capabilities</p>
 </section> <section class="bg-[#4d5168] rounded-md">
 <a class="text-center inline-block py-2 px-1">Remembers what user said earlier in the conversation</a>  </section> <section class="bg-[#4d5168] rounded-md"> <a class="text-center inline-block py-2 px-1">Allows user to provide follow-up corrections</a> </section> <section class="bg-[#4d5168] rounded-md"> <a class="text-center inline-block py-2 px-1">Trained to decline inappropriate requests</a> </section>
</main>

                            <!-- Limitation -->
 <main class="grid gap-y-3">
  <section>
 <div class="flex justify-center">
 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
  stroke-width="1.5" stroke="currentColor" class="w-8 h-8"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /> </svg>
 </div>
 <p class="text-center text-xl">Limitations</p>
 </section>
 <section class="bg-[#4d5168] rounded-md"> <a class="text-center inline-block py-2 px-1">May occasionally generate incorrect information</a> </section> <section class="bg-[#4d5168] rounded-md"> <a class="text-center inline-block py-2 px-1">May occasionally produce harmful instructions or biased content</a>
</section> <section class="bg-[#4d5168] rounded-md">
<a class="text-center inline-block py-2 px-1">Limited knowledge of world and events after 2021</a> </section> </main> </div>
 </div>
 </section>
 </main>
                <!-- [INPUT SECTION] -->
                <!-- Input Searh bar -->
<main class="w-[80%] mx-auto mt-[4em]">
 <div class="w-[90%] mx-auto h-12 bg-[#3a3e57] rounded-md shadow-xl"> <input type="search" class="bg-transparent outline-none w-[95%] px-4 h-full rounded-md"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
 class="w-6 h-6 inline-block text-slate-500 tran rotate-[-45deg] hover:bg-gray-900 p-1 rounded-md cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5" />
 </svg>
 </div>
<div>
<p class="text-slate-300 mt-4 text-xs text-center">
 <a href="https://help.openai.com/en/articles/6825453-chatgpt-release-notes" target="_blank" class="underline">ChatGPT Jan 9 Version.</a> Free Research Preview. Our goal is to make AI systems more natural and safe to interact with. Your feedback will help us improve.
</p>
</div>
<div id="scrollIcon">
</div> </main>
</section>
</div>
</main>

Browser Output

From the browser output, we have the right section displayed.

Now we have completed the UI design. The next thing to do is to add JavaScript.

Adding JavaScript

Head onto the main.js file and then click to open. Once you've done that, type the code below.

//-> main.js
// EMAIL: This section create an alert for Email not required!
const floatPopUp = document.querySelector('#floatMessage');
const email = document.querySelector('#email');

function floatMessage(){
floatPopUp.innerHTML = `<span class="toast">Your Email is not required! click Continue to login</span>`;
email.classList.replace('focus:border-teal-500', 'focus:border-red-600');
}
email.addEventListener('keydown', floatMessage);

From the code example above, we create a function to parse in an error message of "Your Email is not required! click Continue to login". So that users will click on the continue bottom instead of providing an email that is not needed and if they do, they will get a display error message.

Browser output

From the browser output, we have the error message displayed. To see this error message in action, press any character keys on your keyboard.

Now that we have our error messages out of the way. We are going to target the models and create a function that parses in the document to the DOM as soon as the page loads.

Try the code example below.

//-> main.js
// MODEL: This section creates an model pop when the page loods
/*first model pop variables*/
const modelBtnFirst = document.querySelector('#modelBtnFirst');
const modelFirst = document.querySelector('#modelFirst');
const wrapper = document.querySelector('#wrapper');

/*-------------------------------------------------------------------*/
/*second model pop variables*/
const modelSecond = document.querySelector('#modelSecond');
const modelBtnSecondBack = document.querySelector('#modelBtnSecondBack');
const modelBtnSecondNext = document.querySelector('#modelBtnSecondNext');

/*-------------------------------------------------------------------*/
/*Third model pop variables*/
const modelThird = document.querySelector('#modelThird');
const modelBtnThirdBack = document.querySelector('#modelBtnThirdBack');
const modelBtnThirdDone = document.querySelector('#modelBtnThirdDone');
/*overlay displaay background*/
const overlay = document.querySelector('#overlay');

From the code example above, we targeted the necessary element and assign them to a variable.

Now consider the code sample below.

// WINDOW: This section loads the pop model on DOMContnentLoad event
document.addEventListener('DOMContentLoaded', ()=>{
    overlay.classList.remove('hidden');
    modelFirst.classList.remove('hidden');
    wrapper.classList.replace('hidden','flex');

    // console.log(overlay);
});

// Set the first Model to hidden and Remove Hidden from the second element
/* Move to the second Model*/
modelBtnFirst.addEventListener('click', ()=>{
    modelFirst.classList.add('hidden');
    modelSecond.classList.remove('hidden');
});

/* Move back to the first Model*/
modelBtnSecondBack.addEventListener('click', ()=>{
    modelSecond.classList.add('hidden');
    modelFirst.classList.remove('hidden');
});

// Set the Second element to hidden and remove hidden from the third element
/* Move Next to the third Model*/
modelBtnSecondNext.addEventListener('click', ()=>{
    modelSecond.classList.add('hidden');
    modelThird.classList.remove('hidden');
});

/* Move Back to the Second Model*/
modelBtnThirdBack.addEventListener('click', ()=>{
    modelThird.classList.add('hidden');
    modelSecond.classList.remove('hidden');
});

// Set all elements of the Model to Hidden
/* set the Done button to set all element to none*/
modelBtnThirdDone.addEventListener('click', ()=>{
    modelThird.classList.add('hidden');
    overlay.classList.add('hidden');
    wrapper.classList.replace('flex','hidden');
});

From the code sample above, we DOMContentLoaded to perse the overlay and model elements to the DOM tree as the page loads.

Browser Output

From the browser output, we have the complete project displayed.

Summary

We learned about how to create a chartGPT clone using the following.

  • Vite.js

  • TailwindCSS

  • Vanilla JavaScript

Alright! We’ve come to the end of this tutorial. Thanks for taking the time to read this article to completion. Feel free to ask questions. I’ll gladly reply. You can find me on Twitter and other social media @ocxigin.

#Cheers