Creating Register Page with Reactjs Linktree Project 3

Creating Login page and integrating Backend | LinkTree Project

This tutorial is a part of the Series ‘Complete FullStack LinkTree Project with MERN (opens in a new tab)‘. This Project covers beginner to Intermediate level implementation of MongoDB, Express, ReactJS, NodeJS, and NextJS.

Project Walkthrough

Users can signup on the LinkTree website and start creating their LinkTree right away. They get a user profile editing page, edit or customize links page, a Dashboard to edit and track the links, and many more.

I’ve created a YouTube series on this Project in 6 parts. This Code snippet is from the 3rd part where we have created a Register page.

Frontend

import React, { useState } from "react";
import styles from "../styles/apply.module.css";
import Footer from "../components/Footer";
import { toast } from "react-toastify";
import Link from "next/link";
import { useRouter } from "next/router";
 
const Apply = () => {
  const router = useRouter();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
 
  const handleLogin = (e) => {
    e.preventDefault();
    // backend here
    fetch("http://localhost:8080/api/login", {
      method: "POST",
      headers: {
        "content-type": "application/json"
      },
      body: JSON.stringify({
        email,
        password
      })
    })
      .then((res) => res.json())
      .then((data) => {
        if (data.status === "success") {
          toast("You are Logged in");
          localStorage.setItem("LinkTreeToken", data.token);
          router.push("/dashboard");
        }
        if (data.status === "not found") {
          toast.error("User not found");
        }
      })
      .catch((err) => {
        console.log(err);
      });
  };
  return (
    <>
      <section
        className={
          styles.background + " min-h-screen flex justify-center items-center"
        }
      >
        <div className="main">
          <div className="content bg-white border-2 px-4 py-8 rounded-2xl shadow-lg">
            <h1 className="text-2xl font-bold text-center">
              You're now among top creators
            </h1>
            <p className="text-center">Access your Dashboard</p>
            <p className="text-center py-5 font-bold text-gray-500">
              Start building your Hub
            </p>
            <form
              onSubmit={handleLogin}
              className="flex flex-col gap-4 text-lg mt-5"
            >
              <span className="flex flex-row shadow-md border-2 px-3 py-2 rounded-md focus:outline-none">
                <img className="w-6 mr-2" src="/svg/email.svg" alt="" />
                <input
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  className="focus:outline-none"
                  type="email"
                  placeholder="Enter your email"
                  required
                />
              </span>
              <input
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className="shadow-md border-2 px-3 py-2 rounded-md focus:outline-none"
                type="password"
                placeholder="Set a password"
                required
              />
              <input
                className="bg-indigo-600 text-white py-2 rounded-lg cursor-pointer"
                type="submit"
                value="Login"
              />
            </form>
          </div>
          <h4 className="text-center text-white pt-3">
            New Here?{" "}
            <Link className="font-bold text-red-400" href="/apply">
              Apply
            </Link>
          </h4>
        </div>
      </section>
      <Footer />
    </>
  );
};
 
export default Apply;

Backend

import React, { useState } from "react";
import styles from "../styles/apply.module.css";
import Footer from "../components/Footer";
import { toast } from "react-toastify";
import Link from "next/link";
import { useRouter } from "next/router";
 
const Apply = () => {
  const router = useRouter();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
 
  const handleLogin = (e) => {
    e.preventDefault();
    // backend here
    fetch("http://localhost:8080/api/login", {
      method: "POST",
      headers: {
        "content-type": "application/json"
      },
      body: JSON.stringify({
        email,
        password
      })
    })
      .then((res) => res.json())
      .then((data) => {
        if (data.status === "success") {
          toast("You are Logged in");
          localStorage.setItem("LinkTreeToken", data.token);
          router.push("/dashboard");
        }
        if (data.status === "not found") {
          toast.error("User not found");
        }
      })
      .catch((err) => {
        console.log(err);
      });
  };
  return (
    <>
      <section
        className={
          styles.background + " min-h-screen flex justify-center items-center"
        }
      >
        <div className="main">
          <div className="content bg-white border-2 px-4 py-8 rounded-2xl shadow-lg">
            <h1 className="text-2xl font-bold text-center">
              You're now among top creators
            </h1>
            <p className="text-center">Access your Dashboard</p>
            <p className="text-center py-5 font-bold text-gray-500">
              Start building your Hub
            </p>
            <form
              onSubmit={handleLogin}
              className="flex flex-col gap-4 text-lg mt-5"
            >
              <span className="flex flex-row shadow-md border-2 px-3 py-2 rounded-md focus:outline-none">
                <img className="w-6 mr-2" src="/svg/email.svg" alt="" />
                <input
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  className="focus:outline-none"
                  type="email"
                  placeholder="Enter your email"
                  required
                />
              </span>
              <input
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className="shadow-md border-2 px-3 py-2 rounded-md focus:outline-none"
                type="password"
                placeholder="Set a password"
                required
              />
              <input
                className="bg-indigo-600 text-white py-2 rounded-lg cursor-pointer"
                type="submit"
                value="Login"
              />
            </form>
          </div>
          <h4 className="text-center text-white pt-3">
            New Here?{" "}
            <Link className="font-bold text-red-400" href="/apply">
              Apply
            </Link>
          </h4>
        </div>
      </section>
      <Footer />
    </>
  );
};
 
export default Apply;
// Along with registerUser, loginUser function implemented
 
const loginUser = (req, res) => {
  const { email, password } = req.body;
  try {
    const user = User.findOne({ email: email, password: password });
    console.log(user);
    if (!user) {
      return res.json({ status: "not found", error: "Invalid credentials" });
    }
    const token = jwt.sign({ email: email }, process.env.SECRET_JWT);
    return res.json({
      message: "user found",
      status: "success",
      token: token,
      id: user._id
    });
  } catch (err) {
    return res.json({ message: err.message, status: "error" });
  }
};
 
module.exports = { registerUser, loginUser };

Summing up

I hope this part of the tutorial on the Fullstack LinkTree Project was helpful to you. If you faced any problems while following the video or the source code snippets, comment below and I’ll reply as soon as possible. See you soon.

IndGeek provides solutions in the software field, and is a hub for ultimate Tech Knowledge.