<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jagadeesh Koyya</title>
    <description>The latest articles on DEV Community by Jagadeesh Koyya (@jagadeeshkj).</description>
    <link>https://dev.to/jagadeeshkj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F664525%2Fbbdb8466-f199-4db9-975e-248425887331.jpg</url>
      <title>DEV Community: Jagadeesh Koyya</title>
      <link>https://dev.to/jagadeeshkj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jagadeeshkj"/>
    <language>en</language>
    <item>
      <title>OPENAI DALL-E AI IMAGE GENERATOR USING MERN STACK</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Fri, 27 Jan 2023 06:16:18 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/dall-e-ai-image-generator-150b</link>
      <guid>https://dev.to/jagadeeshkj/dall-e-ai-image-generator-150b</guid>
      <description>&lt;p&gt;Hello there! How do you do? I hope you are doing extremely well. Great! &lt;/p&gt;

&lt;p&gt;Without further due let's jump into the amazing project that we're going to build today. It's built upon the great MERN stack. &lt;/p&gt;

&lt;p&gt;Stack Used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express JS&lt;/li&gt;
&lt;li&gt;React JS&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Node JS&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;OpenAI DALL-E API&lt;/li&gt;
&lt;li&gt;Cloudinary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While doing this project, I can say that I got a feeling of zeel in driving through the process and it's levitating and I hope you feel the same zeel.&lt;/p&gt;

&lt;p&gt;I can provide you with the file hierarchy in which this project is going to be built. We start with two folders namely client (frontend) and server (backend) in a root folder of your chosen name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mhyphkxksxj4xin8zsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1mhyphkxksxj4xin8zsg.png" alt="root" width="334" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0hycf0dumv2asaxs1qj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0hycf0dumv2asaxs1qj.png" alt="Client" width="338" height="1242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkq3u7zy7qa06zdy6pgb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkq3u7zy7qa06zdy6pgb.png" alt="Server" width="324" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get access to every file listed in the above image in the below-provided links to my GitHub repo.&lt;/p&gt;

&lt;p&gt;I would like to write the experience here that I've acquired during building this project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Get Started&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend (Client)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beginning with the client folder we focus on building the UI for our project. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx05mhnyzjqj0lwkenqio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx05mhnyzjqj0lwkenqio.png" alt="UI" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's our homepage where we can see all the AI generated images shared by people. &lt;/p&gt;

&lt;p&gt;You can generate your desired AI image with a prompt of yours and with your name in the checkboxes provided as shown in the below image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtm0cxbpv1evup6l362t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtm0cxbpv1evup6l362t.png" alt="Upload" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekc67egovc2exwdhlrbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekc67egovc2exwdhlrbq.png" alt="loader" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gzwlnwgzbg22sfrnmyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gzwlnwgzbg22sfrnmyh.png" alt="gen" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can share the image with the world if you want to. And furthur it will be stick in the community gallery where you can download any image you wish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;src &lt;em&gt;client&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Assets folder consists of some cool images that you need in making this UI look better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { BrowserRouter, Link, Route, Routes } from "react-router-dom";

import { openai } from "./assets";
import { Home, CreatePost } from "./pages";

const App = () =&amp;gt; {
  return (
    &amp;lt;BrowserRouter&amp;gt;
      {/* Header */}
      &amp;lt;header className="w-full flex justify-between items-center bg-[#FFCEFE] sm:px-8 px-4 py-4 border-b border-b-[#FFCEFE]"&amp;gt;
        &amp;lt;Link to="/"&amp;gt;
          &amp;lt;img src={openai} alt="logo" className="h-10 w-10 object-cover" /&amp;gt;
        &amp;lt;/Link&amp;gt;

        &amp;lt;Link
          to="/create-post"
          className="font-inter font-medium bg-[#a600ff] text-white px-4 py-2 rounded-md"
        &amp;gt;
          Create Post
        &amp;lt;/Link&amp;gt;
      &amp;lt;/header&amp;gt;

      {/* Body UI */}
      &amp;lt;main className="sm:px-8 px-4 py-8 w-full bg-[#EFEFEF] min-h-[calc(100vh-4.563rem)]"&amp;gt;
        &amp;lt;Routes&amp;gt;
          &amp;lt;Route path="/" element={&amp;lt;Home /&amp;gt;} /&amp;gt;
          &amp;lt;Route path="/create-post" element={&amp;lt;CreatePost /&amp;gt;} /&amp;gt;
        &amp;lt;/Routes&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the main component which renders a header with an OpenAI logo and a "Create Post" button, and a main section where the different pages of the app are rendered based on the current URL. &lt;/p&gt;

&lt;p&gt;The component has two routes: the default route ("/") which renders the Home component, and the "/create-post" route, which renders the CreatePost component.&lt;/p&gt;

&lt;p&gt;The component also contains some styling classed which are used to customize the component layout and design.&lt;/p&gt;

&lt;p&gt;The components folder provides Card.jsx, FormField.jsx, Loader.jsx.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Card.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

import { download } from "../assets";
import { downloadImage } from "../utils";

const Card = ({ _id, name, prompt, photo }) =&amp;gt; {
  return (
    &amp;lt;div className="rounded-xl group relative shadow-card hover:shadow-cardhover card"&amp;gt;
      &amp;lt;img
        src={photo}
        alt={prompt}
        className="w-full h-auto object-cover rounded-xl"
      /&amp;gt;
      &amp;lt;div className="group-hover:flex flex-col max-h-[94.5%] hidden absolute bottom-0 left-0 right-0 bg-[rgba(255,255,255,0.1)] m-2 p-4 rounded-md"&amp;gt;
        &amp;lt;p className="text-white text-sm overflow-y-auto prompt"&amp;gt;{prompt}&amp;lt;/p&amp;gt;

        &amp;lt;div className="flex justify-between items-center mt-4 gap-2"&amp;gt;
          &amp;lt;div className="flex items-center gap-2"&amp;gt;
            &amp;lt;div className="w-7 h-7 rounded-full object-cover bg-green-700 flex justify-center items-center text-white text-xs font-bold"&amp;gt;
              {name[0]}
            &amp;lt;/div&amp;gt;
            &amp;lt;p className="text-white text-xs"&amp;gt;{name}&amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button
            type="button"
            onClick={() =&amp;gt; downloadImage(_id, photo)}
            classname="outline-none bg-transparent border-none"
          &amp;gt;
            &amp;lt;img
              src={download}
              alt="download"
              className="w-6 h-6 object-contain invert"
            /&amp;gt;
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Card;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is a React component that renders a card with an image, prompt, and download button. &lt;/p&gt;

&lt;p&gt;The component takes in props of _id, name, prompt, and photo. &lt;/p&gt;

&lt;p&gt;It renders an image with the given photo prop as the source and the prompt prop as the alt text. &lt;/p&gt;

&lt;p&gt;It also renders a div containing the name prop in a circle with a background color of green-700 and text color of white. &lt;/p&gt;

&lt;p&gt;Lastly, it renders a download button which calls the downloadImage function when clicked and passes in _id and photo as arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FormField.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const FormField = ({
  labelName,
  type,
  name,
  placeholder,
  value,
  handleChange,
  isSurpriseMe,
  handleSurpriseMe,
}) =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div className="flex items-center gap-2 mb-2"&amp;gt;
        &amp;lt;label
          htmlFor={name}
          className="block text-sm font-medium text-gray-900"
        &amp;gt;
          {labelName}
        &amp;lt;/label&amp;gt;

        {isSurpriseMe &amp;amp;&amp;amp; (
          &amp;lt;button
            type="button"
            onClick={handleSurpriseMe}
            className="font-semibold text-xs bg-[#ECECF1] py-1 px-2 rounded-[5px] text-black"
          &amp;gt;
            Surprise me
          &amp;lt;/button&amp;gt;
        )}
      &amp;lt;/div&amp;gt;

      &amp;lt;input
        type={type}
        id={name}
        name={name}
        placeholder={placeholder}
        value={value}
        onChange={handleChange}
        required
        className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-[#4649ff] focus:border-[#4649ff] outline-none block w-full p-3"
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default FormField;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code renders a form field. It takes in several props, such as labelName, type, name, placeholder, value, handleChange, isSurpriseMe and handleSurpriseMe.&lt;/p&gt;

&lt;p&gt;It then renders an input field with the given props and also renders a button if isSurpriseMe is true. &lt;/p&gt;

&lt;p&gt;When the button is clicked it calls the handleSurpriseMe function. I'll tell you what this function does later.&lt;/p&gt;

&lt;p&gt;Finally it exports the FormField component so it can be used in other components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loader.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const Loader = () =&amp;gt; (
  &amp;lt;div role="status"&amp;gt;
    &amp;lt;svg
      aria-hidden="true"
      className="inline w-10 h-10 mr-2 text-gray-200 animate-spin fill-[#6469ff]"
      viewBox="0 0 100 101"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    &amp;gt;
      &amp;lt;path
        d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
        fill="currentColor"
      /&amp;gt;
      &amp;lt;path
        d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
        fill="currentFill"
      /&amp;gt;
    &amp;lt;/svg&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default Loader;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one got that nice cool loading effect when an image gets generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Card from "./Card";
import FormField from "./FormField";
import Loader from "./Loader";

export { Card, FormField, Loader };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used index.js file to export all these components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constant's index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const surpriseMePrompts = [
  "an armchair in the shape of an avocado",
  "a surrealist dream-like oil painting by Salvador Dalí of a cat playing checkers",
  "teddy bears shopping for groceries in Japan, ukiyo-e",
  "an oil painting by Matisse of a humanoid robot playing chess",
  "panda mad scientist mixing sparkling chemicals, digital art",
  "a macro 35mm photograph of two mice in Hawaii, they're each wearing tiny swimsuits and are carrying tiny surf boards, digital art",
  "3D render of a cute tropical fish in an aquarium on a dark blue background, digital art",
  "an astronaut lounging in a tropical resort in space, vaporwave",
  "an oil painting portrait of a capybara wearing medieval royal robes and an ornate crown on a dark background",
  "a stained glass window depicting a hamburger and french fries",
  "a pencil and watercolor drawing of a bright city in the future with flying cars",
  "a sunlit indoor lounge area with a pool with clear water and another pool with translucent pastel pink water, next to a big window, digital art",
  "a fortune-telling shiba inu reading your fate in a giant hamburger, digital art",
  '"a sea otter with a pearl earring" by Johannes Vermeer',
  "an oil pastel drawing of an annoyed cat in a spaceship",
  "a painting of a fox in the style of Starry Night",
  "a bowl of soup that looks like a monster, knitted out of wool",
  "A plush toy robot sitting against a yellow wall",
  "A synthwave style sunset above the reflecting water of the sea, digital art",
  "Two futuristic towers with a skybridge covered in lush foliage, digital art",
  "A 3D render of a rainbow colored hot air balloon flying above a reflective lake",
  "A comic book cover of a superhero wearing headphones",
  "A centered explosion of colorful powder on a black background",
  "A photo of a Samoyed dog with its tongue out hugging a white Siamese cat",
  "A photo of a white fur monster standing in a purple room",
  "A photo of Michelangelo's sculpture of David wearing headphones djing",
  "A Samurai riding a Horse on Mars, lomography.",
  "A modern, sleek Cadillac drives along the Gardiner expressway with downtown Toronto in the background, with a lens flare, 50mm photography",
  "A realistic photograph of a young woman with blue eyes and blonde hair",
  "A man standing in front of a stargate to another dimension",
  "Spongebob Squarepants in the Blair Witch Project",
  "A velociraptor working at a hotdog stand, lomography",
  "A man walking through the bustling streets of Kowloon at night, lit by many bright neon shop signs, 50mm lens",
  "A BBQ that is alive, in the style of a Pixar animated movie",
  "A futuristic cyborg dance club, neon lights",
  "The long-lost Star Wars 1990 Japanese Anime",
  "A hamburger in the shape of a Rubik’s cube, professional food photography",
  "A Synthwave Hedgehog, Blade Runner Cyberpunk",
  "An astronaut encountering an alien life form on a distant planet, photography",
  "A Dinosaur exploring Cape Town, photography",
  "A Man falling in Love with his Computer, digital art",
  "A photograph of a cyborg exploring Tokyo at night, lomography",
  "Dracula walking down the street of New York City in the 1920s, black and white photography",
  "Synthwave aeroplane",
  "A man wanders through the rainy streets of Tokyo, with bright neon signs, 50mm",
  "A Space Shuttle flying above Cape Town, digital art",
];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a bunch of prompts in which one is randomly given to the person when they hit the SurpriseMe button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAGES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CreatePost.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";
import { useNavigate } from "react-router-dom";

import { preview } from "../assets";
import { getRandomPrompt } from "../utils";
import { FormField, Loader } from "../components";

const CreatePost = () =&amp;gt; {
  const navigate = useNavigate();
  const [form, setForm] = useState({
    name: "",
    prompt: "",
    photo: "",
  });
  const [generatingImg, setGeneratingImg] = useState(false);
  const [loading, setLoading] = useState(false);

  // Integrate with the backend
  const generateImage = async () =&amp;gt; {
    if (form.prompt) {
      try {
        setGeneratingImg(true);
        const response = await fetch(
          "https://dall-e-4e72.onrender.com/api/v1/dalle",
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({ prompt: form.prompt }),
          }
        );

        const data = await response.json();

        setForm({ ...form, photo: `data:image/jpeg;base64,${data.photo}` });
      } catch (error) {
        alert("Something went wrong");
      } finally {
        setGeneratingImg(false);
      }
    } else {
      alert("Please enter a prompt");
    }
  };

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();

    if (form.prompt &amp;amp;&amp;amp; form.photo) {
      setLoading(true);

      try {
        const response = await fetch(
          "https://dall-e-4e72.onrender.com/api/v1/post",
          {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(form),
          }
        );

        await response.json();
        navigate("/");
      } catch (error) {
        alert("Something went wrong");
      } finally {
        setLoading(false);
      }
    } else {
      alert("Please enter a prompt and generate an image");
    }
  };

  const handleChange = (e) =&amp;gt; {
    setForm({ ...form, [e.target.name]: e.target.value });
  };

  const handleSurpriseMe = () =&amp;gt; {
    const randomPrompt = getRandomPrompt(form.prompt);
    setForm({ ...form, prompt: randomPrompt });
  };

  return (
    &amp;lt;section className="max-w-7xl mx-auto"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1 className="font-extrabold text-[#222328] text-[2rem]"&amp;gt;
          Create Post
        &amp;lt;/h1&amp;gt;

        &amp;lt;p className="mt-2 text-[#666e75] text-[1rem] max-w-[31.25rem]"&amp;gt;
          Create imaginative and visually stunning images through DALL-E AI and
          share them with the world.
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;form className="mt-16 max-w-3xl" onSubmit={handleSubmit}&amp;gt;
        &amp;lt;div className="flex flex-col gap-5"&amp;gt;
          &amp;lt;FormField
            labelName="Your Name"
            type="text"
            name="name"
            placeholder="Eg. Jagadeesh KJ"
            value={form.name}
            handleChange={handleChange}
          /&amp;gt;

          &amp;lt;FormField
            labelName="Prompt"
            type="text"
            name="prompt"
            placeholder="Eg. An armchair in the shape of an avocado"
            value={form.prompt}
            handleChange={handleChange}
            isSurpriseMe
            handleSurpriseMe={handleSurpriseMe}
          /&amp;gt;

          &amp;lt;div className="relative bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 w-64 p-3 h-64 flex justify-center items-center"&amp;gt;
            {form.photo ? (
              &amp;lt;img
                src={form.photo}
                alt={form.prompt}
                className="w-full h-full object-contain"
              /&amp;gt;
            ) : (
              &amp;lt;img
                src={preview}
                alt="preview"
                className="w-9/12 h-9/12 object-contain opacity-40"
              /&amp;gt;
            )}

            {generatingImg &amp;amp;&amp;amp; (
              &amp;lt;div className="absolute inset-0 z-0 flex justify-center items-center bg-[rgba(0,0,0,0.5)] rounded-lg"&amp;gt;
                &amp;lt;Loader /&amp;gt;
              &amp;lt;/div&amp;gt;
            )}
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div className="mt-5 flex gap-5"&amp;gt;
          &amp;lt;button
            type="button"
            onClick={generateImage}
            className="text-white bg-green-700 font-medium rounded-md text-sm w-full sm:w-auto px-5 py-2.5 text-center"
          &amp;gt;
            {generatingImg ? "Generating..." : "Generate Image"}
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div className="mt-10"&amp;gt;
          &amp;lt;p className="mt-2 text-[#666e75] text-[0.875rem]"&amp;gt;
            Once you have created the image, you can share it with the world.
          &amp;lt;/p&amp;gt;
          &amp;lt;button
            type="submit"
            className="mt-3 text-white bg-[#6469ff] font-medium rounded-md text-sm w-full sm:w-auto px-5 py-2.5 text-center"
          &amp;gt;
            {loading ? "Sharing..." : "Share"}
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/section&amp;gt;
  );
};

export default CreatePost;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component is really important as it takes the input from the person and gives them a chance to create a image by DALL-E. &lt;/p&gt;

&lt;p&gt;The CreatePost component is defined, which uses the useNavigate and useState hooks to handle navigation and state management. &lt;/p&gt;

&lt;p&gt;The initial state includes an empty form object, with properties for name, prompt, and photo. The component also has state variables for generatingImg and loading.&lt;/p&gt;

&lt;p&gt;The generateImage function sends a POST request to the DALL-E API, which returns an image based on the prompt. The handleSubmit function sends a POST request to the backend to create a post. &lt;/p&gt;

&lt;p&gt;The handleChange function updates the form state with the input values. The handleSurpriseMe function sets the prompt field to a random prompt, and the render method returns JSX that renders the form and other UI elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";

import { Loader, Card, FormField } from "../components";

const RenderCards = ({ data, title }) =&amp;gt; {
  if (data?.length &amp;gt; 0) {
    return data.map((post) =&amp;gt; &amp;lt;Card key={post._id} {...post} /&amp;gt;);
  }

  return (
    &amp;lt;h2 className="mt-5 font-bold text-[#6449ff] text-xl uppercase"&amp;gt;{title}&amp;lt;/h2&amp;gt;
  );
};

const Home = () =&amp;gt; {
  const [loading, setLoading] = useState(false);
  const [allPosts, setAllPosts] = useState(null);

  const [searchText, setSearchText] = useState("");
  const [searchedResults, setSearchedResults] = useState(null);
  const [searchTimeout, setSearchTimeout] = useState(null);

  // Integrate with the backend to fetch all posts
  useEffect(() =&amp;gt; {
    const fetchPosts = async () =&amp;gt; {
      setLoading(true);

      try {
        const response = await fetch(
          "https://dall-e-4e72.onrender.com/api/v1/post",
          {
            method: "GET",
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        if (response.ok) {
          const result = await response.json();
          setAllPosts(result.data.reverse());
        }
      } catch (error) {
        alert("Something went wrong");
      } finally {
        setLoading(false);
      }
    };

    fetchPosts();
  }, []);

  // Search functionality
  const handleSearchChange = (e) =&amp;gt; {
    clearTimeout(searchTimeout);

    setSearchText(e.target.value);

    setSearchTimeout(
      setTimeout(() =&amp;gt; {
        const searchResults = allPosts.filter(
          (item) =&amp;gt;
            item.name.toLowerCase().includes(searchText.toLowerCase()) ||
            item.prompt.toLowerCase().includes(searchText.toLowerCase())
        );

        setSearchedResults(searchResults);
      }, 500)
    );
  };

  return (
    &amp;lt;section className="max-w-7xl mx-auto"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1 className="font-extrabold text-[#222328] text-[2rem]"&amp;gt;
          DALL-E AI Gallery
        &amp;lt;/h1&amp;gt;
        &amp;lt;p className="mt-2 text-[#666e75] text-[1rem]"&amp;gt;
          Browse through the images generated by DALL-E AI. You can also create
          a new post and share your own images.
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className="mt-16"&amp;gt;
        &amp;lt;FormField
          labelName="Search Posts"
          type="text"
          name="text"
          placeholder="Search by name or prompt"
          value={searchText}
          handleChange={handleSearchChange}
        /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className="mt-10"&amp;gt;
        {loading ? (
          &amp;lt;div className="flex justify-center items-center"&amp;gt;
            &amp;lt;Loader /&amp;gt;
          &amp;lt;/div&amp;gt;
        ) : (
          &amp;lt;&amp;gt;
            {searchText &amp;amp;&amp;amp; (
              &amp;lt;h2 className="font-medium text-[#666e75] text-xl mb-3"&amp;gt;
                Search Results for{" "}
                &amp;lt;span className="text-[#222328]"&amp;gt;{searchText}&amp;lt;/span&amp;gt;
              &amp;lt;/h2&amp;gt;
            )}

            &amp;lt;div className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3"&amp;gt;
              {searchText ? (
                &amp;lt;RenderCards data={searchedResults} title="No results found" /&amp;gt;
              ) : (
                &amp;lt;RenderCards data={allPosts} title="No posts found" /&amp;gt;
              )}
            &amp;lt;/div&amp;gt;
          &amp;lt;/&amp;gt;
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  );
};

export default Home;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "Home" component sets up several state variables, including "loading", "allPosts", "searchText", "searchedResults", and "searchTimeout", using the "useState" hook.&lt;/p&gt;

&lt;p&gt;It also uses the "useEffect" hook to fetch all posts from an API when the component first renders and sets the state variables accordingly.&lt;/p&gt;

&lt;p&gt;The component also includes a search functionality, where the "handleSearchChange" function is called when the user types into the search field.&lt;/p&gt;

&lt;p&gt;The component then renders either the searched results or all posts, and includes a loading spinner if the data is still being fetched from the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAGES index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Home from "./Home";
import CreatePost from "./CreatePost";

export { Home, CreatePost };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;UTILS index.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import FileSaver from "file-saver";

import { surpriseMePrompts } from "../constant";

export function getRandomPrompt() {
  const randomIndex = Math.floor(Math.random() * surpriseMePrompts.length);
  const randomPrompt = surpriseMePrompts[randomIndex];

  //   To not get the same prompt twice in a row
  if (randomPrompt === prompt) return getRandomPrompt(prompt);

  return randomPrompt;
}

export async function downloadImage(_id, photo) {
  FileSaver.saveAs(photo, `download-${_id}.jpg`);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is importing the FileSaver library which is used to save a file to the user's device. It also imports an array of strings named "surpriseMePrompts" from a separate file.&lt;/p&gt;

&lt;p&gt;The function "downloadImage" takes in two parameters, _id and photo. It then uses the FileSaver library to save the "photo" file to the user's device with the file name "download-_id.jpg".&lt;/p&gt;

&lt;p&gt;I've used &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; for storing the images after retrieving from the &lt;a href="https://cloudinary.com/" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt; after generating an image using &lt;a href="https://openai.com/api/" rel="noopener noreferrer"&gt;OpenAI API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt; is a great hosting cloud platform which we can use it for deploying the backend and I've used &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;vercel&lt;/a&gt; for the frontend.&lt;/p&gt;

&lt;p&gt;A tip I can leave which I've found useful while choosing a color palette for the website is &lt;a href="https://www.visme.co/" rel="noopener noreferrer"&gt;Visme&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's all to it, folks. I wanted to show my gratitude to &lt;a href="https://www.youtube.com/watch?v=EyIvuigqDoA&amp;amp;t=159s" rel="noopener noreferrer"&gt;JavaScript Mastery&lt;/a&gt; for making this wonderful MERN stack webapp possible. He's just awesome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/dall-e-ai-img-gen" rel="noopener noreferrer"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dall-e-ai-img-gen.vercel.app/" rel="noopener noreferrer"&gt;Live 🚀&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm gonna wrap it up with links provided to my GitHub repo and to the live deployment. See you soon!&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>New Year Countdown</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 01 Jan 2023 14:02:53 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/new-year-countdown-531k</link>
      <guid>https://dev.to/jagadeeshkj/new-year-countdown-531k</guid>
      <description>&lt;p&gt;Hola! How're you doing? I'm hoping for the best. I wish you a lovely happy new year. This is gonna be my 1st post in this new year 2023 'Tis.  &lt;/p&gt;

&lt;p&gt;This is not a project but just a cool time pass with vanilla javascript. I've always wanted a countdown timer to catch up with seconds while capturing the moment Iron man snaps in the Avengers Endgame. &lt;a href="https://www.instagram.com/reel/Cm1_opUjbcN/?utm_source=ig_web_copy_link"&gt;Voila!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/new-year-countdown"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://new-year-countdown-six.vercel.app/"&gt;Live 🚀&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The boilerplate for this project is simple as it looks in this hierarchy of files.&lt;/p&gt;

&lt;p&gt;.&lt;br&gt;
├── index.html&lt;br&gt;
├── script.js&lt;br&gt;
└── style.css&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css" /&amp;gt;
    &amp;lt;title&amp;gt;Happy New Year&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;

  &amp;lt;body&amp;gt;
    &amp;lt;div id="year" class="year"&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;h1&amp;gt;New Year Countdown&amp;lt;/h1&amp;gt;

    &amp;lt;div id="countdown" class="countdown"&amp;gt;
      &amp;lt;div class="time"&amp;gt;
        &amp;lt;h2 id="days"&amp;gt;00&amp;lt;/h2&amp;gt;
        &amp;lt;small&amp;gt;days&amp;lt;/small&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="time"&amp;gt;
        &amp;lt;h2 id="hours"&amp;gt;00&amp;lt;/h2&amp;gt;
        &amp;lt;small&amp;gt;hours&amp;lt;/small&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="time"&amp;gt;
        &amp;lt;h2 id="minutes"&amp;gt;00&amp;lt;/h2&amp;gt;
        &amp;lt;small&amp;gt;minutes&amp;lt;/small&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="time"&amp;gt;
        &amp;lt;h2 id="seconds"&amp;gt;00&amp;lt;/h2&amp;gt;
        &amp;lt;small&amp;gt;seconds&amp;lt;/small&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;img
      src="./img/spinner.gif"
      alt="Loading..."
      id="loading"
      class="loading"
    /&amp;gt;

    &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;/p&gt; with the id of "year" and class of "year" will display the current year. The &lt;h1&gt; tag displays the title of the countdown. 

&lt;/h1&gt;
&lt;p&gt;The &lt;/p&gt; with the id of "countdown" and class of "countdown" contains four other s that each contain an &lt;h2&gt; tag with an id of either days, hours, minutes, or seconds. 

&lt;/h2&gt;
&lt;p&gt;These will display the number of days, hours, minutes, and seconds until New Year's Day. &lt;/p&gt;

&lt;p&gt;The &lt;a href="" class="article-body-image-wrapper"&gt;&lt;img&gt;&lt;/a&gt; tag displays a loading spinner while the script is running and the script itself is located in a file called "script.js".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Script.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const days = document.getElementById('days');
const hours = document.getElementById('hours');
const minutes = document.getElementById('minutes');
const seconds = document.getElementById('seconds');
const countdown = document.getElementById('countdown');
const year = document.getElementById('year');
const loading = document.getElementById('loading');

const currentYear = new Date().getFullYear();

const newYearTime = new Date(`January 01 ${currentYear + 1} 00:00:00`);

// Set background year
year.innerText = currentYear + 1;

// Update countdown time
function updateCountdown() {
  const currentTime = new Date();
  const diff = newYearTime - currentTime;

  const d = Math.floor(diff / 1000 / 60 / 60 / 24);
  const h = Math.floor(diff / 1000 / 60 / 60) % 24;
  const m = Math.floor(diff / 1000 / 60) % 60;
  const s = Math.floor(diff / 1000) % 60;

  // Add values to DOM
  days.innerHTML = d;
  hours.innerHTML = h &amp;lt; 10 ? '0' + h : h;
  minutes.innerHTML = m &amp;lt; 10 ? '0' + m : m;
  seconds.innerHTML = s &amp;lt; 10 ? '0' + s : s;
}

// Show spinner before countdown
setTimeout(() =&amp;gt; {
  loading.remove();
  countdown.style.display = 'flex';
}, 1000);

// Run every second
setInterval(updateCountdown, 1000);

&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This code is setting up a countdown timer for the new year. It starts by declaring variables for each of the elements in the HTML document that will be used in the countdown. &lt;/p&gt;

&lt;p&gt;It then sets the current year and creates a new Date object for the new year. The updateCountdown() function is then declared which calculates the difference between the current time and the new year time, and stores it in days, hours, minutes, and seconds. &lt;/p&gt;

&lt;p&gt;The values are then added to the DOM using innerHTML. A setTimeout() function is used to remove a loading spinner before displaying the countdown, and a setInterval() function is used to run updateCountdown() every second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styles&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css?family=Muli&amp;amp;display=swap');

* {
  box-sizing: border-box;
}

body {
  background-image: url('https://images.unsplash.com/photo-1467810563316-b5476525c0f9?ixlib=rb-1.2.1&amp;amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=1349&amp;amp;q=80');
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  height: 100vh;
  color: #fff;
  font-family: 'Muli';
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0;
  overflow: hidden;
}

/* Add a dark overlay */
body::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

body * {
  z-index: 1;
}

h1 {
  font-size: 60px;
  margin: -80px 0 40px;
}

.year {
  font-size: 200px;
  z-index: -1;
  opacity: 0.2;
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
}

.countdown {
  /* display: flex; */
  display: none;
  transform: scale(2);
}

.time {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 15px;
}

.time h2 {
  margin: 0 0 5px;
}

@media (max-width: 500px) {
  h1 {
    font-size: 45px;
  }

  .time {
    margin: 5px;
  }

  .time h2 {
    font-size: 12px;
    margin: 0;
  }

  .time small {
    font-size: 10px;
  }
}

&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The @import statement at the top of the code imports a font from Google Fonts called 'Muli'. &lt;/p&gt;

&lt;p&gt;The rest of the code sets up styling for the body element, including background image, color, font family, and another styling.&lt;/p&gt;

&lt;p&gt;It also sets up styling for elements within the body such as h1 and .year. &lt;/p&gt;

&lt;p&gt;Finally, it includes a media query to adjust styling for smaller screens.&lt;/p&gt;

&lt;p&gt;And the final output looks something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sMta-wdk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2gnbcwztz164w4fkn46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sMta-wdk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2gnbcwztz164w4fkn46.png" alt="voila" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for the start of a year fellas. A wise man once said, "start small". I'll see you soon.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>OpenAI CodeX ChatBot</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 25 Dec 2022 16:20:53 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/openai-codex-chatbot-5d06</link>
      <guid>https://dev.to/jagadeeshkj/openai-codex-chatbot-5d06</guid>
      <description>&lt;p&gt;Hey there! How's it going? It's been a while since we last had our interaction in dev. Here we build stuff, little but great and cool.&lt;/p&gt;

&lt;p&gt;Today we're gonna build and deploy a live chatbot that can help you answer any question you have regarding to coding and stuff (and definitely not your relationship doubts, eh? Just kidding!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/codeX" rel="noopener noreferrer"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://codex-psi-lemon.vercel.app/" rel="noopener noreferrer"&gt;Live 🚀&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final output looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsb6r14gcw708kpmyx3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsb6r14gcw708kpmyx3x.png" alt="end result" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that said, let's jump into action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack used&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML5&lt;/li&gt;
&lt;li&gt;CSS3&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;Express &lt;/li&gt;
&lt;li&gt;OpenAI API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We start with two folders named client and server in our project folder which looks in heirarchy like this.&lt;/p&gt;

&lt;p&gt;.&lt;br&gt;
├── client/&lt;br&gt;
│   ├── assets&lt;br&gt;
│   ├── index.html&lt;br&gt;
│   ├── style.css&lt;br&gt;
│   └── script.js&lt;br&gt;
└── server/&lt;br&gt;
    └── server.js&lt;/p&gt;

&lt;p&gt;You can checkout my GtHub repo provided above to see the files you need and how it actually structured. &lt;/p&gt;

&lt;p&gt;The assets folder consists nothing but some images required for the project. &lt;/p&gt;

&lt;p&gt;I hope you'd node js in your system. You're gonna need node js to run this project.&lt;/p&gt;

&lt;p&gt;Create a template for our project in plain vanilla javascript.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm create vite@latest client --template vanilla&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLIENT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we start with client side first. Assuming you'd know how to link styles and script files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div id="app"&amp;gt;
      &amp;lt;div id="chat_container"&amp;gt;
        &amp;lt;!-- Main Portion --&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;form&amp;gt;
        &amp;lt;textarea name="prompt" placeholder="What questions do you have?" cols="1" rows="1"&amp;gt;&amp;lt;/textarea&amp;gt;
        &amp;lt;button type="submit"&amp;gt;&amp;lt;img src="assets/send.svg" alt="send it"&amp;gt;&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;script type="module" src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;/p&gt; tag contains all of the content for the page. Inside of the body, there is a div with an id of "app" which contains two elements: a div with an id of "chat_container" and a form with a textarea and submit button. Finally, there is a script tag which links to an external JavaScript file.

&lt;p&gt;&lt;strong&gt;style.css&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css?family=Muli&amp;amp;display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  /* font-family: "Alegreya Sans", sans-serif; */
  font-family: 'Muli';
}

body {
  background: #343541;
}

#app {
  width: 100vw;
  height: 100vh;
  background: #343541;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

#chat_container {
  flex: 1;
  width: 100%;
  height: 100%;
  overflow-y: scroll;

  display: flex;
  flex-direction: column;
  gap: 10px;

  -ms-overflow-style: none;
  scrollbar-width: none;

  padding-bottom: 20px;
  scroll-behavior: smooth;
}

/* hides scrollbar */
#chat_container::-webkit-scrollbar {
  display: none;
}

.wrapper {
  width: 100%;
  padding: 15px;
}

.ai {
  background: #40414F;
}

.chat {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;

  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
}

.profile {
  width: 36px;
  height: 36px;
  border-radius: 5px;

  background: #5436DA;

  display: flex;
  justify-content: center;
  align-items: center;
}

.ai .profile {
  background: #10a37f;
}

.profile img {
  width: 60%;
  height: 60%;
  object-fit: contain;
}

.message {
  flex: 1;

  color: #dcdcdc;
  font-size: 20px;

  max-width: 100%;
  overflow-x: scroll;

  white-space: pre-wrap; 

  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* hides scrollbar */
.message::-webkit-scrollbar {
  display: none;
}

form {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 10px;
  background: #40414F;

  display: flex;
  flex-direction: row;
  gap: 10px;
}

textarea {
  width: 100%;

  color: #fff;
  font-size: 18px;

  padding: 10px;
  background: transparent;
  border-radius: 5px;
  border: none;
  outline: none;
}

button {
  outline: 0;
  border: 0;
  cursor: pointer;
  background: transparent;
}

form img {
  width: 30px;
  height: 30px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all the styling we need for making this project looking good with UI. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;script.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import bot from './assets/bot.svg';
import user from './assets/user.svg';

const form = document.querySelector('form');
const chatContainer = document.querySelector('#chat_container');

// AI Loading...
let loadInterval;

function loader(element) {
  element.textContent = '';

  loadInterval = setInterval(() =&amp;gt; {
    element.textContent += '.';

    // reset 
    if(element.textContent === '....') {
      element.textContent = '';
    }
  }, 300)
}

// AI typing...
function typeText(element, text) {
  let index = 0;

  let interval = setInterval(() =&amp;gt; {
    if(index &amp;lt; text.length) {
      element.innerHTML += text.charAt(index);
      index++;
    } else {
      clearInterval(interval);
    }
  }, 20)
}

function generateUniqueId() {
  const timestamp = Date.now();
  const randomNumber = Math.random();
  const hexaStr = randomNumber.toString(16);

  return `id-${timestamp}-${hexaStr}`;
}

// chat dark and light grey stripes
function chatStripe (isAI, value, uniqueId) {
  return (
    `
    &amp;lt;div class = "wrapper ${isAI &amp;amp;&amp;amp; 'ai'}"&amp;gt;
      &amp;lt;div class = "chat"&amp;gt;
        &amp;lt;div class = "profile"&amp;gt;
          &amp;lt;img
            src = "${isAI ? bot : user}"
            alt = "${isAI ? 'bot' : 'user'}"
          /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div class = "message" id = ${uniqueId}&amp;gt;
          ${value}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    `
  )
}

const handleSubmit = async(e) =&amp;gt; {
  e.preventDefault();

  const data = new FormData(form);

  // user's chat stripe
  chatContainer.innerHTML += chatStripe(false, data.get('prompt'));

  form.reset();

  // bot's chat stripe
  const uniqueId = generateUniqueId();
  chatContainer.innerHTML += chatStripe(true, " ", uniqueId);
  chatContainer.scrollTop = chatContainer.scrollHeight;

  const messageDiv = document.getElementById(uniqueId);

  loader(messageDiv);

  // fetch data from server -&amp;gt; bot's response

  const response = await fetch('https://codex-djxd.onrender.com/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      prompt: data.get('prompt')
    })
  })

  clearInterval(loadInterval);
  messageDiv.innerHTML = '';

  if(response.ok) {
    const data = await response.json();
    const parsedData = data.bot.trim();

    typeText(messageDiv, parsedData);
  } else {
    const err = await response.text();

    messageDiv.innerHTML = "Something went wrong";

    alert(err);
  }
}

// Submit by pressing enter
form.addEventListener('submit', handleSubmit);
form.addEventListener('keyup', (e) =&amp;gt; {
  if(e.keyCode === 13) {
    handleSubmit(e);
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is a chatbot program. It imports two images, one for the user and one for the bot. It then creates a form element and a chat container element. It then defines functions to load, type text, generate unique IDs, and create chat stripes. &lt;/p&gt;

&lt;p&gt;The handleSubmit function is called when the user submits the form or presses enter. This function sends the user's message to the server and receives a response from the bot. The response is then displayed in the chat container with a unique ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SERVER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's make our project work by fetching and uploading data as in client-server architecture.&lt;/p&gt;

&lt;p&gt;Generate a new package.json file inside your server folder by entering the command below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we need to install a couple of dependencies to do our server side work properly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install cors dotenv express nodemon openai&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;server.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import * as dotenv from 'dotenv';
import cors from 'cors';
import { Configuration, OpenAIApi } from 'openai';

dotenv.config();

const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY,
});

const openai = new OpenAIApi(configuration);

const app = express();
app.use(cors());
app.use(express.json());

app.get('/', async(req, res) =&amp;gt; {
    res.status(200).send({
        message: 'Hello from CodeX',
    })
});

// fetches data from frontend body
app.post('/', async(req, res) =&amp;gt; {
    try {
        const prompt = req.body.prompt;

        // used from openai examples
        const response = await openai.createCompletion({
            model: "text-davinci-003",
            prompt: `${prompt}`,
            temperature: 0,
            max_tokens: 3000,
            top_p: 1,
            frequency_penalty: 0.5,
            presence_penalty: 0,
        });

        res.status(200).send({
            bot: response.data.choices[0].text
        })
    } catch (error) {
        console.log(error);
        res.status(500).send({ error })
    }
})

app.listen(5000, () =&amp;gt; console.log('Server is running on port http://localhost:5000'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is setting up an Express server that will be used to communicate with the OpenAI API. It starts by importing the necessary packages and configuring the environment variables.&lt;/p&gt;

&lt;p&gt;Then it sets up an Express server and adds a GET route that will return a message when called. &lt;/p&gt;

&lt;p&gt;Finally, it adds a POST route that will take in data from the frontend, use it to call the OpenAI API, and return the response from OpenAI back to the frontend.&lt;/p&gt;

&lt;p&gt;You can do deploy the server side in Render and client side using vercel after creating a git repository. &lt;/p&gt;

&lt;p&gt;Checkout &lt;a href="https://www.youtube.com/watch?v=2FeymQoKvrk&amp;amp;t=404s&amp;amp;ab_channel=JavaScriptMastery" rel="noopener noreferrer"&gt;here&lt;/a&gt; for the complete tutorial. Helpful!&lt;/p&gt;

&lt;p&gt;That's it for the day folks. See you next time!&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Netflix Clone Build 2.0 With React-Redux and Firebase</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Wed, 26 Oct 2022 13:51:45 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/netflix-clone-build-20-with-react-redux-and-firebase-4kg2</link>
      <guid>https://dev.to/jagadeeshkj/netflix-clone-build-20-with-react-redux-and-firebase-4kg2</guid>
      <description>&lt;p&gt;Hello there! How do you do? I hope you're extremely doing well. Well, this time I've come up with a cloning project. And yes. It's the all time famous "netflix clone". What makes you a web developer without having atleast one clone webapp in your resume? A good one.&lt;/p&gt;

&lt;p&gt;Tools we're going to use: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React JS&lt;/li&gt;
&lt;li&gt;Redux&lt;/li&gt;
&lt;li&gt;Firebase&lt;/li&gt;
&lt;li&gt;TMDB API&lt;/li&gt;
&lt;li&gt;HTML &amp;amp; CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Responsiveness&lt;/li&gt;
&lt;li&gt;Dynamic &lt;/li&gt;
&lt;li&gt;Realtime data fetching&lt;/li&gt;
&lt;li&gt;Updated new list of movies and webseries&lt;/li&gt;
&lt;li&gt;Authenticated users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Firstly we need to create a project folder and name it netflix-clone (anything you want) and open cmd in that directory.&lt;/p&gt;

&lt;p&gt;Now, let's install react redux: &lt;br&gt;
&lt;code&gt;npx create-react-app netflix-clone --template redux&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the directory with a code editor (I'd prefer vscode) and let's get started. &lt;/p&gt;

&lt;p&gt;At the end of the project, we will have the directories heirarichy as shown below:&lt;br&gt;
.&lt;br&gt;
└── netflix-clone/&lt;br&gt;
    └── src/&lt;br&gt;
        ├── app/&lt;br&gt;
        │   └── store.js&lt;br&gt;
        ├── components/&lt;br&gt;
        │   ├── Banner.js&lt;br&gt;
        │   ├── Nav.js&lt;br&gt;
        │   ├── Row.js&lt;br&gt;
        │   ├── HomeScreen.js&lt;br&gt;
        │   ├── LoginScreen.js&lt;br&gt;
        │   ├── SignUpScreen.js&lt;br&gt;
        │   ├── ProfileScreen.js&lt;br&gt;
        │   └── Requests.js&lt;br&gt;
        ├── features/counter/&lt;br&gt;
        │   └── userSlice.js&lt;br&gt;
        ├── img/&lt;br&gt;
        │   └── logo.png&lt;br&gt;
        ├── App.js&lt;br&gt;
        ├── axios.js&lt;br&gt;
        ├── firebase.js&lt;br&gt;
        ├── index.css&lt;br&gt;
        └── index.js&lt;/p&gt;

&lt;p&gt;Meanwhile, let's create a project in firebase console. &lt;/p&gt;

&lt;p&gt;.&lt;br&gt;
├── Firebase Console/&lt;br&gt;
│   └── Add Project/&lt;br&gt;
│       └── Project Name (Anything you wish)&lt;br&gt;
└── Create a web app/&lt;br&gt;
    ├── Give your webapp a name&lt;br&gt;
    ├── Copy the script &lt;br&gt;
    └── Create a firebase.js and paste it there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;firebase.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';


const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: ""
};

const firebaseApp = firebase.initializeApp(firebaseConfig);
const db = firebaseApp.firestore();
const auth = firebase.auth();

export { auth };
export default db;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do me a favour by creating this firebase configuration with your webapp script, would you?&lt;/p&gt;

&lt;p&gt;You'll see something like this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6hblscnbiuhaj8gadq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6hblscnbiuhaj8gadq3.png" alt="firebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We do need authentication activated for our webapp and you can find it in the left side of your firebase website (Build).&lt;/p&gt;

&lt;p&gt;Open it and enable Email and Password auth. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl3c50f9qpd9vebubgbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl3c50f9qpd9vebubgbh.png" alt="email"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we're using TMDB API to fetch the latest movies and webseries data from it. Go to tmdb API and create a account. It's free. Now we need a API key for our project. &lt;/p&gt;

&lt;p&gt;TMDB API/&lt;br&gt;
└── Click on your profile /&lt;br&gt;
    └── Settings/&lt;br&gt;
        └── API (left navbar)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18gz6d1zbpfia3dmk0hv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18gz6d1zbpfia3dmk0hv.png" alt="api key"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's get back to our code editor and let's make some magic happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect } from 'react';
import {
  BrowserRouter as Router,
  Routes,
  Route,
} from "react-router-dom";
import HomeScreen from './components/HomeScreen';
import LoginScreen from './components/LoginScreen';
import { auth } from './firebase';
import { useDispatch, useSelector } from 'react-redux';
import { login, logout, selectUser } from './features/counter/userSlice';
import ProfileScreen from './components/ProfileScreen';

function App() {
  const user = useSelector(selectUser);
  const dispatch = useDispatch();
  useEffect(() =&amp;gt; {
    const unsubscribe = auth.onAuthStateChanged(userAuth =&amp;gt; {
      if(userAuth) {
        dispatch(login({
          uid: userAuth.uid,
          email: userAuth.email,
        }));
      } else {
        dispatch(logout());
      }
    });

    // cleanup
    return unsubscribe;
  }, [dispatch]);

  return (
    &amp;lt;div className="app"&amp;gt;
      &amp;lt;Router&amp;gt;
        {
          !user ? (
            &amp;lt;LoginScreen /&amp;gt;
          ) : (
            &amp;lt;Routes&amp;gt;
              &amp;lt;Route exact path='/' element = {&amp;lt;HomeScreen /&amp;gt;} /&amp;gt;
              &amp;lt;Route path = '/profile' element = {&amp;lt;ProfileScreen /&amp;gt;} /&amp;gt;
            &amp;lt;/Routes&amp;gt;
          )
        }
      &amp;lt;/Router&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the root component for our project. Let's break it down. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It renders &lt;strong&gt;Login Screen&lt;/strong&gt; if the user doesn't get signed in. &lt;/li&gt;
&lt;li&gt;If the user is logged in then it renders the main home screen and profile screen.&lt;/li&gt;
&lt;li&gt;The task of the useEffect is to dispatch the user details when signed in and reload the page when user gets signed out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We're using the bueatiful react-render-dom here with the latest changes in the imports. No errors up to date. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;userSlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: null,
  },
  reducers: {
    login: (state, action) =&amp;gt; {
      state.user = action.payload;
    },
    logout: (state) =&amp;gt; {
      state.user = null;
    }
  },
});

export const { login, logout } = userSlice.actions;
export const selectUser = (state) =&amp;gt; state.user.user;
export default userSlice.reducer;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component is pretty much simple. Think of yourself going to a market and you find there fruits like mango in a row, apples in another row and bananas in another. &lt;/p&gt;

&lt;p&gt;Just like that we have slices for users. The state gets updated whenever user sign-in and sign-out. That's what we all need to listen to events for auth, thanks to redux and firebase auth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;axios.js&lt;/strong&gt;&lt;br&gt;
We need to install axios by using the command "npm i axios".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from 'axios';

const instance = axios.create({
    baseURL: "https://api.themoviedb.org/3"
})

export default instance;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The baseURL given above is really helpful when we fetch movies and webseries data from the TMDB API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requests.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const API_KEY = "your-API-key";

const requests = {
    fetchTrending: `/trending/all/week?api_key=${API_KEY}&amp;amp;language=en-US`,
    fetchNetflixOriginals: `/discover/tv?api_key=${API_KEY}&amp;amp;with_networks=213`,
    fetchTopRated: `/movie/top_rated?api_key=${API_KEY}&amp;amp;language=en-US`,
    fetchActionMovies: `/discover/movie?api_key=${API_KEY}&amp;amp;with_genres=28`,
    fetchComedyMovies: `/discover/movie?api_key=${API_KEY}&amp;amp;with_genres=35`,
    fetchHorrorMovies: `/discover/movie?api_key=${API_KEY}&amp;amp;with_genres=27`,
    fetchRomanceMovies: `/discover/movie?api_key=${API_KEY}&amp;amp;with_genres=10749`,
    fetchDocumentaries: `/discover/movie?api_key=${API_KEY}&amp;amp;with_genres=99`,
};

export default requests;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this file in src &amp;gt; components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Banner.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from '../axios';
import { useEffect, useState } from 'react';
import requests from './Requests';

function Banner() {
    const [movie, setMovie] = useState([]);

    useEffect(() =&amp;gt; {
        async function fetchData() {
            const request = await axios.get(requests.fetchNetflixOriginals);
            setMovie(
                request.data.results[
                    Math.floor(Math.random() * request.data.results.length - 1)
                ]
            );
            return request;
        }

        fetchData();
    }, []);

    const truncate = (str, n) =&amp;gt; {
        return str?.length &amp;gt; n ? str.substr(0, n - 1) + '...' : str
    }

  return (
    &amp;lt;header 
        className='banner'
        style={{
            backgroundSize: "cover",
            backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie?.backdrop_path}")`,
            backgroundPosition: "center center",
        }}
    &amp;gt;
        &amp;lt;div className='banner-content'&amp;gt;
            &amp;lt;h1 className='banner-title'&amp;gt;
                {movie?.title || movie?.name || movie?.original_name}
            &amp;lt;/h1&amp;gt;
            &amp;lt;div className='banner-buttons'&amp;gt;
                &amp;lt;button className='banner-button'&amp;gt;Play&amp;lt;/button&amp;gt;
                &amp;lt;button className='banner-button'&amp;gt;My List&amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;h1 className='banner-description'&amp;gt;
                {
                    truncate(
                        movie.overview, 150
                    )
                }
            &amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div className='banner-fadeBottom' /&amp;gt;
    &amp;lt;/header&amp;gt;
  )
}

export default Banner;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Banner is what we see when the Netflix page get's loaded. The big main one on the top.&lt;/p&gt;

&lt;p&gt;1) We're displaying the banner with the banner content.&lt;br&gt;
2) We've added two buttons just like in Netflix.&lt;br&gt;
3) When the movie description is huge, we truncate it short.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0p84ickhedcacjrrofr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0p84ickhedcacjrrofr.png" alt="netflix"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Row.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "../axios";
import { useEffect, useState } from "react";

const Row = ({ title, fetchURL, isLargeRow = false }) =&amp;gt; {
   const [movies, setMovies] = useState([]);

   const BASE_URL = "https://image.tmdb.org/t/p/original/";

   useEffect(() =&amp;gt; {
    async function fetchData() {
        const request = await axios.get(fetchURL);
        setMovies(request.data.results);
        return request;
    }

    fetchData();
   }, [fetchURL]);

  return (
    &amp;lt;div className='row'&amp;gt;
        &amp;lt;h2&amp;gt;{ title }&amp;lt;/h2&amp;gt;

        &amp;lt;div className="row-posters"&amp;gt;
            {movies.map((movie) =&amp;gt; (
                (isLargeRow &amp;amp;&amp;amp; movie.poster_path) ||
                (!isLargeRow &amp;amp;&amp;amp; movie.backdrop_path)) &amp;amp;&amp;amp; (
                    &amp;lt;img key={movie.id}
                        className = {`row-poster ${isLargeRow &amp;amp;&amp;amp; 'row-posterL'}`}
                        src={`${BASE_URL}${
                            isLargeRow ? movie.poster_path : movie.backdrop_path
                        }`}
                        alt = {movie.name} 
                    /&amp;gt;
                )
            )}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default Row;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those beautiful rows you see down on the main screen, down the banner are fetched using the TMDB API whenever the page loads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nav.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom';

const Nav = () =&amp;gt; {
    const [show, handleShow] = useState(false);
    const navigate = useNavigate();

    const transitionNavBar = () =&amp;gt; {
       (window.scrollY &amp;gt; 100) ? handleShow(true) : handleShow(false);
    }

    useEffect(() =&amp;gt; {
        window.addEventListener("scroll", transitionNavBar);
        // clean-up
        return () =&amp;gt; window.removeEventListener("scroll", transitionNavBar);
    }, []);

  return (
    &amp;lt;div className={`nav ${show &amp;amp;&amp;amp; 'nav-black'}`}&amp;gt;
        &amp;lt;div className='nav-content'&amp;gt;
            &amp;lt;img
                onClick={() =&amp;gt; navigate('/')}
src='https://assets.stickpng.com/images/580b57fcd9996e24bc43c529.png'
                alt='netflix-logo'
                className='navbar-logo'
            /&amp;gt;

            &amp;lt;img 
                onClick={() =&amp;gt; navigate('/profile')}
                src='https://upload.wikimedia.org/wikipedia/commons/0/0b/Netflix-avatar.png'
                alt = "avatar"
                className='navbar-avatar'
            /&amp;gt;
        &amp;lt;/div&amp;gt;

    &amp;lt;/div&amp;gt;
  )
}

export default Nav;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I want to give a brief about this one.&lt;/p&gt;

&lt;p&gt;1) That cool Netflix logo and Avatar you see on Nav bar.&lt;br&gt;
2) When you click on Netflix logo, you'll be navigated to Homepage of netflix.&lt;br&gt;
3) When you click on your Avatar you'll see a profile screen. That's the power of redux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbs7bqxngnn7eep98jbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbs7bqxngnn7eep98jbk.png" alt="profile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ProfileScreen.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import { useSelector } from 'react-redux'
import { selectUser } from '../features/counter/userSlice'
import { auth } from '../firebase'
import Nav from './Nav'

const ProfileScreen = () =&amp;gt; {
  const user = useSelector(selectUser);

  return (
    &amp;lt;div className='profileScreen'&amp;gt;
        &amp;lt;Nav /&amp;gt;
        &amp;lt;div className='profile-body'&amp;gt;
            &amp;lt;h1&amp;gt;Your Profile&amp;lt;/h1&amp;gt;
            &amp;lt;div className='profile-info'&amp;gt;
                &amp;lt;img 
                    src='https://upload.wikimedia.org/wikipedia/commons/0/0b/Netflix-avatar.png' 
                    alt='avatar' 
                /&amp;gt;
                &amp;lt;div className='profile-details'&amp;gt;
                  &amp;lt;h2&amp;gt;{user.email}&amp;lt;/h2&amp;gt;
                  &amp;lt;div className='profile-plan'&amp;gt;
                    &amp;lt;h3&amp;gt;Premium 4K + HDR&amp;lt;/h3&amp;gt;
                    &amp;lt;button 
                      className='profile-signOut'
                      onClick={() =&amp;gt; auth.signOut()}
                    &amp;gt;
                        Sign Out
                    &amp;lt;/button&amp;gt;
                  &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default ProfileScreen;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're fetching the user's email and displaying it with the plan details. Thanks to the useSelector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoginScreen.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from 'react'
import SignUpScreen from './SignUpScreen';
import logo from '../img/login-screen-logo.png'

const LoginScreen = () =&amp;gt; {
    const [signIn, setSignIn] = useState(false);

  return (
    &amp;lt;div className='loginScreen'&amp;gt;
        &amp;lt;div className='login-bg'&amp;gt;
            &amp;lt;img 
                className='login-logo'
                src={logo}
                alt='login-screen-logo' 
            /&amp;gt;
            &amp;lt;button 
                className='login-btn'
                onClick={() =&amp;gt; setSignIn(true)}
            &amp;gt;
                Sign In
            &amp;lt;/button&amp;gt;

            &amp;lt;div className='login-gradient' /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div className='login-body'&amp;gt;
            {signIn ? (
                &amp;lt;SignUpScreen /&amp;gt;
            ) : (
               &amp;lt;&amp;gt;
                &amp;lt;h1&amp;gt;Unlimited movies, TV shows and more.&amp;lt;/h1&amp;gt;
                &amp;lt;h2&amp;gt;Watch anywhere. Cancel anytime.&amp;lt;/h2&amp;gt;
                &amp;lt;h3&amp;gt;Ready to watch? Enter your email to create or restart your membership.&amp;lt;/h3&amp;gt;

                &amp;lt;div className='login-input'&amp;gt;
                    &amp;lt;form&amp;gt;
                        &amp;lt;input 
                            type='email' 
                            placeholder='Email address'
                        /&amp;gt;
                        &amp;lt;button 
                            className='login-getStarted'
                            onClick={() =&amp;gt; setSignIn(true)}
                        &amp;gt;
                            {`Get Started &amp;gt;`} 
                        &amp;lt;/button&amp;gt;
                    &amp;lt;/form&amp;gt;
                &amp;lt;/div&amp;gt;
               &amp;lt;/&amp;gt;
            )}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default LoginScreen;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We build the login screen page for the user as it is shown in the original netflix. &lt;/p&gt;

&lt;p&gt;1) If the user is new, sign up now will be an option.&lt;br&gt;
2) If the user already exists, the user can sign in with their email and password.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SignUpScreen.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useRef } from 'react'
import { auth } from '../firebase';

const SignUpScreen = () =&amp;gt; {
  const emailRef = useRef(null);
  const passwordRef = useRef(null);

  const register = (e) =&amp;gt; {
    e.preventDefault();

    auth.createUserWithEmailAndPassword(
      emailRef.current.value,
      passwordRef.current.value
    ).then((authUser) =&amp;gt; {
      console.log(authUser)
    }).catch((err) =&amp;gt; {
      alert(err.message);
    });
  };

  const signIn = (e) =&amp;gt; {
    e.preventDefault();
    auth.signInWithEmailAndPassword(
      emailRef.current.value,
      passwordRef.current.value
    ).then((authUser) =&amp;gt; {
      console.log(authUser)
    }).catch((err) =&amp;gt; {
      alert(err.message)
    });
  };


  return (
    &amp;lt;div className='signUp'&amp;gt;
        &amp;lt;form&amp;gt;
          &amp;lt;h1&amp;gt;Sign In&amp;lt;/h1&amp;gt;
          &amp;lt;input 
            type="email"
            placeholder='Email address'
            ref={emailRef}
          /&amp;gt;
          &amp;lt;input 
            placeholder='Password'
            type="password"
            ref={passwordRef}
          /&amp;gt;
          &amp;lt;button 
            type='submit'
            onClick={signIn}
          &amp;gt;
            Sign In
          &amp;lt;/button&amp;gt;

          &amp;lt;h4&amp;gt;
            &amp;lt;span className='signUp-gray'&amp;gt;New to Netflix? &amp;lt;/span&amp;gt;
            &amp;lt;span className='signUp-link' onClick={register}&amp;gt;Sign Up now.&amp;lt;/span&amp;gt;
          &amp;lt;/h4&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default SignUpScreen;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use the firebase auth to provide the authentication to our users. When a new user is signed up, their data is stored for login availability. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqqp5rtpazco4xbi3pus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqqp5rtpazco4xbi3pus.png" alt="signin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styling Portion&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css2?family=Readex+Pro:wght@300;400;500;600;700&amp;amp;display=swap');

* {
  margin: 0;
  font-family: 'Readex Pro';
}

/* NavBar */
.nav {
  position: fixed;
  top: 0;
  width: 100%;
  padding: 20px;
  height: 30px;
  z-index: 1;
  transition-timing-function: ease-in;
  transition: all 0.5s;
}



.nav-content {
  display: flex;
  justify-content: space-between;
}

.nav-black {
  background-color: #111;
}

.navbar-logo {
  position: fixed;
  top: 10px;
  left: 0px;
  width: 80px;
  object-fit: contain;
  padding-left: 20px;
  cursor: pointer;
}

.navbar-avatar {
  position: fixed;
  right: 20px;
  width: 30px;
  cursor: pointer;
}

/* Banner */
.banner {
  height: 448px;
  position: relative;
  object-fit: contain;
  color: white;
}

.banner-content {
  margin-left: 30px;
  padding-top: 140px;
  height: 190px;
}

.banner-title {
  font-size: 3rem;
  font-weight: 800;
  padding-bottom: 0.3rem;
}

.banner-description {
  width: 45rem;
  line-height: 1.3;
  padding-top: 1rem;
  font-size: 0.8rem;
  max-width: 360px;
  height: 80px;
}

.banner-fadeBottom {
  height: 7.4rem;
  background-image: linear-gradient(
    100deg,
    transparent,
    rgba(37, 37, 37, 0.61),
    #111
  );
}

.banner-button {
  cursor: pointer;
  color: #fff;
  outline: none;
  border: none;
  font-weight: 700;
  border-radius: 0.2vw;
  margin-right: 1rem;
  background-color: rgba(51, 51, 51, 0.5);
  padding: 0.5rem 2rem;
}

.banner-button:hover {
  color: #000;
  background-color: #e6e6e6;
  transition: all 0.2s;
}

.app {
  background-color: #111;
}

/* Row */
.row {
  color: #fff;
  margin-left: 20px;
}

.row-posters {
  display: flex;
  overflow-y: hidden;
  overflow-x: scroll;
  padding: 20px;
}

.row-posters::-webkit-scrollbar {
  display: none;
}

.row-poster {
  max-height: 100px;
  object-fit: contain;
  margin-right: 10px;
  width: 100%;
  transition: transform 450ms;
}

.row-poster:hover {
  transform: scale(1.08);
  opacity: 1;
}

.row-posterL {
  max-height: 250px;
}

/* LoginScreen */
.loginScreen {
  position: relative;
  height: 100%;
  background: url('https://assets.nflxext.com/ffe/siteui/vlv3/79fe83d4-7ef6-4181-9439-46db72599559/bd05b4ed-7e37-4be9-85c8-078f067bd150/IN-en-20221017-popsignuptwoweeks-perspective_alpha_website_medium.jpg') center no-repeat;
  background-size: cover;
}

.login-logo {
  position: fixed;
  left: 0;
  width: 150px;
  object-fit: contain;
  padding-left: 20px;
}

.login-btn {
  position: fixed;
  right: 20px;
  top: 20px;
  padding: 10px 20px;
  font-size: 1rem;
  color: #fff;
  background-color: #e50914;
  font-weight: 600;
  border: none;
  cursor: pointer;
}

.login-body {
  position: absolute;
  z-index: 1;
  top: 30%;
  color: #fff;
  padding: 20px;
  text-align: center;
  /* centering a absolute element */
  margin-left: auto;
  margin-right: auto;
  left: 0;
  right: 0;
}

.login-gradient {
  width: 100%;
  z-index: 1;
  height: 100vh;
  background: rgba(0, 0, 0, 0.4);
  background-image: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.8) 0,
    rgba(0, 0, 0, 0) 60%,
    rgba(0, 0, 0, 0.8) 100%
  );
}

.login-body &amp;gt; h1 {
  font-size: 3.125rem;
  margin-bottom: 20px;
}

.login-body &amp;gt; h2 {
  font-size: 2rem;
  font-weight: 400;
  margin-bottom: 30px;
}

.login-body &amp;gt; h3 {
  font-size: 1.3rem;
  font-weight: 400;
}

.login-input &amp;gt; form &amp;gt; input {
  padding: 10px;
  outline-width: 0;
  height: 30px;
  width: 30%;
  border: none;
  max-width: 600px;
}

.login-getStarted {
  padding: 15px 20px;
  font-size: 1rem;
  color: #fff;
  background-color: #e50914;
  border: none;
  font-weight: 600;
  cursor: pointer;
}

.login-input {
  margin: 20px;
}


/* Sign-Up Screen */
.signUp{
  max-width: 300px;
  padding: 70px;
  margin-left: auto;
  margin-right: auto;
  background: rgba(0, 0, 0, 0.85);
}

.signUp &amp;gt; form {
  display: grid;
}

.signUp &amp;gt; form &amp;gt; h1 {
  text-align: left;
  margin-bottom: 25px;
}

.signUp &amp;gt; form &amp;gt; input {
  padding: 5px 15px;
  outline-width: 0;
  height: 40px;
  margin-bottom: 14px;
  border-radius: 5px;
  border: none;
}

.signUp &amp;gt; form &amp;gt; button {
  padding: 16px 20px;
  font-size: 1rem;
  color: #fff;
  border-radius: 5px;
  background-color: #e50914;
  border: none;
  font-weight: 600;
  cursor: pointer;
  margin-top: 20px;
}


.signUp &amp;gt; form &amp;gt; h4 {
  text-align: left;
  margin-top: 30px;
}

.signUp-gray {
  color: gray;
}

.signUp-link:hover {
  cursor: pointer;
  text-decoration: underline;
}

/* Profile Screen */
.profileScreen {
  height: 100vh;
  color: #fff;
}

.profile-body {
  display: flex;
  flex-direction: column;
  width: 50%;
  margin-left: auto;
  margin-right: auto;
  padding-top: 8%;
  max-width: 800px;
}

.profile-body &amp;gt; h1 {
  font-size: 60px;
  font-weight: 400;
  border-bottom: 1px solid #282c2d;
  margin-bottom: 20px;
}

.profile-info {
  display: flex;
}

.profile-info &amp;gt; img {
  height: 100px;
}

.profile-details {
  color: #fff;
  margin-left: 25px;
  flex: 1;
}

.profile-details &amp;gt; h2 {
  background-color: gray;
  padding: 15px;
  font-size: 15px;
  padding-left: 20px;
}

.profile-signOut {
  padding: 10px 20px;
  font-size: 1rem;
  margin-top: 5%;
  width: 100%;
  color: #fff;
  background-color: #e50914;
  font-weight: 600;
  border: none;
  cursor: pointer;
}

.profile-plan {
  margin-top: 20px;
}

.profile-plan &amp;gt; h3 {
  border-bottom: 1px solid #282c2d;
  padding-bottom: 10px;
}

@media(max-width: 900px) {
  .profileScreen {
    height: 100vh;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .profile-body &amp;gt; h1 {
    font-size: 1.9rem;
    font-weight: 400;
    border-bottom: 1px solid #282c2d;
    margin-bottom: 20px;
  }

  .profile-info &amp;gt; img {
    height: 50px;
    display: none;
  }

  .login-body &amp;gt; h1 {
    font-size: 2.5rem;
    margin-bottom: 20px;
  }

  .login-body &amp;gt; h2 {
    font-size: 1.5rem;
    font-weight: 400;
    margin-bottom: 30px;
  }

  .login-body &amp;gt; h3 {
    font-size: 0.9rem;
    font-weight: 400;
  }

  .login-input &amp;gt; form {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
  }

  .login-input &amp;gt; form &amp;gt; input {
    width: 80%;
  }

  .login-getStarted{
    margin-top: 10px;
  }

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Final Outlook&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F847igy58h975zar4r57c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F847igy58h975zar4r57c.png" alt="final"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's pretty much up to it. Let's wrap it up with the deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're going to host our webapp in firebase itself with a few commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g firebase-tools
npm run build
firebase login
firebase init
firebase deploy

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The steps are to generate build first, then login using your google account to the firebase and init the firebase by choosing already existing project (here, netflix-clone) and deploy.&lt;/p&gt;

&lt;p&gt;Choose "build" as your firebase public folder. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/netflix-clone" rel="noopener noreferrer"&gt;Code ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://netflix-clone-2aba1.web.app/" rel="noopener noreferrer"&gt;Live 🚀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>firebase</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Firebase React PhotoGallery</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 16 Oct 2022 16:16:29 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/firebase-react-photogallery-37ci</link>
      <guid>https://dev.to/jagadeeshkj/firebase-react-photogallery-37ci</guid>
      <description>&lt;p&gt;Hello there! How do you do? I hope you're extremely well. I'm about to dive you into some mind-blowing project but for doing that I need the next 5 minutes in your life if you'd allow me. That's great!&lt;/p&gt;

&lt;p&gt;The idea of this webapp is to build a photo gallery to display our images wherever you go. Yes, the images can stay in there forever. What a nice way to keep all your memories together as images! &lt;/p&gt;

&lt;p&gt;You can use it as a mini social media to share some great pictures or moments of your acheivements with your groups and your friends can share some cool stuff too. Sounds fun? Oh, Yeah.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;br&gt;
You need to install react for creating this project and also the firebase using node js.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Let's install react js by creating our project folder named "firegram"&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app firegram
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After that, install firebase using the command given below&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i firebase
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We'll be using framer-motion for some cool animations, let's install it and keep it in our project pockets.&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i framer-motion
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now open the project folder in your favourite code editor (I'd recommend vs code for this project).&lt;/p&gt;

&lt;p&gt;Delete the files App.test.js, logo.svg, reportWebVitals.js, setupTests.js as we're not testing for now and clear the code in App.js&lt;/p&gt;

&lt;p&gt;The boiler plate looks something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GkkL5PK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cth2chy0il57v5wwficg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GkkL5PK7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cth2chy0il57v5wwficg.png" alt="boiler plate" width="273" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ImageGrid from './components/ImageGrid';
import Modal from './components/Modal';
import Title from './components/Title';
import UploadForm from './components/UploadForm';
import { useState } from 'react';


const App = () =&amp;gt; {
  const [selectedImg, setSelectedImg] = useState(null);

  return (
    &amp;lt;div className='App'&amp;gt;
        &amp;lt;Title /&amp;gt;
        &amp;lt;UploadForm /&amp;gt;
        &amp;lt;ImageGrid setSelectedImg = {setSelectedImg} /&amp;gt;
        {
          selectedImg &amp;amp;&amp;amp; &amp;lt;Modal setSelectedImg = { setSelectedImg }selectedImg = {selectedImg} /&amp;gt;
        }
    &amp;lt;/div&amp;gt;
  )
}

export default App

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the root component for our project. Just clean out App.js with the code above and I'm going to demonstrate you the components used in App.js&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o3V01K4L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5i1hrkw6g50zxuaat9gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o3V01K4L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5i1hrkw6g50zxuaat9gt.png" alt="begin" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Title.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'

const Title = () =&amp;gt; {
  return (
    &amp;lt;div className='title'&amp;gt;
      &amp;lt;h1&amp;gt;Photo Gallery&amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;Your Pictures&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;Let the pictures showcase your memories.&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default Title;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the starter file for our project. Pretty much what you see on UI before any images are uploaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ImageGrid.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { motion } from 'framer-motion';
import useFirestore from '../hooks/useFirestore'

const ImageGrid = ({ setSelectedImg }) =&amp;gt; {
  const { docs } = useFirestore('images');
  const unique = [...new Map(docs.map((m) =&amp;gt; [m.url, m])).values()];

  return (
    &amp;lt;div className='img-grid'&amp;gt;
      { 
        unique &amp;amp;&amp;amp; unique.map(doc =&amp;gt; (
          &amp;lt;motion.div 
            className='img-wrap' 
            key = {doc.id} 
            onClick = {() =&amp;gt; setSelectedImg(doc.url)}
            whileHover = {{ opacity: 1 }}
            layout
          &amp;gt;
            &amp;lt;motion.img 
              src={doc.url} 
              alt="uploaded-img" 
              initial = {{ opacity: 0 }}
              animate = {{ opacity: 1 }}
              transition = {{ delay: 1 }}
            /&amp;gt;
          &amp;lt;/motion.div&amp;gt;
        )) 
      }
    &amp;lt;/div&amp;gt;
  )
}

export default ImageGrid;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty much what PhotoGrid component does is that it renders each and every image into the UI by collecting the images from firebase firestore database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I1LuNYIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmdle2rcokfhk2h9dqdm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I1LuNYIe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmdle2rcokfhk2h9dqdm.png" alt="firstly" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FirebaseConfig.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore'; 
import { getStorage } from 'firebase/storage';

const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: ""
};


const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const storage = getStorage(app);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the linking file to our project and firebase. You need to get the firebaseConfig data by creating a project in firebase. I'll show you how.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open firebase in your browser and click on 'Get started'&lt;/li&gt;
&lt;li&gt;Create a new project by selecting 'Add Project'&lt;/li&gt;
&lt;li&gt;Name your project and you're good to go. (It's your wish to enable or disable google analytics, for this project it's not needed)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DnahADH6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6q536wojpl2ixamfbec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DnahADH6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6q536wojpl2ixamfbec.png" alt="firebase" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i2TlOP1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbmuzpa1o9283s7qwmgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i2TlOP1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbmuzpa1o9283s7qwmgy.png" alt="firebase" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wr131_iW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0k5l2eb2471qz44q3g8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wr131_iW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0k5l2eb2471qz44q3g8.png" alt="firebase" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Continue and now we need to create a web app by choosing web&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QTm6Zp5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vntlmcp0dck3dbgulk5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QTm6Zp5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vntlmcp0dck3dbgulk5z.png" alt="webapp" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dC9bgMts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0djx8uftj4moai7c5ki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dC9bgMts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0djx8uftj4moai7c5ki.png" alt="webapp" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Name your webapp.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IKfOV_cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdyujc5z7s2jhv2jwot2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IKfOV_cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdyujc5z7s2jhv2jwot2.png" alt="webapp" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the code and save it in your project folder as firebaseConfig.js and the connection is established. &lt;/p&gt;

&lt;p&gt;We'll be using the firestore database and storage services of firebase. For that, I've created two hooks for each of them. Let me enlighten you. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useFirestore.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { db } from "../firebase/config";
import { useEffect, useState } from 'react';
import { collection, onSnapshot, query, orderBy } from "firebase/firestore";

const useFirestore = (col) =&amp;gt; {
  const [docs, setDocs] = useState([]);
  const collectionRef = collection(db, col);
  const q = query(collectionRef, orderBy("createdAt", "desc"));


    useEffect(() =&amp;gt; {
        const unsub = onSnapshot(q, (snap) =&amp;gt; {
            let documents = [];
            snap.forEach(doc =&amp;gt; {
                documents.push({...doc.data(), id: doc.id})
            });
            setDocs(documents);
        })

        return () =&amp;gt; unsub(); 

    }, [collection])

  return { docs };
}

export default useFirestore;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're using the useEffect hook to fetch the docs (images) from the firestore database (db) every time there's a change in the firestore database. Given a query, we pass it as a parameter to onSnapshot, which takes a snapshot of the firestore db every time a change occurs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useStorage.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react';
import { storage, db } from '../firebase/config';
import { 
    ref, 
    uploadBytesResumable, 
    getDownloadURL 
} from "firebase/storage";
import { 
    collection, 
    addDoc, 
    serverTimestamp
  } from 'firebase/firestore';

const useStorage = (file) =&amp;gt; {
    const [progress, setProgress] = useState(0);
    const [error, setError] = useState(null);
    const [url, setUrl] = useState(null);

  const collectionRef = collection(db, "images");

    useEffect(() =&amp;gt; {
        const storageRef = ref(storage, file.name);
        const uploadTask = uploadBytesResumable(storageRef, file);

        uploadTask.on('state_changed', (snapshot) =&amp;gt; {
            let percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            setProgress(percentage);
        }, (err) =&amp;gt; {
            setError(err);
        }, async () =&amp;gt; {
            const url = await getDownloadURL(uploadTask.snapshot.ref);
            setUrl(url);
            addDoc(collectionRef, { url, createdAt: serverTimestamp() });
        })

    }, [file]);

  return { progress, url, error }
}

export default useStorage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, don't be worried by the above code. It's pretty much easy. What this component does is that it'll create a collection in firestore database by uploading the url of the image. &lt;/p&gt;

&lt;p&gt;We can get the image url after uploading it to the firebase storage by using uploadTask and getDownloadURL. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f8Y4cATR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdhreb6k8ficjojsrm80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f8Y4cATR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdhreb6k8ficjojsrm80.png" alt="progress bar" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That progress bar you see above is the upload rate of the image to the firebase storage. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modal.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { motion } from 'framer-motion';

const Modal = ({ selectedImg, setSelectedImg }) =&amp;gt; {
    const handleClick = (e) =&amp;gt; {
        if(e.target.classList.contains('backdrop')) {
            setSelectedImg(null);
        }
    }

  return (
    &amp;lt;motion.div 
      className='backdrop' 
      onClick={handleClick}
      initial = {{ opacity: 0 }}
      animate = {{ opacity: 1 }}
    &amp;gt;
        &amp;lt;motion.img 
          src={selectedImg} 
          alt='modal-img'
          initial = {{ y: "-100vh" }}
          animate = {{ y: 0 }}
        /&amp;gt;
    &amp;lt;/motion.div&amp;gt;
  )
}

export default Modal;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you click on any image on the UI, it'll be enlarged and displayed as a modal on our UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8e3kq5rr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2qyrcg1fllrlmifkie5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8e3kq5rr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2qyrcg1fllrlmifkie5.png" alt="modal" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UploadForm.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from 'react';
import ProgressBar from './ProgressBar';

const UploadForm = () =&amp;gt; {
    const [file, setFile] = useState(null);
    const [error, setError] = useState(null);
    const types = ['image/png', 'image/jpeg'];

    const changeHandler = (e) =&amp;gt; {
        let selected = e.target.files[0];

        if(selected &amp;amp;&amp;amp; types.includes(selected.type)) {
            setFile(selected);
            setError('');
        } else {
            setError('Please choose an image (jpeg or png)');
            setFile(null);
        }
    }

  return (
    &amp;lt;form&amp;gt;
        &amp;lt;label&amp;gt;
            &amp;lt;input 
                type = 'file'
                onChange={changeHandler}
            /&amp;gt;
            &amp;lt;span&amp;gt;+&amp;lt;/span&amp;gt;
        &amp;lt;/label&amp;gt;
        &amp;lt;div className='output'&amp;gt;
            { error &amp;amp;&amp;amp; &amp;lt;div className='error'&amp;gt;{ error }&amp;lt;/div&amp;gt;}
            { file &amp;amp;&amp;amp; &amp;lt;div&amp;gt; {file.name} &amp;lt;/div&amp;gt; }
            { file &amp;amp;&amp;amp; &amp;lt;ProgressBar file = {file} setFile = {setFile} /&amp;gt; }
        &amp;lt;/div&amp;gt;
    &amp;lt;/form&amp;gt;
  )
}

export default UploadForm;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The imput tag you see on UI with a "+" is rendered by this component. We accept images of types jpeg or png otherwise it'll display an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E2C3ySss--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sca71u2mhlr99e0bee15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E2C3ySss--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sca71u2mhlr99e0bee15.png" alt="upload img" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's pretty much up to it. I'll wrap up here. I want to thank Brad Traversy and Net Ninja for making this project possible. It's cool as this is my very first webapp. &lt;/p&gt;

&lt;p&gt;The final UI looks like this with loaded images using some cool framer-motion animations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FOChHC2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hiafd7mhxowmimhd6d12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FOChHC2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hiafd7mhxowmimhd6d12.png" alt="final" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase Hosting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're going to host our webapp in firebase itself with a few commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g firebase-tools
npm run build
firebase login
firebase init
firebase deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The steps are to generate build first, then login using your google account to the firebase and init the firebase by choosing already existing project (here firegram) and deploy.&lt;/p&gt;

&lt;p&gt;When you enter "firebase init" you need to choose something like "&amp;gt;() Hosting: Config...firebase...Github" by pressing space button.&lt;/p&gt;

&lt;p&gt;Choose your firebase project for your webapp and enter "build" as the public directory. &lt;/p&gt;

&lt;p&gt;Cool. See you next week. Keep smiling! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/react-firebase-photo-gallery"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://firegram-8cab6.web.app/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>firebase</category>
      <category>webdev</category>
      <category>sidehustle</category>
    </item>
    <item>
      <title>Task Tracker with React</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 09 Oct 2022 06:40:02 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/task-tracker-with-react-3nd6</link>
      <guid>https://dev.to/jagadeeshkj/task-tracker-with-react-3nd6</guid>
      <description>&lt;p&gt;How's your weekend going? I hope it's fruitful and lovely! Here comes a cool react project which is the "task tracker". Let me steel the next 3 minutes of your perfectly managed time to make your weekend a little bit more interesting with this cool project.&lt;/p&gt;

&lt;p&gt;As for the boiler plate, you need to install react JS in prior to work on this project. You can get the prerequisites fulfilled in my previous post. I'll provide the link at the end, don't worry about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--68OdPv8p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul7rwx11i58ptjo8lq33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--68OdPv8p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul7rwx11i58ptjo8lq33.png" alt="sample" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to Brad Traversy for making this possible. Here is a picture of showing that every highlighted one is a unique and reusable component in react. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The idea is to make a track of our tasks as you see the usecase in Notes or Tasks in your mobile devices. Yes, but this is gonna be a webapp. Here we add some tasks and make some tasks as reminders and then let the react manage them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
import AddTask from "./components/AddTask";
import Header from "./components/Header";
import Tasks from "./components/Tasks";


function App() {
  const [showAddTask, setShowAddTask] = useState(false);
  const [tasks, setTasks] = useState([
    {
        id: 1, 
        text: 'Marvels Appointment',
        day: 'Oct 15th at 2:30pm',
        reminder: true,
    },
    {
        id: 2, 
        text: 'Meeting at School',
        day: 'Nov 5th at 1:30pm',
        reminder: true,
    },
    {
        id: 3, 
        text: 'Grocery Shopping',
        day: 'Nov 6th at 4:30pm',
        reminder: false,
    },
  ])

  const addTask = (task) =&amp;gt; {
    const id = Math.floor(Math.random() * 10000) + 1
    const newTask = {id, ...task}
    setTasks([...tasks, newTask])
  }

  const deleteTask = (id) =&amp;gt; {
    setTasks(tasks.filter((task) =&amp;gt; task.id !== id))
  }

  const toggleReminder = (id) =&amp;gt; {
    setTasks(
      tasks.map((task) =&amp;gt; 
        task.id === id ? {...task, reminder: !task.reminder} : task
      )
    )
  }


  return (
    &amp;lt;div className="container"&amp;gt;
      &amp;lt;Header 
        onAdd = {() =&amp;gt; setShowAddTask(!showAddTask)} 
        showAdd = {showAddTask}
      /&amp;gt;
      {
        showAddTask &amp;amp;&amp;amp; &amp;lt;AddTask onAdd = {addTask} /&amp;gt;
      }
      {
        tasks.length &amp;gt; 0 ? 
          &amp;lt;Tasks tasks = {tasks} onDelete = {deleteTask} onToggle = {toggleReminder} /&amp;gt; :
          'No Tasks To Show'
      }
    &amp;lt;/div&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, don't worry looking at this code. Let me make it easy for you. In brief, what this code exactly does is that we take a bunch of tasks in prior and then we write functions to add or remove tasks by using the useful map and filter methods in JS. We have created a state called tasks (array) consisting each and every task (object).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasks.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Task from "./Task"
const Tasks = ({ tasks, onDelete, onToggle }) =&amp;gt; {
  return (
    &amp;lt;&amp;gt;
        {tasks.map((task) =&amp;gt; (
            &amp;lt;Task key = {task.id} task = {task} onDelete = {onDelete} onToggle = {onToggle}/&amp;gt;
        ))}
    &amp;lt;/&amp;gt;
  )
}

export default Tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here comes the next component Tasks.js (remember that we've created every part of this UI as a component) used to render the tasks one by one by calling another component called Task.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { FaTimes } from 'react-icons/fa';

const Task = ({ task, onDelete, onToggle }) =&amp;gt; {
  return (
    &amp;lt;div className = {`task ${task.reminder &amp;amp;&amp;amp; 'reminder'}`}
    onDoubleClick = {() =&amp;gt; onToggle(task.id)}
    &amp;gt;
        &amp;lt;h3&amp;gt; 
          {task.text} 
          &amp;lt;FaTimes style={{ color: 'red', cursor: 'pointer' }} 
          onClick = {() =&amp;gt; onDelete(task.id)}
          /&amp;gt; 
        &amp;lt;/h3&amp;gt;

        &amp;lt;p&amp;gt; {task.day} &amp;lt;/p&amp;gt; 
    &amp;lt;/div&amp;gt;
  )
}

export default Task

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each and every task is a unique and reusable component in our project and we make it to seperate the code for reusablity and better management. I'll add a image to make you understand of all the components created and used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H2fr44lH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdzvjym6xvjvgwzz813e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H2fr44lH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdzvjym6xvjvgwzz813e.png" alt="components" width="214" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styles.css&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400&amp;amp;display=swap');

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Poppins', sans-serif;
}

.container {
  max-width: 500px;
  margin: 30px auto;
  overflow: auto;
  min-height: 300px;
  border: 1px solid steelblue;
  padding: 30px;
  border-radius: 5px;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.btn {
  display: inline-block;
  background-color: #000;
  color: #fff;
  border: none;
  padding: 10px 20px;
  margin: 5px;
  border-radius: 5px;
  cursor: pointer;
  text-decoration: none;
  font-size: 15px;
  font-family: inherit;
}

.btn:focus {
  outline: none;
}

.btn:active {
  transform: scale(0.98);
}

.btn-block {
  display: block;
  width: 100%;
}

.task {
  background-color: #f4f4f4;
  margin: 5px;
  padding: 10px 20px;
  cursor: pointer;
}

.reminder {
  border-left: 5px solid green;
}

.task h3 {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.add-form {
  margin-bottom: 40px;
}

.form-control {
  margin: 20px 0;
}

.form-control label {
  display: block;
}

.form-control input {
  width: 100%;
  height: 40px;
  margin: 5px;
  padding: 3px 7px;
  font-size: 17px;
}

.form-control-check {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.form-control-check label {
  flex: 1;
}

.form-control-check input {
  flex: 2;
  height: 20px;
}

footer {
  margin-top: 30px;
  text-align: center;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Styling is what makes UI looks more cooler and better. These are all the styling we've used in the code to add beauty to this project.&lt;/p&gt;

&lt;p&gt;I'll wrap up here. Pretty cool, right? Oh and for the deployment part, I've discussed about that in my previous post. I'll leave the links to my repo and the live running of this project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/jagadeeshkj/react-tailwind-gallery-52gj"&gt;Previous Post 🚀&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/JagadeeshKJ/task-tracker"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jagadeeshkj.github.io/task-tracker/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>React Tailwind Gallery</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Fri, 07 Oct 2022 17:34:03 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/react-tailwind-gallery-52gj</link>
      <guid>https://dev.to/jagadeeshkj/react-tailwind-gallery-52gj</guid>
      <description>&lt;p&gt;Hello there! How do you do? I hope you're doing extremely awesome! Just here to steal 5 minutes of your time (barely) if you'd allow me.&lt;/p&gt;

&lt;p&gt;Here comes my first react app with tailwind css. I'll give you a breif idea about this cool project. &lt;/p&gt;

&lt;p&gt;I have used an API from Pixabay to fetch some beautiful set of images and render them on the screen. Based on the user's input, this project will re-render the images matching the user's query. Pretty simple, right? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhkhdvlzx0p1fvaq7nqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhkhdvlzx0p1fvaq7nqn.png" alt="sample"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a react app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First things first, we need to install react into our project. I'm assuming you've installed node in your pc. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Create a project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a folder named "react-tailwind-gallery" and open vs code editor and then open a terminal.&lt;/p&gt;

&lt;p&gt;npx create-react-app . (coommand for windows)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Install Tailwind CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;npm install -D tailwindcss postcss autoprefixer&lt;br&gt;
npx tailwindcss init -p&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Configure tailwind.config.js file.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a file named "tailwind.config.js" and just copy paste the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4) Add the Tailwind directives to your CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the below code to your ./src/index.css file.&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/tailwind"&gt;@tailwind&lt;/a&gt; base;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/tailwind"&gt;@tailwind&lt;/a&gt; components;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/tailwind"&gt;@tailwind&lt;/a&gt; utilities;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5) Start your build process&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;npm start run &lt;/p&gt;

&lt;p&gt;Now we've created a react project and integrated tailwind to our project. Cool. I'll make sure my root component App.js is up and running error free. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect } from "react";
import ImageCard from "./components/ImageCard";
import ImageSearch from "./components/ImageSearch";

function App() {
  const [images, setImages] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [term, setTerm] = useState('');

  useEffect(() =&amp;gt; {
    fetch(`https://pixabay.com/api/?key={your-pixabay-key}&amp;amp;q=${term}&amp;amp;image_type=photo&amp;amp;pretty=true`)
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; {
      setImages(data.hits);
      setIsLoading(false);
    })
    .catch(err =&amp;gt; console.log(err));
  }, [term]);

  return (
    &amp;lt;div className="container mx-auto"&amp;gt;
      &amp;lt;ImageSearch searchText = {(text) =&amp;gt; setTerm(text)} /&amp;gt;

      {!isLoading &amp;amp;&amp;amp; images.length === 0 &amp;amp;&amp;amp; &amp;lt;h1 className="text-5xl text-center mx-auto mt-32"&amp;gt;No Images Found&amp;lt;/h1&amp;gt;}

      {isLoading ? &amp;lt;h1 className="text-6xl text-center mx-auto mt-32"&amp;gt;Loading...&amp;lt;/h1&amp;gt; 
      : &amp;lt;div className="grid grid-cols-3 gap-4"&amp;gt;
        {images.map(image =&amp;gt; (
          &amp;lt;ImageCard key = {image.id} image = {image} /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't be worried by the code. It's pretty simple. We're trying to render an array of images using an API pixabay using a key given by pixabay. Then we store the response and load the data into an array called images as soon as the page renders (with the help of useEffect hook it's made possible).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ImageCard.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'

const ImageCard = (props) =&amp;gt; {
    const tags = props.image.tags.split(',');

  return (
    &amp;lt;div className="max-w-sm rounded overflow-hidden shadow-lg"&amp;gt;
      &amp;lt;img src={props.image.webformatURL} alt="random" className="w-full" /&amp;gt;
      &amp;lt;div className="px-6 py-4"&amp;gt;
        &amp;lt;div className="font-bold text-red-500 text-xl mb-2"&amp;gt;
          Photo by {props.image.user}
        &amp;lt;/div&amp;gt;
        &amp;lt;ul&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;strong&amp;gt;Views: &amp;lt;/strong&amp;gt;
            {props.image.views}
          &amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;strong&amp;gt;Downloads: &amp;lt;/strong&amp;gt;
            {props.image.downloads}
          &amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;strong&amp;gt;Likes: &amp;lt;/strong&amp;gt;
            {props.image.likes}
          &amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div className="px-6 py-4"&amp;gt;
        {tags.map((tag,index) =&amp;gt; (
            &amp;lt;span key = {index} className="inline-block bg-gray-200 rounded-full px-3 
            py-1 text-sm font-semibold text-gray-700 mr-2"&amp;gt;
              #{tag}
            &amp;lt;/span&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default ImageCard;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the component we use for rendering each and every image card. Here I used the grid alignment to make sure that the image cards are rendered as 3 in coloumn and as many rows as they wish.&lt;br&gt;
It's all basics of react (I'm hoping you'd know them).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ImageSearch.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

const ImageSearch = (props) =&amp;gt; {
  const [text, setText] = useState('');

  const onSubmit = (e) =&amp;gt; {
    e.preventDefault();
    props.searchText(text);
  }

  return (
    &amp;lt;div className='max-w-sm rounded overflow-hidden my-10 mx-auto'&amp;gt;
      &amp;lt;form onSubmit={onSubmit} className="w-full max-w-sm"&amp;gt;
        &amp;lt;div className="flex items-center border-b border-b-2 border-teal-500 py-2"&amp;gt;
            &amp;lt;input onChange={e =&amp;gt; setText(e.target.value)} className="appearance-none bg-transparent border-none w-full text-gray-700 mr-3 py-1 px-2 leading-tight focus:outline-none" type="text" placeholder="Search Image Term..." /&amp;gt;
            &amp;lt;button className="flex-shrink-0 bg-teal-500 hover:bg-teal-700 border-teal-500 hover:border-teal-700 text-sm border-4 text-white py-1 px-2 rounded" type="submit"&amp;gt;
                Search
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default ImageSearch; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the heart to our project. We provide an input field for the user to enter the query. For example, user entered "cats" so that we render only the images related to cats. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlu742fvb4c80qjv7dht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlu742fvb4c80qjv7dht.png" alt="cats-sample-img"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;For each and every time, based on the user's query, this project renders the related image cards using the useEffect hook by fetching the API's data from Pixabay.&lt;/p&gt;

&lt;p&gt;That's pretty much up to it. I don't wanna brag in or go deep. You can have my github repo and the live deployed link to experience the fun!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/react-tailwind-gallery" rel="noopener noreferrer"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jagadeeshkj.github.io/react-tailwind-gallery/" rel="noopener noreferrer"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can end here as the project is over. I just wanted to talk about the deployment part. Here I've deployed this project in GitHub Pages. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1) Firstly create a repo in github with your project name&lt;/p&gt;

&lt;p&gt;2) Enter the commands in your terminal as given below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/JagadeeshKJ/gallery.git
git push -u origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Add GitHub Pages dependency package using this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save gh-pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Add homepage property to package.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"homepage": "https://{username}.github.io/{your-repo-name}/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx37r69s67npchu0svnsb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx37r69s67npchu0svnsb.png" alt="homepage-property"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) Add deploy scripts to package.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"predeploy": "npm run build",
"deploy": "gh-pages -d build"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2k4vkfd337bslax1fa7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2k4vkfd337bslax1fa7.png" alt="scripts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) Deploy the Application to GitHub Pages&lt;/p&gt;

&lt;p&gt;Now run the below command to deploy your react application to GitHub Pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You'll get something like this, in your terminal (vs code).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh-pages -d build
Published
Done in 18.14s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can access the live deployed link using the homepage link which you've added to your package.json &lt;/p&gt;

&lt;p&gt;(Looks like this) "&lt;a href="https://JagadeeshKJ.github.io/react-tailwind-gallery/" rel="noopener noreferrer"&gt;https://JagadeeshKJ.github.io/react-tailwind-gallery/&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>tailwindcss</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Eyes Watching Mouse</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 25 Sep 2022 15:24:07 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/eyes-watching-mouse-269c</link>
      <guid>https://dev.to/jagadeeshkj/eyes-watching-mouse-269c</guid>
      <description>&lt;p&gt;Hey there! How do you do? I hope you're doing superb! I hope the very best for you.&lt;/p&gt;

&lt;p&gt;Here comes a tiny cool thing called "Eyes Watching Mouse" (wait a min...what's that?) let's talk about it, shall we?&lt;/p&gt;

&lt;p&gt;We have a boiler plate for starters with index.html, style.css and script.js and the final outcome looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F590ziw30q4fqjiit9y4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F590ziw30q4fqjiit9y4i.png" alt="smile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We start with the html which is really easy and all it has are some div tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div class="face"&amp;gt;
        &amp;lt;div class="eyes"&amp;gt;
            &amp;lt;div class="eye"&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;div class="eye"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty simple, cool? The main div with a class "face" holds a face with two eyes and that's what you saw in the earlier image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #333;
    cursor: pointer;
}

.face {
    position: relative;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    background-color: #ffcd00;
    display: flex;
    justify-content: center;
    align-items: center;
}

.face::before {
    content: '';
    position: absolute;
    top: 180px;
    width: 150px;
    height: 70px;
    background-color: #b57700;
    border-bottom-left-radius: 70px;
    border-bottom-right-radius: 70px;
    transition: 0.5s;
}

.face:hover::before {
    top: 210px;
    width: 150px;
    height: 20px;
    background-color: #b57700;
    border-bottom-left-radius: 0px;
    border-bottom-right-radius: 0px;
}

.eyes {
    position: relative;
    top: -40px;
    display: flex;
}

.eyes .eye {
    position: relative;
    width: 80px;
    height: 80px;
    display: block;
    background-color: #fff;
    margin: 0 15px;
    border-radius: 50%;
}

.eyes .eye::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 25px;
    transform: translate(-50%, -50%);
    width: 40px;
    height: 40px;
    background-color: #333;
    border-radius: 50%;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll try to give you a brief of this code. So we had a background to highlight the face and we displayed it using flex. It holds another div, if you saw the html code earlier. We have a div with class "eyes" in it. That would be the main portion.&lt;/p&gt;

&lt;p&gt;So when we hover over the face, we have this smile effect goes numb. That's when you hover inside the face. When the region of cursor gets over the face, you'll see the face smile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.querySelector('body').addEventListener('mousemove', eyeball);

function eyeball() {
    var eye = document.querySelectorAll('.eye');
    eye.forEach(function(eye){
        let x = (eye.getBoundingClientRect().left) + (eye.clientWidth / 2);
        let y = (eye.getBoundingClientRect().top) + (eye.clientHeight / 2);
        let radian = Math.atan2(event.pageX - x, event.pageY - y);
        let rot = (radian * (180 / Math.PI) * -1) + 270;
        eye.style.transform = "rotate("+ rot + "deg)";
    })
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand this, I strongly recommend you to have a knowledge hunch on querySelectorAll, getBoundingClientRect, atan2, pageX, pageY.&lt;/p&gt;

&lt;p&gt;The querySelectorAll will select all the queries having in common like all p tags or all h1 tags. The Element.getBoundingClientRect() method returns a DOMRect object providing information about the size of an element and its position relative to the viewport.&lt;/p&gt;

&lt;p&gt;I don't want to go for longer explainations, that wouldn't be so cool. See you next week! I just wanna wrap up here with the links to my Github repo and the live deployment of this whatever you can name-it-and-call-it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/eyes-watching-mouse" rel="noopener noreferrer"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://eyes-watching-mouse-666j.vercel.app/" rel="noopener noreferrer"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
      <category>fun</category>
    </item>
    <item>
      <title>Slider Sign-In/Sign-Up</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 18 Sep 2022 16:09:51 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/slider-sign-insign-up-32m</link>
      <guid>https://dev.to/jagadeeshkj/slider-sign-insign-up-32m</guid>
      <description>&lt;p&gt;Hello there! I hope you're living your best life now. Just another weekend. Another cool project. This time it's the login page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3qsyB3eV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzhq047n4ofgnnrlnq35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3qsyB3eV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzhq047n4ofgnnrlnq35.png" alt="sample" width="880" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the boiler plate, we have index.html, style.css and script.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" 
    href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
    integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
    crossorigin="anonymous"
    &amp;gt;
    &amp;lt;link rel="icon" href="https://www.simplyhealth.co.uk/shcore/sh/furniture/images/svgs/top-nav-account-icon.svg"&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
    &amp;lt;title&amp;gt;Slider Sign In/Sign Up Form&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class="container" id="container"&amp;gt;
        &amp;lt;div class="form-container sign-up-container"&amp;gt;
            &amp;lt;form action="#"&amp;gt;
                &amp;lt;h1&amp;gt;Create Account&amp;lt;/h1&amp;gt;
                &amp;lt;div class="social-container"&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-facebook-f"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-google-plus-g"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-linkedin-in"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;span&amp;gt;or use your email for registration&amp;lt;/span&amp;gt;
                &amp;lt;input type="text" placeholder="Name" /&amp;gt;
                &amp;lt;input type="email" placeholder="Email" /&amp;gt;
                &amp;lt;input type="password" placeholder="Password" /&amp;gt;
                &amp;lt;button&amp;gt;Sign Up&amp;lt;/button&amp;gt;
            &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div class="form-container sign-in-container"&amp;gt;
            &amp;lt;form action="#"&amp;gt;
                &amp;lt;h1&amp;gt;Sign in&amp;lt;/h1&amp;gt;
                &amp;lt;div class="social-container"&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-facebook-f"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-google-plus-g"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                    &amp;lt;a href="#" class="social"&amp;gt;&amp;lt;i class="fab fa-linkedin-in"&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/a&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;span&amp;gt;or use your account&amp;lt;/span&amp;gt;
                &amp;lt;input type="email" placeholder="Email" /&amp;gt;
                &amp;lt;input type="password" placeholder="Password" /&amp;gt;
                &amp;lt;a href="#"&amp;gt;Forgot your password?&amp;lt;/a&amp;gt;
                &amp;lt;button&amp;gt;Sign In&amp;lt;/button&amp;gt;
            &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div class="overlay-container"&amp;gt;
            &amp;lt;div class="overlay"&amp;gt;
                &amp;lt;div class="overlay-panel overlay-left"&amp;gt;
                    &amp;lt;h1&amp;gt;Welcome Back!&amp;lt;/h1&amp;gt;
                    &amp;lt;p&amp;gt;To keep connected with us please login with your personal info&amp;lt;/p&amp;gt;
                    &amp;lt;button class="ghost" id="signIn"&amp;gt;Sign In&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="overlay-panel overlay-right"&amp;gt;
                    &amp;lt;h1&amp;gt;Hello, Friend!&amp;lt;/h1&amp;gt;
                    &amp;lt;p&amp;gt;Enter your personal details and start journey with us&amp;lt;/p&amp;gt;
                    &amp;lt;button class="ghost" id="signUp"&amp;gt;Sign Up&amp;lt;/button&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a form and it consists of two variants. One is the sign-in form and the another one is the sign-up form. Respective one of those will have a overlay content of greetings. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css?family=Montserrat:400,800');

* {
    box-sizing: border-box;
}

body {
    font-family: 'Montserrat', sans-serif;
    background-color: #f6f5f7;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: -20px 0 50px;
}

h1 {
    font-weight: bold;
    margin: 0;
}

p {
    font-size: 14px;
    letter-spacing: 0.5px;
    font-weight: 100;
    line-height: 20px;
    margin: 20px 0 30px;
}

span {
    font-size: 12px;
}

a {
    color: #333;
    text-decoration: none;
    margin: 15px 0;
    font-size: 14px;
}

.container {
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 14px 28px rgba(0,0,0,0.25), 
    0 10px 10px rgba(0,0,0,0.22);
    position: relative;
    overflow: hidden;
    width: 768px;
    max-width: 100%;
    min-height: 480px;
}

.form-container form {
    background-color: #fff;
    display: flex;
    flex-direction: column;
    padding: 0 50px;
    height: 100%;
    justify-content: center;
    align-items: center;
    text-align: center;
}

.social-container {
    margin: 20px 0;
}

.social-container a {
    border: 1px solid #ddd;
    border-radius: 50%;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    height: 40px;
    width: 40px;
    margin: 0 5px;
}

.form-container input {
    background-color: #eee;
    border: none;
    margin: 8px 0;
    padding: 12px 15px;
    width: 100%;
}


button {
    border-radius: 20px;
    border: 1px solid #ff4b2b;
    background-color: #ff4b2b;
    color: #fff;
    font-size: 12px;
    font-weight: bold;
    padding: 12px 45px;
    letter-spacing: 1px;
    text-transform: uppercase;
    transition: transform 80ms ease-in;
}

button:active {
    transform: scale(0.95);
}

button.ghost {
    background: transparent;
    border-color: #fff;
}


.form-container {
    position: absolute;
    top: 0;
    height: 100%;
    transition: all 0.6s ease-in-out;
}

.sign-in-container {
    left: 0;
    width: 50%;
    z-index: 2;
}

.sign-up-container {
    left: 0;
    width: 50%;
    z-index: 1;
    opacity: 0;
}

.overlay-container {
    position: absolute;
    top: 0;
    left: 50%;
    height: 100%;
    width: 50%;
    overflow: hidden;
    transition: transform 0.6s ease-in-out;
    z-index: 100;
}

.overlay {
    background-color: #ff416c;
    background: linear-gradient(to right, #FF4B2B, #FF416C) no-repeat 0 0 / cover; 
    color: #fff;
    position: relative;
    left: -100%;
    height: 100%;
    width: 200%;
    transform: translateX(0);
    transition: transform 0.6s ease-in-out;
}

.overlay-panel {
    position: absolute;
    top: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 0 40px;
    height: 100%;
    width: 50%;
    text-align: center;
    transform: translateX(0);
    transition: transform 0.6s ease-in-out;
}

.overlay-right{
    right: 0;
    transform: translateX(0);
}

.overlay-left {
    transform: translateX(-20%);
}

.container.right-panel-active .sign-in-container {
    transform: translateX(100%);
}

.container.right-panel-active .overlay-container{
    transform: translateX(-100%);
}

.container.container.right-panel-active .sign-up-container{
    transform: translateX(100%);
    opacity: 1;
    z-index: 5;
}

.container.right-panel-active .overlay {
    transform: translateX(50%);
}

.container.right-panel-active .overlay-left {
    transform: translateX(0);
}

.container.right-panel-active .overlay-right {
    transform: translateX(20%);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The styling will take up the huge portion in making this project possible. It includes transitions, transformations and pretty much the basics of css. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('container');

signUpButton.addEventListener('click', () =&amp;gt; {
    container.classList.add("right-panel-active");
});

signInButton.addEventListener('click', () =&amp;gt; {
    container.classList.remove("right-panel-active");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's to the manipulative portion of DOM. Thanks to the event listeners, we can now slide between sign-in and sign-up forms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/slider-sign-in-sign-up"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="https://slider-sign-in-sign-up.vercel.app/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's pretty much up to it, my fellow avid reader. See you in the next weekend!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>sideprojects</category>
      <category>css</category>
    </item>
    <item>
      <title>Gallery Grid</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 11 Sep 2022 16:17:31 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/gallery-grid-4c73</link>
      <guid>https://dev.to/jagadeeshkj/gallery-grid-4c73</guid>
      <description>&lt;p&gt;Hey there! I hope you're doing extremely well. Here's to this week's mini project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NSiFXTYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gok23jgeer99vblk1bbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NSiFXTYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gok23jgeer99vblk1bbg.png" alt="Photo Gallery" width="880" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Start Building
&lt;/h2&gt;

&lt;p&gt;The concept is simple. We're planning on to build a static website hosting a bunch of pictures. This idea is derived from photo gallery which is cool.&lt;/p&gt;

&lt;p&gt;The boiler plate consists of html, css, js pages. The root file is index.html&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
    &amp;lt;link rel="icon" href="https://assets.materialup.com/uploads/5f78aab4-7fbc-4eb8-8ac2-755948f9c89d/preview.jpg"&amp;gt;
    &amp;lt;title&amp;gt;Grid Gallery&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

    &amp;lt;div class="full-img" id="fullImgBox"&amp;gt;
        &amp;lt;img src="img/img1.jpg" id="fullImg" alt="full-img"&amp;gt;
        &amp;lt;span onClick = "closeFullImg()"&amp;gt;X&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="img-gallery"&amp;gt;
        &amp;lt;img src="img/img1.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img2.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img3.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img4.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img5.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img6.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img7.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;img src="img/img8.jpg" onClick = "openFullImg(this.src)" alt="img"&amp;gt;
        &amp;lt;!-- this.src is passed to the f() when full img is clicked --&amp;gt;
    &amp;lt;/div&amp;gt;


    &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The html code is pretty simple. All we did was created a div for holding 8 images which will be hosted on our webpage when rendered. Prior to that div, we have another div for full image, which will pop up when any small img is viewed.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*{
    margin: 0;
    padding: 0;
    font-family: sans-serif;
}

body{
    background-color: #ecf4fb;
}

.img-gallery{
    width: 80%;
    margin: 6em auto 3em; /* 16px = 1em */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15em, 1fr));
    grid-gap: 2em;
}

.img-gallery img{
    width: 100%;
    cursor: pointer;
    transition: 0.4s;
}

.img-gallery img:hover{
    transform: scale(0.8) rotate(-15deg); 
    border-radius: 20px;
    box-shadow: 0 32px 75px rgba(68, 77, 136, 0.2); 
}

.full-img{
    width: 100%;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.9);
    position: fixed;
    top: 0;
    left: 0;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 100; 
}

.full-img img{
    width: 90%;
    max-width: 30em;
}

.full-img span{
    position: absolute;
    top: 5%;
    right: 5%;
    font-size: 30px;
    color: #fff;
    cursor: pointer;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believe that the styles I've used here is self-explanatory so I'm gonna go to the script part now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Script.js
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var fullImgBox = document.getElementById('fullImgBox')
var fullImg = document.getElementById('fullImg')

function openFullImg (pic) {
    fullImgBox.style.display = "flex";
    fullImg.src = pic;
}

function closeFullImg() {
    fullImgBox.style.display = "none";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here comes the heart to this gallery grid. So what this script file does is, it has two functions in it, as you can see ofcourse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;openFullImg&lt;/strong&gt; triggers the clicked image to scale up with the respective styles applied. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;closeFullImg&lt;/strong&gt; when triggered hides the full image by simply mainpulating the display attribute set to none.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/gallery-grid"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="http://gallery-grid-lilac.vercel.app/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for the day my fellow developer. The next time I'll be coming up with real-time webapp where this gallery grid is gonna be customisable to everyone. You can render your own images online! Till then, bye-bye!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>hustle</category>
    </item>
    <item>
      <title>Hoverboard</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Sun, 04 Sep 2022 15:29:27 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/hoverboard-1j08</link>
      <guid>https://dev.to/jagadeeshkj/hoverboard-1j08</guid>
      <description>&lt;p&gt;Hello there! How're you doing? Hope you're well and sound.&lt;/p&gt;

&lt;p&gt;This is just an article on a side-project which I'd made with &lt;a class="mentioned-user" href="https://dev.to/traversymedia"&gt;@traversymedia&lt;/a&gt; tutorial. That guy is just awesome in making cool projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ctl9XL0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74eve0j8yx1s86qhci8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ctl9XL0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74eve0j8yx1s86qhci8p.png" alt="Sample" width="880" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kq9zKhml--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7am8gopzfxnnpw1hmn7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kq9zKhml--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7am8gopzfxnnpw1hmn7.png" alt="Hi'ya" width="880" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Start Building!
&lt;/h2&gt;

&lt;p&gt;We'll start with a new folder named Hoverboard (anything you wish) and will add index.html, style.css and script.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Html :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
    &amp;lt;link rel="icon" href="https://designshack.net/wp-content/uploads/hover-effects.png"&amp;gt;
    &amp;lt;title&amp;gt;Hoverboard&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class="container" id = "container"&amp;gt;
        &amp;lt;!-- Squares are inserted by JS --&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll try to keep it short and brief as it doesn't demand it. Here's the thing, we created a container and gave it an id with the same class name in a div.&lt;/p&gt;

&lt;p&gt;Inside the container, we'll generate some cool square boxes with the help of script.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JS :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const container = document.getElementById('container');
const colors = ['#e74c3c', '#8e44ad', '#3498db', '#e67e22', '#2ecc71'];
const SQUARES = 500;
for(let i = 0; i &amp;lt; SQUARES; i++) {
    const square = document.createElement('div');
    square.classList.add('square');

    square.addEventListener('mouseover', () =&amp;gt; setColor(square));

    square.addEventListener('mouseout', () =&amp;gt; removeColor(square));

    container.appendChild(square);
}

function setColor(element) {
    const color = getRandomColor()
    element.style.background = color
    element.style.boxShadow = `0 0 2px ${color}, 0 0 10px ${color}`
}

function removeColor(element) {
    element.style.background = '#1d1d1d';
    element.style.boxShadow = '0 0 2px #000';
}

function getRandomColor() {
    return colors[Math.floor(Math.random() * colors.length)]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty much up to it. What this code does is that it'll generate the SQUARES using an iterative loop (say upto 500 for now).&lt;/p&gt;

&lt;p&gt;We got an array of different colors for the color effect when we hover over the square boxes to make it look just awesome.&lt;/p&gt;

&lt;p&gt;Using the event listeners, we're able to make it possible and we made changes to the styles based on the actions of mouse over and out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Styles :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*{
    box-sizing: border-box;
}

body{
    background-color: #111;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}

.container{
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    max-width: 400px;
}

.square{
    background-color: #1d1d1d;
    box-shadow: 0 0 2px #000;
    height: 16px;
    width: 16px;
    margin: 2px;
    transition: 2s ease;
}

.square:hover{
    transition-duration: 0s;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The beauty of transitions is exhibited here. All we need is the power of flexbox and that's it. Box-shadow is a way to go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/Hoverboard"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="http://hoverboard-one.vercel.app/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think that's it, my fellow developer. Thank you for your time! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Digital Resume</title>
      <dc:creator>Jagadeesh Koyya</dc:creator>
      <pubDate>Tue, 30 Aug 2022 13:18:04 +0000</pubDate>
      <link>https://dev.to/jagadeeshkj/a-digital-resume-1aba</link>
      <guid>https://dev.to/jagadeeshkj/a-digital-resume-1aba</guid>
      <description>&lt;p&gt;If you have a resume in hand, let's make it fly over the web. &lt;/p&gt;

&lt;p&gt;A resume is a brief summary of personal and professional experiences, skills, and education history. Its main purpose is to show off your best self to potential. And you should carefully prepare your resume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let start building
&lt;/h2&gt;

&lt;p&gt;I've started this project by creating a folder with index.html, style.css and script.js&lt;/p&gt;

&lt;p&gt;index.html is the root file for your project. All the styling part is seperated into style.css and the script.js file handles the events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JagadeeshKJ/digital-resume"&gt;Repo ⚡&lt;/a&gt;&lt;br&gt;
&lt;a href="http://digital-resume-brown.vercel.app/"&gt;Live ⚡&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML Setup&lt;/strong&gt;&lt;br&gt;
Let's get some boiler plate HTML setup and build out everything up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
    &amp;lt;link rel="icon" href="https://st3.depositphotos.com/27847728/36434/v/950/depositphotos_364349646-stock-illustration-initial-letter-logo-design-vector.jpg?forcejpeg=true"&amp;gt;
    &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;title&amp;gt;Jagadeesh Koyya&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

    &amp;lt;!-- Button --&amp;gt;
    &amp;lt;input type="checkbox" id="checkbox" onclick="myFunction()"&amp;gt;

    &amp;lt;div id="container"&amp;gt;

        &amp;lt;section id="wrapper--hero" class="section--page"&amp;gt;
            &amp;lt;div&amp;gt;
                &amp;lt;h1 id="username"&amp;gt;Jagadeesh Koyya&amp;lt;/h1&amp;gt;
                &amp;lt;p id="bio"&amp;gt;Software developer, programmer in c and c++. Enthusiastic in full stack development. Blogger in dev, hashnode.&amp;lt;/p&amp;gt;
                &amp;lt;p id="email"&amp;gt;👉 jagadeesh10th@gmail.com&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;

        &amp;lt;section class="section--page"&amp;gt;
            &amp;lt;div id="social--links"&amp;gt;
                &amp;lt;a href="https://dev.to/jagadeeshkj" target="_blank"&amp;gt;Dev&amp;lt;/a&amp;gt;
                &amp;lt;a href="https://twitter.com/jagadeesh_kj" target="_blank"&amp;gt;Twitter&amp;lt;/a&amp;gt;
                &amp;lt;a href="https://www.linkedin.com/in/jagadeesh-kj/" target="_blank"&amp;gt;Linkedin&amp;lt;/a&amp;gt;
                &amp;lt;a href="https://github.com/JagadeeshKJ" target="_blank"&amp;gt;GitHub&amp;lt;/a&amp;gt;
                &amp;lt;a href="./assets/Jagadeesh Koyya.pdf" target="_blank"&amp;gt;Download Resume&amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;

        &amp;lt;section class="section--page"&amp;gt;
            &amp;lt;h2&amp;gt;Skills &amp;amp; Qualifications&amp;lt;/h2&amp;gt;
            &amp;lt;ul id="qualifications--list"&amp;gt;
                &amp;lt;li&amp;gt;✔️ HackerRank with 20205 Hackos in C &amp;amp; C++
                &amp;lt;/li&amp;gt;
                &amp;lt;li&amp;gt;✔️ Selected as Campus Ambassador of E-Cell, IIT Bombay (2021-22)&amp;lt;/li&amp;gt;
                &amp;lt;li&amp;gt;✔️ Experienced content writer on Dev community, Hashnode &amp;lt;/li&amp;gt;
                &amp;lt;li&amp;gt;✔️ CEFR B2 Upper Intermediate 499 EnglishScore&amp;lt;/li&amp;gt;
            &amp;lt;/ul&amp;gt;
        &amp;lt;/section&amp;gt;

        &amp;lt;section class="section--page"&amp;gt;
            &amp;lt;h2&amp;gt;Tech Stack&amp;lt;/h2&amp;gt;

            &amp;lt;div id="wrapper--techstack--items"&amp;gt;
                &amp;lt;div class="card--techstack"&amp;gt;
                    &amp;lt;span&amp;gt;Python, Javascript, Node JS&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="card--techstack"&amp;gt;
                    &amp;lt;span&amp;gt;Django, FastAPI&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="card--techstack"&amp;gt;
                    &amp;lt;span&amp;gt;React, Next JS&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;div class="card--techstack"&amp;gt;
                    &amp;lt;span&amp;gt;MangoDB, MySQL&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;

            &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;

        &amp;lt;section id = "work-history-wrapper class="section--page"&amp;gt;
            &amp;lt;h2&amp;gt;Work History&amp;lt;/h2&amp;gt;

            &amp;lt;div class="line-break"&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;div class="card--work-history"&amp;gt;
                &amp;lt;strong&amp;gt;🚧 Software Developer, Blog writter at Dev.io&amp;lt;/strong&amp;gt;
                &amp;lt;p&amp;gt;01/2021 - Present&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;Worked on building useful tools for real-time problem solving. Learning trending tech and teaching people via blog writing is helpful and enjoyable.&amp;lt;/p&amp;gt;
                &amp;lt;ul&amp;gt;
                    &amp;lt;li&amp;gt;Produced educational blog content which resulted in 300k+ views on Dev&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Produced SE campaigns and content to gain market share for related keywords.&amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="line-break"&amp;gt;&amp;lt;/div&amp;gt;

            &amp;lt;div class="card--work-history"&amp;gt;
                &amp;lt;strong&amp;gt;🚧 Campus Ambassador of E-Cell, IIT Bombay&amp;lt;/strong&amp;gt;
                &amp;lt;p&amp;gt;05/2021 - Present&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;Interacted with people of different mindsets and from various cultural backgrounds.&amp;lt;/p&amp;gt;
                &amp;lt;ul&amp;gt;
                    &amp;lt;li&amp;gt;Made regular contributions to the CA program (work from home)&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Incentives, real-time learning, entrepreneurship and more &amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="line-break"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;

        &amp;lt;!-- Projects --&amp;gt;
        &amp;lt;section class="section--page"&amp;gt;
            &amp;lt;h2&amp;gt;Projects &amp;amp; Accomplishments&amp;lt;/h2&amp;gt;

            &amp;lt;div class="card--project"&amp;gt;
                &amp;lt;a href="project1.html"&amp;gt;&amp;lt;span&amp;gt;🏆 &amp;lt;/span&amp;gt;QR Code Generator - For Any Website
                &amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="card--project"&amp;gt;
                &amp;lt;a href="project5.html"&amp;gt;&amp;lt;span&amp;gt;🏆 &amp;lt;/span&amp;gt;Password Generator - Authentic
                &amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="card--project"&amp;gt;
                &amp;lt;a href="project2.html" &amp;gt;&amp;lt;span&amp;gt;🏆 &amp;lt;/span&amp;gt;Whatsapp Anonymous Messanger&amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="card--project"&amp;gt;
                &amp;lt;a href="project3.html" &amp;gt;&amp;lt;span&amp;gt;🏆 &amp;lt;/span&amp;gt;Starbucks Clone - An art of cool work&amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

            &amp;lt;div class="card--project"&amp;gt;
                &amp;lt;a href="project4.html"&amp;gt;&amp;lt;span&amp;gt;🏆 &amp;lt;/span&amp;gt;Restaurant Website - A Working Prototype&amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;

        &amp;lt;/section&amp;gt;

    &amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've included sections for Skills, Tech Stack, Work History and Projects and wrapped all of 'em in a container.&lt;/p&gt;

&lt;p&gt;A boiler plate for a project page would be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
    &amp;lt;title&amp;gt;Jagadeesh Koyya&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id="container"&amp;gt;
        &amp;lt;a href="index.html"&amp;gt;&amp;amp;#x2190; Go Back&amp;lt;/a&amp;gt;
        &amp;lt;h1&amp;gt;Built a tool to generate QR Code for handling business websites&amp;lt;/h1&amp;gt;

        &amp;lt;ul&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;a href="https://qr-code-generator-eight.vercel.app/" target="_blank"&amp;gt;Live Demo&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;a href="https://github.com/JagadeeshKJ/QR-Code-Generator" target="_blank"&amp;gt;Source code&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
        &amp;lt;p&amp;gt;Why remember long websites when you can just click-scan-hit in one go. That's where the cool work of this tool is projected. This tool generates a QR Code for the entered website and it can be saved to access the website 24x7.&amp;lt;/p&amp;gt;

        &amp;lt;ul&amp;gt;
            &amp;lt;li&amp;gt;QR Codes are portable and comes in handy.&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;Build using qrcode.js, a library of JS.&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;QR Code comes in any size and takes little storage.&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Styling what we have so far&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url('https://fonts.googleapis.com/css2?family=Readex+Pro:wght@300;400;500;600;700&amp;amp;display=swap');

:root{
    --mainTextColor-light:#000;
    --secondaryTextColor-light:rgb(51 51 51);
    --mainLinkColor-light:#0da2b8;
    --mainBorderColor-light:rgb(218, 218, 218);
    --mainBgColor-light:rgb(249, 250,251);

    --mainTextColor-dark:#fff;
    --secondaryTextColor-dark:#adb0b1;
    --mainLinkColor-dark:rgb(30, 190,214);
    --mainBorderColor-dark:#2b3031;
    --mainBgColor-dark:#131415;

    --mainTextColor:var(--mainTextColor-light);
    --secondaryTextColor:var(--secondaryTextColor-light);
    --mainLinkColor:var(--mainLinkColor-light);
    --mainBorderColor:var(--mainBorderColor-light);
    --mainBgColor:var(--mainBgColor-light);
}

*{
    font-family: 'Readex Pro';
    line-height: 1.5em;
    box-sizing: border-box;
    color: var(--mainTextColor);
}

body{
    background-color: var(--mainBgColor);
}

p, span, li{
    color: var(--secondaryTextColor);
    font-size: 1em;
}

a{
    text-decoration: none;
    color: var(--mainLinkColor);
    font-size: 500;
}

li{
    line-height: 1.9em;
}

#container{
    max-width: 700px;
    margin: 0 auto;
}

.section--page{
    padding-top: 1em;
    padding-bottom: 1em;
}

/* Wrapper-Hero */
#wrapper--hero{
    display: flex;
    align-items: center;
    gap: 4em;
}

#username{
    font-size: 3em;
    line-height: 1em;
}

#bio, a{
    font-weight: 300;
}

/* #pic{
    border-radius: 50%;
    width: 200px;
    height: 150px;
    object-fit: cover;
} */

#email{
    color: var(--mainTextColor);
}

/* Social Media Links */
#social--links{
    display: flex;
    column-gap: 1em;
    justify-content: space-between;
    flex-wrap: wrap;
}

#social--links a{
    font-size: 0.9em;
    color: var(--secondaryTextColor);
    transition: 0.3s;
}

#social--links a:hover{
    color: var(--mainLinkColor);
}

#qualifications--list{
    list-style: none;
}

/* Tech Stack */
#wrapper--techstack--items{
    display: flex;
    gap: 1em;
    flex-wrap: wrap;
    font-size: 0.9em;
}

.card--techstack{
    border: 1px solid var(--mainBorderColor);
    border-radius: 5px;
    padding: 0.5em 1em;
}

/* Work History */
.card--work-history{
    margin: 3em 0;
    padding-left: 2em;
    border-left: 1px solid var(--mainBorderColor);
}

.line-break{
    background-color: var(--mainBorderColor);
    height: 1px;
}

/* Projects */
.card--project{
    padding: 1em 0;
    border-top: 1px solid var(--mainBorderColor);
}

.card--project a{
    color: var(--mainTextColor);
    transition: .3s;
}

.card--project a:hover{
    color: var(--mainLinkColor);
}

@media(max-width: 600px){
    #wrapper--hero{
        flex-direction: column;
        gap: 1em;
    }

    .section--page{
        padding: 1em 0;
    }

    .card--work-history{
        border-left: none;
        padding-left: 0;
    }

    #qualifications--list{
        padding: 0;
    }
}


/* Dark Mode */
.dark-mode {
    background-color: var(--mainBgColor-dark);
}

/* Styling the checkbox input */
#checkbox{
    position: absolute;
    top: 20px;
    right: 20px;
    appearance: none;
    -webkit-appearance : none;
    -moz-appearance : none;
    -o-appearance : none;
    width: 60px;
    height: 30px;
    background: black;
    border-radius: 22px;
    cursor: pointer;
    outline: none;
}
/* styling the circle inside the checkbox input */
#checkbox::before{
    content: '';
    position: absolute;
    width: 25px;
    height: 25px;
    background-color:white;
    border-radius: 35px;
    top: 2px;
    left: 2px;
    cursor: pointer;
    transition: .3s linear;
}
/* moving the checkbox circle when it's toggled by the user */
#checkbox:checked::before{
    left: 35px;
}
/* changing the color of the checkbox when it's toggled */
#checkbox:checked{
    background: rgb(12, 177, 81);
}

#checkbox:checked ~ #container{
    --mainTextColor:var(--mainTextColor-dark);
    --secondaryTextColor:var(--secondaryTextColor-dark);
    --mainLinkColor:var(--mainLinkColor-dark);
    --mainBorderColor:var(--mainBorderColor-dark);
    --mainBgColor:var(--mainBgColor-dark);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myFunction() {
    var element = document.body;
    element.classList.toggle("dark-mode");
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty much up to it. I've provided the links to live deployment and the GitHub repo where you can access the source code.🔝&lt;/p&gt;

&lt;p&gt;This project is entirely based on a tutorial I've recently come across in &lt;a class="mentioned-user" href="https://dev.to/traversymedia"&gt;@traversymedia&lt;/a&gt;. They do really make some awesome content. &lt;a class="mentioned-user" href="https://dev.to/dennisivy11"&gt;@dennisivy11&lt;/a&gt; is such a nice guy with skills. 🙌🏻&lt;/p&gt;

&lt;p&gt;An extension which I've added in my project is the dark mode feature. You can switch to light/dark mode in just one click and it's cool I guess. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
