How to develop a Chat App using RedisJSON and Next JS from scratch.
Muhammad Bilal
Full-stack Engineer Proficient in Next.js, React, TypeScript, TailwindCSS, React Native, Node.js,FastAPI, Postgresql and NoSQL databases.
Important Note:
This article was written 1 year ago and the genocide of palestinian people which is happening currently is strongly condemnable and can never be just justified at any stage.
Why I am writing this article?
Today one to one online communication between the world is present due to the presence of chat applications. We see these chat applications in different formats like Google chat, Whatsapp, messenger, and telegram and there are plenty of examples that could be given in this regard.
When a developer sees anything he is inspired and wants to create a similar thing like that because our curiosity takes us to think about the algorithm and logic behind these applications and the overall functionality of how they work. That's how developers live.
No curiosity = No Learning = No creativity = No development= No progress
We don't exist to only take the pay for what we code but what keeps us interested in development is the idea to understand the logic between amazing things that are developed and how we can develop them on our own. That's the reason I have planned to write a step-by-step but to-the-point process of creating the chat application.
We will be using Redis JSON and Node JS, and Express JS on the backend for the database part. While in the front end I will use Next JS with type script but you can use React JS also if you know about React.
Why Choose Redis?
Watch out for this video on why to choose Redis as your Database:
Source Code
Pre-Requisites:
You need to have the following things installed on your system:
What we will cover?
Redis, Redis Enterprise and Redis JSON?
1) Redis
2) RedisJSON
3) Redis Enterprise
With Redis Enterprise,?you can use Redis as both an in-memory cache and a primary database in a single system, thus eliminating the complexity and latency of two separate systems because mostly Redis is used?as a cache to make traditional databases faster.
Redis Enterprise Cloud has modules like RedisJSON and RediSearch that are sufficient to be used as a main single database. RedisJSON has this capability.
What is a RESTFUL API or a REST API?
The REST(Representational state transfer) APIs are there to fill the communication gap between databases and the application. Because Databases like Redis, Mongo DB, SQL, My SQL, Postgres SQL and many other databases are not able to communicate directly with the application without the use of APIS. They play a vital role in application development. The direct is impossible due to security concerns that APIs are restricted to perform only specific actions like CREATE, READ, UPDATE and DELETE more specifically known as CRUD.
The HTTP methods like GET, POST, PUT, DELETE are used as a binding material with the rest APIs to create a bridge for the communication between databases and the application.
Here is a picture of how it works
While some of you may be thinking that firebase's real-time database, firestore, and Supabase does not require the Restful APIS to be created. The reason for this is that the operations we perform on these databases also use microservices like REST or maybe SOAP(Simple Object Access Protocol) but they are hidden from us and we are only provided with the APIs directly and we don't have to build the API for interacting with these databases. So the conclusion is that regardless of what database you are using. A microservice such as REST or SOAP etc needed to interact with any database.
If you are interested in learning more about REST. Here is an article explaining the REST Api in simple explanation:
If I would go into more detail this article will be too long so if you are interested in learning about REST you can check these explanations. Here is a video explaining the concept of Rest API.
Chat App Logic building
Here are the four main components(building blocks) of chat
Understanding the logic:
Suppose we have this interface for our chat app after logging in. In this app, we will use this interface.
Now in the next step if I select any user from the user's list. Note that there must be two users registered in our app because chat can be between any two users. So at least two users must be there so they can communicate with each other. Now I select MuhammadBilal
from the users list from the left menu so that this will be the interface after that.
Here Suppose
bilal is the logged-in user --> Sender
MuhammadBilal is the user name of the receiver --> Receiver
Now suppose Sender(bilal) is sending a message 'Hello MuhammadBilal' and the receiver is MuhammadBilal here is how it works. Look at the below picture.
Now for the receiver MuhammadBilal to give a reply to the sender bilal first of all he has to log in using his account login information like username and password Then he will be able to reply to the sender. So for this first of all MuhammadBilal login's into his account and then finds this interface.
Now select the user bilal and this interface will appear.
Now if MuhammadBilal(sender) sends a message 'Hi bilal I am available' then this message will appear as below in the interface of the Login user MuhammadBilal.
Now let's have a look at the database chatSchema.
export const chatSchema = new Schema(Chat,{
? ? userIDSender: {
? ? ? ? type: 'string'
? ? },
? ? userNameSender: {
? ? ? ? type: 'string'
? ? },
? ? userIDReceiver: {
? ? ? ? type: 'string'
? ? },
? ? userNameReceiver: {
? ? ? ? type: 'string'
? ? },
? ? message: {
? ? ? ? type: 'string'
? ? },
? ? timeSent: {
? ? ? ? type: 'string'
? ? },
? ? isUserOnline: {
? ? ? ? type: 'boolean'
? ? },
}, {
? ? dataStructure: 'JSON'
});
Now the following is the Array of Objects of chat data after we have sent some messages above:
[? ?
{
? ? ? ? userIDSender: "01GCF640M1VMS3GQ9FZW07HRY2",
? ? ? ? userNameSender: "MuhammadBilal",
? ? ? ? userIDReceiver: "01GCK5A1K7NH3RT30S2JPK53DH",
? ? ? ? userNameReceiver: "bilal",
? ? ? ? message: "Hi bilal I am available",
? ? ? ? timeSent: "9/15/2022, 11:22:43 AM",
? ? ? ? isUserOnline: true
? ? },
? ? {
? ? ? ? userIDSender: "01GCK5A1K7NH3RT30S2JPK53DH",
? ? ? ? userNameSender: "bilal",
? ? ? ? userIDReceiver: "01GCF640M1VMS3GQ9FZW07HRY2",
? ? ? ? userNameReceiver: "MuhammadBilal",
? ? ? ? message: "Hello MuhammadBilal",
? ? ? ? timeSent: "9/10/2022, 5:56:21 PM",
? ? ? ? isUserOnline: true
? ? }
]
Note that the user's list is a separate array of user objects. The user list is the list of registered users displayed on the left sidebar.
So in order to show the above array of chat objects data in the proper format to each user, we have to categorize the messages into two categories as I have shown in the interface Sent and Received messages. as shown below
{(item.userIDSender === JSON.parse(localStorage.getItem('loggedInUserData')).id && item.userIDReceiver === currentSelectedUser.id) ? (? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="insideMainContainerChatSender" key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Sent</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxHeader">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-primary">{item.userNameSender}</h5>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6 className="text-secondary">{item.timeSent}</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxBody">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p className="text-dark">{item.message}</p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
2. Now categorize messages based on the Received category. The following condition will be used.
{(item.userIDReceiver === JSON.parse(localStorage.getItem('loggedInUserData')).id && item.userIDSender === currentSelectedUser.id) ? ( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ?<>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="insideMainContainerChatReceiver" key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Received</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxHeader">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-primary">{item.userNameSender}</h5>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6 className="text-secondary">{item.timeSent}</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxBody">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p className="text-dark">{item.message}</p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
Initial Setup
1) SignUp for the Redis Cloud
?The fastest way to start using the Redis database is to utilize their free tier on?Redis Enterprise Cloud .
You will see this page.
领英推荐
Then follow this video tutorial.
Now, in the end, you must have the following things:
"You must have copied your endpoint instead of this one".
"You must have your UserName and Password for the user you have created in the Data Access Control".
Please do note that the username and password you are giving to a user you must remember and save it in a safe place because we will be using this?username?and?password?for getting the access to the redis database from our?Node JS?backend javascript based server code base.
Initial Setup is completed here. Now we can create the front-end part.
Writing the front-end part.
The front end is created in typescript and Next JS .
The chat app will contain the following pages
2. Login Page
3. Registration Page
1) Creating a new next js application.
As I said earlier I will do everything from scratch nothing complex. I will do everything from the beginning like I am teaching this to a person who knows nothing about the subject matter. Let's create our next js application.
The terminal will be opened. Type the following command in the cmd and press enter
npx create-next-app redischatapp
A new next js app named redischatapp will be created and the required packages download will be started.
After all the packages have been downloaded now you should navigate into the app redischatapp directory and start the project by npm run dev. On the same terminal where you created a new next js app recently type the following command.
cd redischatapp && npm run dev
The project will be started at the URL localhost:3000 . If you will paste this link localhost:3000 in the browser you will see the next js start up page.
Your terminal will be like this after stating the project:
2) Writing our front-end code for the chat app.
code .
Adding Mdbootstrap Library for styling
// File Relative Path: pages/_app.tsx
import type { AppProps } from 'next/app';
import Head from 'next/head';
import Script from 'next/script';
//Importing Containers CSS Files
import '../styles/globals.css';
import "../styles/ContainerCss/Home.css";
import "../styles/ContainerCss/Chat.css";
//Importing Component CSS Files
import "../Components/Footer/style.css";
import "../Components/Header/style.css";
import "../Components/Chat/UsersList/style.css";
function MyApp({ Component, pageProps }: AppProps) {
? return (
? ? <>
? ? ?<Head>
? ? ? <meta charSet="utf-8" />
? ? ? <meta name="description" content="A chat app built with Next JS,redis,Node JS and Express" />
? ? ? <meta name="keywords" content="ChatApp,NextJS,Redis,NodeJS,Express,Realtime" />
? ? ? <meta name="author" content="Muhammad-Bilal-7896" />
? ? ? <meta name="viewport" content="width=device-width, initial-scale=1" />
? ? ? <meta name="theme-color" content="#000000" />
? ? ? <title>Redis Chat App</title>
? ? </Head>
? ? <Component {...pageProps} />
? ? <Script
? ? ? type="text/javascript"
? ? ? src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/3.5.0/mdb.min.js"
? ? ></Script>
? ? </>
? )
}
export default MyApp;
In the latest next js versions, the script tags are deprecated, and instead of script Script tags from next js are preferred.
// File Relative Path: pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
const Document = () => {
? ? return (
? ? ? ? <Html>
? ? ? ? ? ? <Head>
? ? ? ? ? ? ? ? {/* Font Awesome */}
? ? ? ? ? ? ? ? <link rel="stylesheet" />
? ? ? ? ? ? ? ? {/* Google Fonts */}
? ? ? ? ? ? ? ? <link rel="stylesheet" />
? ? ? ? ? ? ? ? {/* MDB */}
? ? ? ? ? ? ? ? <link rel="stylesheet" />
? ? ? ? ? ? ? ? {/* <!-- MDB --> */}
? ? ? ? ? ? </Head>
? ? ? ? ? ? <body>
? ? ? ? ? ? ? ? <Main />
? ? ? ? ? ? ? ? <NextScript />
? ? ? ? ? ? </body>
? ? ? ? </Html>
? ? )
}
export default Document;
Now Mdbootstrap is added successfully to our project.
Writing the front-end part.
a) Home Page
// Relative Path: pages\index.tsx
import { useEffect, useState } from "react";
import Head from 'next/head';
import Link from 'next/link';
//Importing Compoents
import Header from '../Components/Header';
import Footer from '../Components/Footer';
import UsersList from "../Components/Chat/UsersList";
function Home() {
? const [isSSR, setIsSSR] = useState<boolean>(false);
? const [chatList, setChatList] = useState<any>([]);
? const [currentSelectedUser, setCurrentSelectedUser] = useState<any>(null);
? //VALUES
? // userIDSender: this.userIDSender,
? // userNameSender: this.userNameSender,
? // userIDReceiver: this.userIDReceiver,
? // userNameReceiver: this.userNameReceiver,
? // message:this.message,
? // timeSent:this.timeSent,
? // isUserOnline:this.isUserOnline
? const [message, setMessage] = useState<string>('');
? //VALUES
? const [userData, setUserData] = useState<any>(null);
? const [loggedInUserData, setLoggedInUserData] = useState<any>(null);
? const [isSignedIn, setIsSignedIn] = useState<boolean>(false);
? useEffect(() => {
? ? //For Realtime Updates
? ? setInterval(() => {
? ? ? fetchDataFromAPIGetChat();
? ? ? fetchDataFromAPIGETOfUsers();
? ? }, 1000);
? ? // setLoggedInUserData(loggedUserData);
? }, []);
? function fetchDataFromAPIGetChat() {
? ? if (typeof window !== "undefined") {
? ? ? (async () => {
? ? ? ? const response = await fetch('https://localhost:8000/chat', {
? ? ? ? ? method: 'GET',
? ? ? ? ? headers: {
? ? ? ? ? ? accept: 'application/json',
? ? ? ? ? }
? ? ? ? });
? ? ? ? const content = await response.json();
? ? ? ? setChatList(content);
? ? ? })();
? ? }
? }
? function fetchDataFromAPIGETOfUsers() {
? ? if (typeof window !== "undefined") {
? ? ? (async () => {
? ? ? ? const response = await fetch('https://localhost:8000/user/', {
? ? ? ? ? method: 'GET',
? ? ? ? ? headers: {
? ? ? ? ? ? accept: 'application/json',
? ? ? ? ? }
? ? ? ? });
? ? ? ? const content = await response.json();
? ? ? ? setUserData(content);
? ? ? })();
? ? }
? }
? function getLoggedInUserData() {
? ? console.log("user data: ", userData);
? ? if (userData !== null) {
? ? ? for (let i = 0; i < userData.length; i++) {
? ? ? ? if (userData[i].isSignedIn === true) {
? ? ? ? ? console.log("userData Specific is equal to : ", userData[i]);
? ? ? ? ? // setLoggedInUserData(userData[i]);
? ? ? ? ? return userData[i];
? ? ? ? }
? ? ? }
? ? }
? ? else {
? ? ? console.log("userData is null");
? ? }
? }
? useEffect(() => {
? ? console.log(`The Chat List is equal to : `, chatList);
? ? console.log('The User Data is equal to : ', userData);
? ? console.log('The Logged In User Data is equal to : ', loggedUserData);
? ? if (typeof window !== "undefined") {
? ? ? setIsSSR(true);
? ? }
? ? else {
? ? ? setIsSSR(false);
? ? }
? ? console.log("The signedIn User is equal to :-=-=-=-=-=-= OBJ=> ", getLoggedInUserData());
? ? //Getting user data from local storage
? ? if (typeof window !== "undefined" && isSignedIn == false && localStorage.getItem('signedInUserId') !== null) {
? ? ? setIsSignedIn(true);
? ? }
? ? else {
? ? ? console.log("User is not signed in yet Nor is there a user in local storage");
? ? }
? ? //Getting user data from local storage
? })
? let loggedUserData: any = null;
? loggedUserData = getLoggedInUserData();
? console.log("loggedUserData : ", loggedUserData);
? const sendMessage = async () => {
? ? // userIDSender: this.userIDSender,
? ? // userNameSender: this.userNameSender,
? ? // userIDReceiver: this.userIDReceiver,
? ? // userNameReceiver: this.userNameReceiver,
? ? // message:this.message,
? ? // timeSent:this.timeSent,
? ? // isUserOnline:this.isUserOnline
? ? if (message !== '' && currentSelectedUser !== null && localStorage.getItem('loggedInUserData') !== null && isSSR === true) {
? ? ? const response = await fetch('https://localhost:8000/chat', {
? ? ? ? method: "POST",
? ? ? ? headers: { 'Content-Type': 'application/json' },
? ? ? ? body: JSON.stringify({
? ? ? ? ? // @ts-ignore
? ? ? ? ? userIDSender: JSON.parse(localStorage.getItem('loggedInUserData')).id,
? ? ? ? ? // @ts-ignore
? ? ? ? ? userNameSender: JSON.parse(localStorage.getItem('loggedInUserData')).name,
? ? ? ? ? userIDReceiver: currentSelectedUser.id,
? ? ? ? ? userNameReceiver: currentSelectedUser.name,
? ? ? ? ? message: message,
? ? ? ? ? timeSent: new Date().toLocaleString(),
? ? ? ? ? isUserOnline: true
? ? ? ? })
? ? ? }).catch((error) => {
? ? ? ? alert("Error Sending the message : " + error);
? ? ? ? console.log("Error Sending the message: ", error);
? ? ? })
? ? ? // Fetch the one list data from the API after the POST request
? ? ? const messaging = await response?.json();
? ? ? setChatList([...chatList, messaging]);
? ? ? alert("Message Sent Successfully");
? ? ? setMessage('');
? ? } else {
? ? ? alert('Please fill all the fields to send a new message');
? ? }
? }
? return (
? ? <div>
? ? ? <Head>
? ? ? ? <title>RealTimeChatApp</title>
? ? ? </Head>
? ? ? <Header />
? ? ? <div className="border">
? ? ? ? <div className='chatContainer'>
? ? ? ? ? {(isSSR) ? (
? ? ? ? ? ? <>
? ? ? ? ? ? ? {(localStorage.getItem('loggedInUserData') !== null || isSignedIn !== false) ? (
? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? {(userData !== null) ? (
? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? <div className='containerChattingSidebar'>
? ? ? ? ? ? ? ? ? ? ? ? <h4 className='text-center text-dark mt-4'>?? Welcome
? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? // @ts-ignore
? ? ? ? ? ? ? ? ? ? ? ? ? ? JSON.parse(localStorage.getItem('loggedInUserData')).name
? ? ? ? ? ? ? ? ? ? ? ? ? }!
? ? ? ? ? ? ? ? ? ? ? ? </h4>
? ? ? ? ? ? ? ? ? ? ? ? <div className="text-center mb-4 mt-4">
? ? ? ? ? ? ? ? ? ? ? ? ? <button className='btn btn-danger'
? ? ? ? ? ? ? ? ? ? ? ? ? ? onClick={() => {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? localStorage.removeItem('loggedInUserData');
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setIsSignedIn(false);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? window.location.reload();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? alert("You are logged out Successfully!");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // setLoggedInUserData(null);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Router.push('/');
? ? ? ? ? ? ? ? ? ? ? ? ? ? }}
? ? ? ? ? ? ? ? ? ? ? ? ? >
? ? ? ? ? ? ? ? ? ? ? ? ? ? Logout
? ? ? ? ? ? ? ? ? ? ? ? ? </button>
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-left mb-4" style={{ paddingLeft: "20px", paddingRight: "20px" }}>?? Select a User to start the chat</h5>
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? userData.map((item: any, index: number) => {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {(userData.length >= 1) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // @ts-ignore
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (item.id !== JSON.parse(localStorage.getItem('loggedInUserData')).id) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatUsersBox" key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <UsersList
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? index={index}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // name: this.name,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // password: this.password,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // timeRegistered: this.timeRegistered,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // isSignedIn: this.isSignedIn
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //VALUES
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id={item.id}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? name={item.name}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? timeRegistered={item.timeRegistered}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //OTER Important Props
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? loggedInUserName={
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // @ts-ignore
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? JSON.parse(localStorage.getItem('loggedInUserData')).name
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //FUNCTIONS
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? chatList={chatList}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setChatList={setChatList}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? currentSelectedUser={currentSelectedUser}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setCurrentSelectedUser={setCurrentSelectedUser}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // userData={userData}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6 style={{ marginLeft: "2%", marginRight: "2%" }} className="text-info">Please add a user to chat with them.You can add here. <Link href="/Register">Add User</Link></h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? <div className='containerChattingContainer'>
? ? ? ? ? ? ? ? ? ? ? ? <div className="topChatSelectedUserInfoBox">
? ? ? ? ? ? ? ? ? ? ? ? ? <h3 className="text-primary mt-2 ml-2"> Current User Selected to Chat = {(currentSelectedUser === null) ? ("No User Selected") : (currentSelectedUser.name)} </h3>
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? <div className="containerMainChat">
? ? ? ? ? ? ? ? ? ? ? ? ? <br /><br /><br />
? ? ? ? ? ? ? ? ? ? ? ? ? <div className="d-flex flex-row ml-2">
? ? ? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {(chatList !== null && isSSR === true) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {(currentSelectedUser !== null) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? chatList.map((item: any, index: number) => {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div key={index} className="mt-2">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // @ts-ignore
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (item.userIDSender === JSON.parse(localStorage.getItem('loggedInUserData')).id && item.userIDReceiver === currentSelectedUser.id) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="insideMainContainerChatSender" key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Sent</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxHeader">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-primary">{item.userNameSender}</h5>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6 className="text-secondary">{item.timeSent}</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxBody">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p className="text-dark">{item.message}</p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // @ts-ignore
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (item.userIDReceiver === JSON.parse(localStorage.getItem('loggedInUserData')).id && item.userIDSender === currentSelectedUser.id) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="insideMainContainerChatReceiver" key={index}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Received</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxHeader">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-primary">{item.userNameSender}</h5>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6 className="text-secondary">{item.timeSent}</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="chatBoxBody">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p className="text-dark">{item.message}</p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h5 className="text-center text-dark">No User Selected. Please select a user to chat</h5>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3 className="text-primary">No Messages Yet</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? {/*
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="d-flex flex-row-reverse mr-2">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="insideMainContainerChatReceiver">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Message: Hello World</h3>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6>Send by: Muhammad Bilal</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h6>Time Sent : 20 July 2021</h6>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? */}
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? <div className="containerMessageInput">
? ? ? ? ? ? ? ? ? ? ? ? ? <input className="form-control messageInput" type="text" placeholder="Enter the message here .... " value={message} onChange={(e) => setMessage(e.target.value)} title="Enter" />
? ? ? ? ? ? ? ? ? ? ? ? ? <button className="btn btn-primary btn-lg" onClick={sendMessage}>Send <i className="fas fa-paper-plane"></i></button>
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? <h3 className="text-success text-center">No Users Here <a href="/AddListing">Register Here</a></h3>
? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? <div className="text-center">
? ? ? ? ? ? ? ? ? ? <br /><br /><br /><br /><br /><br /><br /><br />
? ? ? ? ? ? ? ? ? ? <h4 className='text-center text-dark mt-4'>Please Register or Login to Chat with other registered users</h4>
? ? ? ? ? ? ? ? ? ? <Link href="/Login">Login Now</Link>
? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? <br /><br /><br /><br /><br /><br /><br /><br /><br />
? ? ? ? ? ? ? ? ? <Footer />
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? )}
? ? ? ? ? ? </>
? ? ? ? ? ) : (
? ? ? ? ? ? <h3>Chat Page Window is undefined</h3>
? ? ? ? ? )}
? ? ? ? </div>
? ? ? </div>
? ? </div>
? )
}
export default Home;
Now under the directory?styles?create a new folder named?ContainerCss?and then in ContainerCss folder create a file named?Home.css. So this will be the path?styles\ContainerCss\Home.css. Then write the following CSS code in that file.
/*
? ?Relative Path : styles\ContainerCss\Home.css
*/
.form_styling {
? ? width: 70%;
? ? border: 1px solid #ccc;
? ? padding: 20px;
? ? border-radius: 10px;
? ? margin: 0 auto;
}
.addItemInput {
? ? width: 85%;
? ? margin-right: 1%;
}
.commentSection {
? ? width: 100%;
? ? margin-top: 20px;
? ? background-color: rgb(240, 240, 240);
? ? border: 1px solid rgba(250, 6, 91,0.5);
? ? padding: 20px;
? ? border-radius: 1px;
}
Create another file Chat.css in the same directory means in ContainerCss. The relative path of the file will be: styles\ContainerCss\Chat.css
/*
? ?Relative Path : styles\ContainerCss\Chat.css
*/
.containerChattingSidebar {
? ? width: 20%;
? ? margin-top: 72px;
? ? height: 100vw;
? ? background-color: #f5f5f5;
? ? border-right: 1px solid #e0e0e0;
? ? border-bottom: 1px solid #e0e0e0;
? ? border-top: 1px solid #e0e0e0;
? ? border-left: 1px solid #e0e0e0;
? ? border-radius: 0px;
? ? position: fixed;
? ? top: 0px;
? ? left: 0px;
? ? z-index: 1;
}
.containerChattingContainer {
? ? border: 1px solid rgb(246, 246, 246);
? ? width: 80%;
? ? height: 40.5vw;
? ? scroll-behavior: smooth;
? ? overflow-y: scroll;
? ? background-color: #ffffff;
? ? border-radius: 0px;
? ? top: 0px;
? ? margin-left: 20%;
? ? margin-top: 4%;
? ? padding-bottom: 40px;
? ? z-index: 2;
}
.insideMainContainerChatSender {
? ? border: 1px solid black;
? ? width: fit-content;
? ? padding: 10px;
? ? color: blue;
}
.insideMainContainerChatReceiver {
? ? border: 1px solid orange;
? ? margin-top: 10px;
? ? width: fit-content;
? ? padding: 10px;
? ? color: orange;
}
.topChatSelectedUserInfoBox {
? ? background-color: rgb(248, 243, 243);
? ? position: fixed;
? ? width: 100%;
? ? height: 50px;
? ? box-shadow: inset 0px 0px 5px #888888;
? ? top: 72px;
}
.containerMainChat {
? ? padding-left: 2%;
? ? padding-right: 2%;
}
.containerChattingContainer::-webkit-scrollbar {
? ? width: 0.5em;
}
.containerChattingContainer::-webkit-scrollbar-track {
? ? -webkit-box-shadow: inset 0 0 6px rgba(83, 81, 81, 0.3);
}
.containerChattingContainer::-webkit-scrollbar-thumb {
? ? background-color: rgb(161, 174, 187);
? ? outline: 1px solid rgb(60, 123, 187);
? ? border-radius: 10px;
}
.containerMessageInput {
? ? position: fixed;
? ? bottom: 0px;
? ? width: 79%;
? ? margin-right: 1%;
? ? height: 40px;
? ? display: flex;
? ? background-color: inherit;
? ? flex-direction: row;
? ? justify-content: space-between;
}
.messageInput {
? ? width: 90%;
? ? height: 40px;
? ? font-size: 25px;
? ? font-weight: lighter;
? ? border-radius: 5px;
? ? background-color: #fff;
? ? padding: 0px;
? ? margin: 0px;
? ? box-shadow: none !important;
}
So Now First We will create other pages like the Login and Registration page.
b) Login Page
Now under the pages directory create another file named Login.tsx and paste the following code. The relative path of this file will be pages\Login.tsx
// Relative Path : pages\Login.tsx
import { FormEvent, useEffect, useState } from "react";
import Link from "next/link";
import Head from 'next/head';
import Router from 'next/router';
//Importing Compoents
import Header from '../Components/Header';
import Footer from '../Components/Footer';
function Login() {
? ? const [isSSR, setIsSSR] = useState<boolean>(false);
? ? const [usersList, setUsersList] = useState<Array<any>>([]);
? ? // VALUES
? ? // user.name = req.body.name;
? ? // user.password = req.body.password;
? ? // user.timeRegistered = req.body.timeRegistered;
? ? // user.isSignedIn = req.body.isSignedIn;
? ? const [name, setName] = useState<string>('');
? ? const [password, setPassword] = useState<string>('');
? ? const [isSignedIn, setIsSignedIn] = useState<boolean>(false);
? ? const [loggedInUserData, setLoggedInUserData] = useState<any>(null);
? ? useEffect(() => {
? ? ? ? fetchUsersData();
? ? }, []);
? ? function fetchUsersData() {
? ? ? ? if (typeof window !== "undefined") {
? ? ? ? ? ? (async () => {
? ? ? ? ? ? ? ? const response = await fetch('https://localhost:8000/user', {
? ? ? ? ? ? ? ? ? ? method: 'GET',
? ? ? ? ? ? ? ? ? ? headers: {
? ? ? ? ? ? ? ? ? ? ? ? accept: 'application/json',
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? const content = await response.json();
? ? ? ? ? ? ? ? setUsersList(content);
? ? ? ? ? ? })();
? ? ? ? }
? ? }
? ? function getLoggedInUserData() {
? ? ? ? console.log("user data: ", usersList);
? ? ? ? if (usersList !== null) {
? ? ? ? ? ? for (let i = 0; i < usersList.length; i++) {
? ? ? ? ? ? ? ? if (usersList[i].isSignedIn === true) {
? ? ? ? ? ? ? ? ? ? console.log("User Data Specific is equal to : ", usersList[i]);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? console.log("User List is null");
? ? ? ? }
? ? }
? ? // eslint-disable-next-line react-hooks/exhaustive-deps
? ? useEffect(() => {
? ? ? ? console.log(`The users usersList is equal to : `, usersList);
? ? ? ? console.log('The Logged In User Data is equal to : ', loggedUserData);
? ? ? ? if (typeof window !== "undefined" && isSSR === false) {
? ? ? ? ? ? setIsSSR(true);
? ? ? ? }
? ? // eslint-disable-next-line react-hooks/exhaustive-deps
? ? },[isSSR]);
? ? let loggedUserData: any = null;
? ? loggedUserData = getLoggedInUserData();
? ? console.log("loggedUserData : ", loggedUserData);
? ? ////////////////////////////////////////////////////////////////////////
? ? const loginUser = async (
? ? ? ? e: FormEvent<HTMLFormElement>
? ? ) => {
? ? ? ? e.preventDefault();
? ? ? ? for (let i = 0; i < usersList.length; i++) {
? ? ? ? ? ? if (usersList[i].name === name && usersList[i].password === password) {
? ? ? ? ? ? ? ? setLoggedInUserData(usersList[i]);
? ? ? ? ? ? ? ? let user = {
? ? ? ? ? ? ? ? ? ? name: usersList[i].name,
? ? ? ? ? ? ? ? ? ? password: usersList[i].password,
? ? ? ? ? ? ? ? ? ? timeRegistered: usersList[i].timeRegistered,
? ? ? ? ? ? ? ? ? ? isSignedIn: true
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? console.log("Signed In User is Equal to :-=-=-=-= Obj ", user);
? ? ? ? ? ? ? ? //Saving the item to local storage
? ? ? ? ? ? ? ? localStorage.setItem('loggedInUserData', JSON.stringify(usersList[i]));
? ? ? ? ? ? ? ? // localStorage.setItem("userID", usersList[i].id);
? ? ? ? ? ? ? ? // localStorage.setItem("userName", usersList[i].name);
? ? ? ? ? ? ? ? // localStorage.setItem("userPassword", usersList[i].password);
? ? ? ? ? ? ? ? // localStorage.setItem("userTimeRegistered", usersList[i].timeRegistered);
? ? ? ? ? ? ? ? //Saving the item to local storage
? ? ? ? ? ? ? ? setIsSignedIn(true);
? ? ? ? ? ? ? ? alert("Successfully You are logged in!, Redirecting to main page");
? ? ? ? ? ? ? ? Router.push('/');
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? alert("Invalid Credentials");
? ? }
? ? return (
? ? ? ? <div>
? ? ? ? ? ? <Head>
? ? ? ? ? ? ? ? <title>RealTimeChatApp</title>
? ? ? ? ? ? </Head>
? ? ? ? ? ? <Header />
? ? ? ? ? ? <div className={`container`}>
? ? ? ? ? ? ? ? <div className={`row`}>
? ? ? ? ? ? ? ? ? ? <div className={`col-12`}>
? ? ? ? ? ? ? ? ? ? ? ? <br /><br />
? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? <h3 className='text-center text-dark mt-4'>NextJS & Redis Based ChatApp Login Form</h3>
? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? {(isSSR) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? <>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {(localStorage.getItem('loggedInUserData') !== null || loggedInUserData !== null) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* @ts-ignore: Object is possibly 'null'. */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <h4 className='text-center text-dark mt-4'>Welcome {localStorage.getItem('loggedInUserData').name}! You are logged In</h4>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className='text-center'>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button className='btn btn-danger'
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? onClick={() => {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? localStorage.removeItem('loggedInUserData');
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setIsSignedIn(false);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? alert("You are logged out!, Redirecting to login page");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setLoggedInUserData(null);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Router.push('/Login');
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? >
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Logout
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </button>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <form className='form_styling' onSubmit={loginUser}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <fieldset>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <legend className="text-center text-primary">Login Here</legend>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Email input */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-outline mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input type="text" id="form2Example1" className="form-control border" onChange={(e) => setName(e.target.value)} />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-label" htmlFor="form2Example1">User Name</label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Password input */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-outline mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input type="password" id="form2Example2" value={password} onChange={(e) => setPassword(e.target.value)} className="form-control border" />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-label" htmlFor="form2Example2">Password</label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* 2 column grid layout for inline styling */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="row mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="col d-flex justify-content-center">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Checkbox */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-check">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input className="form-check-input" type="checkbox" id="form2Example31" defaultChecked />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-check-label" htmlFor="form2Example31"> Remember me </label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="col">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Forget Password */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a href="#!">Forgot password?</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Submit button */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button type="submit" className="btn btn-primary btn-block mb-4">Sign in</button>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Register buttons */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="text-center">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p>Not a member? <Link href="/Register">Register</Link></p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </fieldset>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </form>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? </>
? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? <h3>Login Page Window is undefined</h3>
? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div >
? ? ? ? ? ? <Footer />
? ? ? ? </div>
? ? )
}
export default Login;
Now creating the Registration page.
c) Register Page
Now again under the pages directory create another file named Register.tsx and paste the following code. The relative path of this file will be pages\Register.tsx
// Relative Path : pages\Register.tsx
import { useEffect, useState } from "react";
import Router from 'next/router'
import Head from 'next/head';
//Importing Compoents
import Header from '../Components/Header';
import Footer from '../Components/Footer';
import Link from "next/link";
function Register() {
? ? if (typeof window !== "undefined") {
? ? ? ? const { pathname } = Router
? ? }
? ? else {
? ? ? ? console.log("Register Page Window is undefined");
? ? }
? ? ////////////////////////////////////////////////////////////////////////
? ? const [usersList, setUsersList] = useState<any>([]);
? ? // VALUES
? ? // user.name = req.body.name;
? ? // user.password = req.body.password;
? ? // user.timeRegistered = req.body.timeRegistered;
? ? // user.isSignedIn = req.body.isSignedIn;
? ? const [name, setName] = useState<string>('');
? ? const [password, setPassword] = useState<string>('');
? ? const [duplicate, setDuplicate] = useState<any>(null);
? ? const [isSignedIn, setIsSignedIn] = useState<boolean>(false);
? ? // const [loggedInUserData, setLoggedInUserData] = useState(null);
? ? useEffect(() => {
? ? ? ? fetchUsersData();
? ? ? ? // setLoggedInUserData(loggedUserData);
? ? }, []);
? ? function checkIfUserAlreadyExists() {
? ? ? ? for (let i = 0; i < usersList.length; i++) {
? ? ? ? ? ? if (usersList[i].name === name) {
? ? ? ? ? ? ? ? // alert("User already exists! Not allowed to register again! Please login instead!");
? ? ? ? ? ? ? ? setDuplicate(true);
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? setDuplicate(false);
? ? ? ? return false;
? ? }
? ? useEffect(() => {
? ? ? ? checkIfUserAlreadyExists();
? ? ? ? if (name === '') {
? ? ? ? ? ? setDuplicate(null);
? ? ? ? }
? ? ? ? // eslint-disable-next-line react-hooks/exhaustive-deps
? ? }, [name]);
? ? function fetchUsersData() {
? ? ? ? if (typeof window !== "undefined") {
? ? ? ? ? ? (async () => {
? ? ? ? ? ? ? ? const response = await fetch('https://localhost:8000/user', {
? ? ? ? ? ? ? ? ? ? method: 'GET',
? ? ? ? ? ? ? ? ? ? headers: {
? ? ? ? ? ? ? ? ? ? ? ? accept: 'application/json',
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? const content = await response.json();
? ? ? ? ? ? ? ? setUsersList(content);
? ? ? ? ? ? })();
? ? ? ? }
? ? }
? ? function getLoggedInUserData() {
? ? ? ? console.log("user data: ", usersList);
? ? ? ? if (usersList !== null) {
? ? ? ? ? ? for (let i = 0; i < usersList.length; i++) {
? ? ? ? ? ? ? ? if (usersList[i].isSignedIn === true) {
? ? ? ? ? ? ? ? ? ? console.log("User Data Specific is equal to : ", usersList[i]);
? ? ? ? ? ? ? ? ? ? // setLoggedInUserData(userData[i]);
? ? ? ? ? ? ? ? ? ? return usersList[i];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? console.log("User List is null");
? ? ? ? }
? ? }
? ? useEffect(() => {
? ? ? ? console.log(`The users usersList is equal to : `, usersList);
? ? ? ? console.log('The Logged In User Data is equal to : ', loggedUserData);
? ? })
? ? let loggedUserData: any = null;
? ? loggedUserData = getLoggedInUserData();
? ? console.log("loggedUserData : ", loggedUserData);
? ? ////////////////////////////////////////////////////////////////////////
? ? const registerUsersData = async (
? ? ? ? event: any
? ? ) => {
? ? ? ? event.preventDefault();
? ? ? ? if (name !== '' && password !== '' && loggedUserData !== null && duplicate === false) {
? ? ? ? ? ? const response = await fetch('https://localhost:8000/user', {
? ? ? ? ? ? ? ? method: "POST",
? ? ? ? ? ? ? ? headers: { 'Content-Type': 'application/json' },
? ? ? ? ? ? ? ? body: JSON.stringify({
? ? ? ? ? ? ? ? ? ? name: name,
? ? ? ? ? ? ? ? ? ? password: password,
? ? ? ? ? ? ? ? ? ? timeRegistered: new Date().toLocaleString(),
? ? ? ? ? ? ? ? ? ? isSignedIn: isSignedIn
? ? ? ? ? ? ? ? })
? ? ? ? ? ? });
? ? ? ? ? ? // Fetch the one list data from the API after the POST request
? ? ? ? ? ? const users = await response.json();
? ? ? ? ? ? // console.log(users);
? ? ? ? ? ? setUsersList([...usersList, users]);
? ? ? ? ? ? alert("users Data Added Successfully");
? ? ? ? ? ? // Resetting the form
? ? ? ? ? ? setName('');
? ? ? ? ? ? setPassword('');
? ? ? ? ? ? setDuplicate(null);
? ? ? ? ? ? fetchUsersData();
? ? ? ? ? ? Router.push('/Login');
? ? ? ? } else {
? ? ? ? ? ? alert('Please fill all the fields to add a new users to the api');
? ? ? ? }
? ? }
? ? return (
? ? ? ? <div>
? ? ? ? ? ? <Head>
? ? ? ? ? ? ? ? <title>RealTimeChatApp</title>
? ? ? ? ? ? </Head>
? ? ? ? ? ? <Header />
? ? ? ? ? ? <div className={`container`}>
? ? ? ? ? ? ? ? <div className={`row`}>
? ? ? ? ? ? ? ? ? ? <div className={`col-12`}>
? ? ? ? ? ? ? ? ? ? ? ? <br /><br /><br />
? ? ? ? ? ? ? ? ? ? ? ? <h3 className='text-center text-dark mt-4'>NextJS & Redis Based ChatApp Registration Form</h3>
? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? <form className='form_styling' onSubmit={registerUsersData}>
? ? ? ? ? ? ? ? ? ? ? ? ? ? <fieldset>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <legend className="text-center text-primary">Register Here</legend>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Email input */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {(duplicate) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="alert alert-danger" role="alert">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <strong>Error!</strong> User already exists! Not allowed to register again! Please login instead!
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (duplicate === false) ? (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="alert alert-success" role="alert">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <strong>Success!</strong> User does not exist! You can register now!
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ) : (
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <></>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-outline mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input type="text" id="form2Example1" value={name} onChange={(e) => setName(e.target.value)} required className="form-control border" />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-label" htmlFor="form2Example1">User Name</label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Password input */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-outline mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input type="password" id="form2Example2" required value={password} onChange={(e) => setPassword(e.target.value)} className="form-control border" />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-label" htmlFor="form2Example2">Password</label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Checked checkbox */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="form-check mb-4">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <input className="form-check-input" type="checkbox" checked={isSignedIn} onChange={() => setIsSignedIn(!isSignedIn)} id="flexCheckChecked" />
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <label className="form-check-label" htmlFor="flexCheckChecked">Keep me Logged In</label>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Submit button */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button type="submit" className="btn btn-primary btn-block mb-4">Register</button>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* Register buttons */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <div className="text-center">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <p>Already Registered ? <Link href="/Login">Login</Link></p>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </fieldset>
? ? ? ? ? ? ? ? ? ? ? ? </form>
? ? ? ? ? ? ? ? ? ? ? ? <br />
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div>
? ? ? ? ? ? <Footer />
? ? ? ? </div>
? ? )
}
export default Register;
So Now let's create the components?
Creating Components
First, we will start with Header Component.
1) Header
// Relative Path : Components\Header\index.tsx
import Link from 'next/link';
import Image from 'next/image';
const Header = () => {
? ? return (
? ? ? ? <>
? ? ? ? ? ? {/* Navbar */}
? ? ? ? ? ? <nav className="navbar navbar-expand-lg fixed-top navbar-light bg-light">
? ? ? ? ? ? ? ? {/* Container wrapper */}
? ? ? ? ? ? ? ? <div className="container-fluid">
? ? ? ? ? ? ? ? ? ? {/* Toggle button */}
? ? ? ? ? ? ? ? ? ? <button className="navbar-toggler" type="button" data-mdb-toggle="collapse" data-mdb-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
? ? ? ? ? ? ? ? ? ? ? ? <i className="fas fa-bars" />
? ? ? ? ? ? ? ? ? ? </button>
? ? ? ? ? ? ? ? ? ? {/* Collapsible wrapper */}
? ? ? ? ? ? ? ? ? ? <div className="collapse navbar-collapse" id="navbarSupportedContent">
? ? ? ? ? ? ? ? ? ? ? ? {/* Navbar brand */}
? ? ? ? ? ? ? ? ? ? ? ? <a className="navbar-brand mt-2 mt-lg-0" href="#">
? ? ? ? ? ? ? ? ? ? ? ? ? ? <Image src="/logo.png" width={45} height={45} title="Redis :) The most loved developers database." alt="Redis" loading="lazy" />
? ? ? ? ? ? ? ? ? ? ? ? </a>
? ? ? ? ? ? ? ? ? ? ? ? {/* Left links */}
? ? ? ? ? ? ? ? ? ? ? ? <ul className="navbar-nav fill me-auto mb-2 mb-lg-0">
? ? ? ? ? ? ? ? ? ? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Link href="/">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="nav-link">Chat</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </Link>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* <li className="nav-item">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Link href="/AddFeedback">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="nav-link" href='#' title="Add Listing">Add Feedback</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </Link>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </li> */}
? ? ? ? ? ? ? ? ? ? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Link href="/Login">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="nav-link" href='#' title="Login">Login</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </Link>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? <li className="nav-item">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Link href="/Register">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="nav-link" href='#' title="Register">Register</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </Link>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? {/* <li className="nav-item">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Link href="/Feedback">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="nav-link" href='#' title="Register">Feedback</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </Link>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </li> */}
? ? ? ? ? ? ? ? ? ? ? ? </ul>
? ? ? ? ? ? ? ? ? ? ? ? {/* Left links */}
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? {/* Collapsible wrapper */}
? ? ? ? ? ? ? ? ? ? {/* Right elements */}
? ? ? ? ? ? ? ? ? ? <div className="d-flex align-items-center">
? ? ? ? ? ? ? ? ? ? ? ? {/* Icon */}
? ? ? ? ? ? ? ? ? ? ? ? <a className="text-reset me-3" title="Learn With Redis University" target="_blank" rel="noreferrer">
? ? ? ? ? ? ? ? ? ? ? ? ? ? <Image src="https://download.logo.wine/logo/Redis/Redis-Logo.wine.png" className="rounded-circle" width={50} height={50} alt="Muhammad Bilal" title="Muhammad Bilal" loading="lazy" />
? ? ? ? ? ? ? ? ? ? ? ? </a>
? ? ? ? ? ? ? ? ? ? ? ? {/* Avatar */}
? ? ? ? ? ? ? ? ? ? ? ? <div className="dropdown">
? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="dropdown-toggle d-flex align-items-center hidden-arrow" href="#" id="navbarDropdownMenuAvatar" role="button" data-mdb-toggle="dropdown" aria-expanded="false">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Image src="https://avatars.githubusercontent.com/u/59303181?v=4" className="rounded-circle" width={25} height={25} alt="Muhammad Bilal" title="Muhammad Bilal" loading="lazy" />
? ? ? ? ? ? ? ? ? ? ? ? ? ? </a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? <ul className="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuAvatar">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="dropdown-item" title="Linkedin Profile" href="https://www.dhirubhai.net/in/muhammad-bilal-028843199/">Linkedin</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="dropdown-item" title="Github Profile" >Github</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <a className="dropdown-item" title="Email" href="mailto:[email protected]">[email protected]</a>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? ? ? ? ? ? ? ? ? </ul>
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? {/* Right elements */}
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? {/* Container wrapper */}
? ? ? ? ? ? </nav>
? ? ? ? ? ? {/* Navbar */}
? ? ? ? </>
? ? )
}
export default Header;
/* Components\Header\style.css */
.nav-link,
.nav-link:after,
.nav-link:before {
? ? transition: all .5s !important;
}
.nav-link {
? ? border-bottom: 1px solid transparent !important;
}
.nav-link:hover {
? ? color: rgb(236, 28, 56) !important;
? ? border-bottom: 1px solid rgb(236, 28, 56) !important;
? ? transition: 0.5s linear !important;
}
The next part I will continue from Footer Component and the backend part will be completed in the next part because the limit for LinkedIn article writing is over here.
This post is in collaboration with?Redis
Check out the following helpful links
Thanks for reading!