Introduction
Welcome to our comprehensive tutorial where we dive deep into creating a dynamic web application using React, Express, and the ChatGPT API. Whether you're a beginner looking to get started or an experienced developer aiming to expand your skill set, this video has something for everyone!
This is a list 1
this is a list 2
this is a list 3
🔍 What You'll Learn:
Setting Up Your Development Environment
A refresher on React components, state management, and hooks.
Learn how to set up an Express server and integrate it with React.
We'll show you how to make your application interactive by integrating OpenAI's ChatGPT.
Tips on connecting your React frontend with your Node.js backend effectively.
🛠️ Tools and Technologies:
React.js
Node.js + Express
ChatGPT API by OpenAI
Additional libraries and tools like Axios for API requests
index.js
const PORT = 3800;
const CHAT_API_KEY = process.env.CHAT_API_KEY;
const express = require('express');
const cors = require('cors');
const app = express();
app.use(express.json());
app.use(cors());
app.post('/completions', async (req, res) => {
const { body } = req;
const message = body.message;
const data = await postFetch(message);
res.send(data.choices[0]);
});
app.listen(PORT, () => {
console.log(`Server running on port:${PORT}`)
});
async function postFetch(message) {
const options = {
method: 'POST',
headers: {
'Authorization': `Bearer ${CHAT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: message }],
max_tokens: 50
})
}
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', options);
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
return null;
}
}
chat-app.js
import React, { useState, useRef, useEffect } from 'react';
import { ReactComponent as ChatLogo } from '../images/chat-svg.svg';
import { ReactComponent as Arrow } from '../images/arrow.svg';
import Profile from '../images/user.jpg'
function ChatApp() {
const messagesEndRef = useRef<HTMLHRElement | null>(null);
const [userMessage, setMessage] = useState<string>('');
const [messages, setMessages] = useState<{ user: string, assistant: string }[]>([{ user: 'What is 2 + 2 ?', assistant: 'It is 4.' }, { user: 'How many days in a week?', assistant: 'There are 7.' }])
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const completion = await postFetch(userMessage as string)
if (completion && completion.message) {
const res = { user: userMessage, assistant: completion.message.content }
setMessages(prevMessages => [...prevMessages, res])
}
setMessage('');
}
useEffect(() => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
}
}, [messages]);
return (
<div className=' h-screen bg-orange-500 flex'>
<section className=' bg-gray-900 basis-1/4 px-2 py-2'>
<button className=' border border-white p-2 text-white rounded-lg w-full'>+ New chat</button>
</section>
<section className=' bg-gray-700 basis-3/4 flex flex-col px-2 py-4 justify-between'>
<h1 className='text-white text-center'>EGPT</h1>
<div className=' px-4'>
<ul className=' list-disc ml-2 text-gray-400 overflow-auto max-h-[700px]'>
{
messages && messages.map((m, index) => <li className='flex flex-col space-y-6 my-4' key={`${m}-${index}`}>
<div className='flex items-center space-x-4'>
<img className=' rounded-full' width={40} src={Profile} alt="user profile" />
<span>{m.user} </span>
</div>
<div className='flex items-center space-x-4 pl-6 m'>
<ChatLogo />
<span>{m.assistant}</span>
</div>
<hr ref={messagesEndRef} className=' border-gray-500' />
</li>)
}
</ul>
</div>
<form onSubmit={handleSubmit} className="flex min-h-16 border border-gray-500 rounded-xl space-x-4 ">
<button className="flex flex-col justify-center items-center bg-gray-500 rounded-l-xl px-2"><Arrow /></button>
<div className=" h-full flex w-full">
<input autoComplete='false' value={userMessage} onChange={(e) => setMessage(e.target.value)} name="message" className=" w-full bg-transparent text-gray-300 focus:outline-none" type="text" placeholder="Message EGPT..." />
</div>
</form>
</section>
</div>
)
}
export default ChatApp;
async function postFetch(message: string) {
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({ message });
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow" as RequestRedirect
};
try {
const response = await fetch("http://localhost:3800/completions", requestOptions);
const result = await response.text();
return JSON.parse(result);
} catch (error) {
console.log('error:', error);
}
}