Build a chartGPT clone with TailwindCSS and JavaScript
How to build a chartGPT clone app
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.
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
vite.js and
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 enterNext, type
chartGTP Demo
as the project name and hit enterNext, hit enter to use
chartGTP Demo
as the package nameNext, hit enter to select the
Vanilla
option on the command promptNext, 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 fileFrom 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 thetailwindcss
andautoprefixer
to yourpostcss.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 yourstyle.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 thelocalhost
number port5173
to lunch the browserFrom 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 theChartGPT Demo
folder.Create two new folders called
imgs
andpages
inside theresources
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 followshome.html
,login.html
andsignup.html
.Your folder structure should look just like the screenshot above. Now delete the
counter.js
andjavascript.svg
file.Go to the
main.js
file and remove the code template, leaving only theimport './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
tohome.html
page.Signup: here we link a
login.html
tosignup.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