+1 (252) 631 8899 +91 98212 12676

Exploring Next.js - Creating a Client Portal from Scratch

August 31, 2024

Next.js Tutorials, Client Portal Development

Sumeet Shroff
By Sumeet Shroff
Exploring Next.js - Creating a Client Portal from Scratch

Table of Contents

  1. Introduction
  2. Basics of Next.js
  3. What is a Client Portal?
  4. Planning the Client Portal
  5. Setting Up
  6. Building the Client Portal
  7. Testing
  8. Deployment
  9. Conclusion
  10. Additional Resources

Introduction

Next.js is a powerful React-based framework that has become immensely popular among developers for building server-rendered React applications. It combines the best features of client-side React with the benefits of server-side rendering (SSR), making it a versatile choice for creating modern web applications. Over the years, Next.js has evolved with numerous features, such as static site generation (SSG), incremental static regeneration (ISR), and API routes, making it a robust framework for both developers and businesses.

The goal of this blog is to provide you with a step-by-step guide on how to create a client portal using Next.js from scratch. By the end of this post, you'll have a solid understanding of Next.js and be able to build your client portal, complete with essential features like user registration, authentication, and more.


Basics of Next.js

Before we dive into building the client portal, it’s crucial to get familiar with the basics of Next.js. This section will cover the installation process, understanding the directory structure, the main components of Next.js, routing, and data fetching methods.

Installing Next.js

To start, you'll need Node.js installed on your machine. Once that’s ready, you can create a new Next.js project by running the following command:

npx create-next-app@latest my-client-portal

This command sets up a new Next.js project in a directory named my-client-portal. Once the setup is complete, navigate to this directory:

cd my-client-portal

To start the development server, use:

npm run dev

This will launch your Next.js app on http://localhost:3000.

Directory Structure

Next.js projects have a unique directory structure that you’ll quickly get accustomed to. Here’s a brief overview:

  • pages/: Contains the application's pages. Each file in this directory automatically becomes a route.
  • public/: Static files like images and fonts go here.
  • styles/: Contains global CSS and other styles.
  • components/: This is where you’ll store React components used across pages.

Main Components of Next.js

Next.js is built on React but includes several additional features:

  • Pages and Routing: Every file in the pages/ directory is treated as a route.
  • API Routes: You can create API endpoints by adding files in the pages/api directory.
  • Data Fetching: Next.js supports SSR, SSG, and CSR (Client-Side Rendering). You can fetch data using getStaticProps, getServerSideProps, and getStaticPaths.

Routing

Next.js simplifies routing. By default, routing is based on the file system. For example, pages/about.js becomes available at /about. Dynamic routing is also supported using brackets, like pages/posts/[id].js, where id is a dynamic parameter.

Data Fetching Methods

  • getStaticProps: Fetches data at build time.
  • getServerSideProps: Fetches data on every request.
  • getStaticPaths: Defines dynamic routes that are statically generated.

These basics form the foundation you'll need to create your client portal in Next.js.


What is a Client Portal?

A client portal is a secure, private website that allows clients to access and interact with their data, services, or content. Typically, businesses use client portals to provide customers with personalized access to services, documents, support, and communication channels.

Uses and Benefits

  • Personalized Experience: Clients can view information relevant to them, such as invoices, project statuses, and messages.
  • Secure Communication: Sensitive information is shared through secure, authenticated channels.
  • Document Management: Clients can upload, download, and manage documents.
  • Self-Service: Reduces the need for direct support by allowing clients to resolve common issues independently.

Essential Features

A robust client portal typically includes features such as:

  • User Registration and Authentication: Ensures that only authorized users can access the portal.
  • Profile Management: Allows users to manage their personal information.
  • Messaging System: Facilitates communication between the client and the service provider.
  • Document Sharing: Securely shares documents between the client and the service provider.
  • Notifications: Keeps users informed about updates and activities within the portal.

Understanding these features will help you structure the client portal effectively.


Planning the Client Portal

In this section, we will plan out the features that will be implemented in the client portal. Planning is crucial to ensure that we cover all necessary aspects and build a scalable and maintainable application.

Key Features to Include

  1. User Registration and Login: Users should be able to create an account and securely log in.
  2. Profile Management: After logging in, users should have the ability to manage their profiles, including changing passwords, updating personal information, etc.
  3. Messaging System: A simple messaging feature that allows users to communicate with the service provider or other clients.
  4. Document Sharing: A secure system for uploading and sharing documents.
  5. Dashboard: A central hub where users can see an overview of their activities, recent messages, and other notifications.

Designing the Architecture

When designing the client portal, it's important to consider the scalability and security of the application. The client portal will consist of the following major components:

  1. Frontend: Built using Next.js, leveraging SSR for enhanced performance.
  2. Backend: We can use Next.js API routes or integrate with a dedicated backend using Node.js or another backend service like Firebase.
  3. Database: Depending on the features, you can use a relational database like MySQL or PostgreSQL, or a NoSQL database like MongoDB.
  4. Authentication: We’ll use JWT (JSON Web Tokens) or OAuth to manage user authentication and sessions.
  5. File Storage: Services like AWS S3 can be used for document storage.

This planning stage ensures that we have a clear roadmap for building the client portal.


Setting Up

Before we start building the portal, you need to set up your development environment. This section will guide you through the process of installing necessary packages and configuring the Next.js application.

Install Necessary Packages

To begin, you’ll need a few essential packages:

  • next-auth: For authentication and session management.
  • axios: For making HTTP requests.
  • formik: For handling form submissions.
  • yup: For form validation.
  • tailwindcss: For styling the application.

You can install these packages using npm:

npm install next-auth axios formik yup tailwindcss

Setting Up Tailwind CSS

Tailwind CSS is a popular utility-first CSS framework that allows you to style your application without leaving your HTML. Here’s how to set it up in your Next.js project:

  1. Install Tailwind CSS:

    npm install tailwindcss postcss autoprefixer
    npx tailwindcss init -p
    
  2. Configure tailwind.config.js:

    Update the purge array in tailwind.config.js to include your Next.js pages and components:

    module.exports = {
      purge: [
        "./pages/**/*.{js,ts,jsx,tsx}",
        "./components/**/*.{js,ts,jsx,tsx}",
      ],
      darkMode: false, // or 'media' or 'class'
      theme: {
        extend: {},
      },
      variants: {
        extend: {},
      },
      plugins: [],
    };
    
  3. Add Tailwind to your CSS:

    In your styles/globals.css, import Tailwind CSS:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    

Configuring Next-Auth

Next, we’ll configure Next-Auth for user authentication. Create a file named [...] under pages/api/auth/[...nextauth].js:

import NextAuth from "next-auth";
import Providers from "next-auth/providers";

export default NextAuth({
  providers: [
    Providers.Credentials({
      name: "Credentials",
      authorize: async (credentials) => {
        const user = { id: 1, name: "John Doe" }; // replace with actual logic
        if (user) {
          return user;
        } else {
          return null;
        }
      },
    }),
  ],
  session: {
    jwt: true,
  },
  pages: {
    signIn: "/auth/signin",
  },
});

This code sets up Next-Auth with a credentials provider. You’ll need to replace the dummy authorize function with real authentication logic.

Setting Up the Database

Depending on your requirements, you might choose a relational or NoSQL database. For example, if using MongoDB, you can install and configure the mongodb package:

npm install mongodb

Then, set up a connection file:

import { MongoClient } from "mongodb";

let uri = process.env.MONGODB_URI;
let dbName = process.env.MONGODB_DB;

let cachedClient = null;
let cachedDb = null;

export async function connectToDatabase() {
  if (cachedClient && cachedDb) {
    return { client: cachedClient, db: cachedDb };
  }

  const client = await MongoClient.connect(uri, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  });
  const db = client.db(dbName);

  cachedClient = client;
  cachedDb = db;

  return { client, db };
}

Now your environment is set up and ready to start building the client portal.


Building the Client Portal

This section will walk you through the process of building each feature of the client portal step by step. We’ll start with the basics and gradually move to more complex features.

User Registration

To allow users to register, create a registration form. Here’s a basic example:

import { useFormik } from "formik";
import * as Yup from "yup";

export default function Register() {
  const formik = useFormik({
    initialValues: {
      username: "",
      password: "",
    },
    validationSchema: Yup.object({
      username: Yup.string().required("Username is required"),
      password: Yup.string().required("Password is required"),
    }),
    onSubmit: async (values) => {
      const response = await axios.post("/api/register", values);
      if (response.status === 200) {
        // Handle successful registration
      }
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <div>
        <label htmlFor="username">Username</label>
        <input
          id="username"
          name="username"
          type="text"
          onChange={formik.handleChange}
          value={formik.values.username}
        />
        {formik.errors.username ? <div>{formik.errors.username}</div> : null}
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          name="password"
          type="password"
          onChange={formik.handleChange}
          value={formik.values.password}
        />
        {formik.errors.password ? <div>{formik.errors.password}</div> : null}
      </div>
      <button type="submit">Register</button>
    </form>
  );
}

The useFormik hook from Formik manages form state, while Yup validates the form. The form submits data to the /api/register endpoint, where you’ll handle the registration logic.

Login System

Next, we’ll create a login system. Here’s a basic setup:

import { signIn } from "next-auth/client";

export default function Login() {
  const handleLogin = async (e) => {
    e.preventDefault();
    const res = await signIn("credentials", {
      redirect: false,
      username: e.target.username.value,
      password: e.target.password.value,
    });

    if (!res.error) {
      // Redirect or show success message
    }
  };

  return (
    <form onSubmit={handleLogin}>
      <div>
        <label htmlFor="username">Username</label>
        <input id="username" name="username" type="text" />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input id="password" name="password" type="password" />
      </div>
      <button type="submit">Login</button>
    </form>
  );
}

This form uses Next-Auth’s signIn function to authenticate the user.

Profile Management

For profile management, create a profile page where users can update their information:

import { useSession } from "next-auth/client";

export default function Profile() {
  const [session] = useSession();

  if (!session) {
    return <p>You must be logged in to view this page</p>;
  }

  return (
    <div>
      <h1>Profile</h1>
      <p>Name: {session.user.name}</p>
      <p>Email: {session.user.email}</p>
      {/* Add form to update profile details */}
    </div>
  );
}

This example shows how to display user information using Next-Auth’s useSession hook.

Messaging Feature

To implement messaging, you’ll need to create a database schema to store messages and an API route to handle sending and retrieving messages.

API Route:

import { connectToDatabase } from "../../utils/mongodb";

export default async function handler(req, res) {
  const { db } = await connectToDatabase();

  if (req.method === "POST") {
    const { sender, recipient, message } = req.body;
    const result = await db
      .collection("messages")
      .insertOne({ sender, recipient, message, createdAt: new Date() });
    res.json(result);
  } else if (req.method === "GET") {
    const messages = await db.collection("messages").find().toArray();
    res.json(messages);
  }
}

Messaging UI:

export default function Messaging() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    async function fetchMessages() {
      const res = await axios.get("/api/messages");
      setMessages(res.data);
    }
    fetchMessages();
  }, []);

  const sendMessage = async (e) => {
    e.preventDefault();
    const message = e.target.message.value;
    await axios.post("/api/messages", {
      sender: "User1",
      recipient: "User2",
      message,
    });
    e.target.reset();
  };

  return (
    <div>
      <h1>Messages</h1>
      <form onSubmit={sendMessage}>
        <input name="message" placeholder="Type your message" />
        <button type="submit">Send</button>
      </form>
      <ul>
        {messages.map((msg, index) => (
          <li key={index}>
            {msg.sender}: {msg.message}
          </li>
        ))}
      </ul>
    </div>
  );
}

Document Sharing

For document sharing, integrate with a service like AWS S3. Here’s a basic setup:

  1. Install AWS SDK:

    npm install aws-sdk
    
  2. API Route:

    import AWS from "aws-sdk";
    
    AWS.config.update({
      accessKeyId: process.env.AWS_ACCESS_KEY,
      secretAccessKey: process.env.AWS_SECRET_KEY,
    });
    
    const s3 = new AWS.S3();
    
    export default async function handler(req, res) {
      if (req.method === "POST") {
        const { file } = req.body;
        const params = {
          Bucket: process.env.S3_BUCKET_NAME,
          Key: `${Date.now()}_${file.name}`,
          Body: file,
          ContentType: file.type,
        };
    
        s3.upload(params, (err, data) => {
          if (err) {
            res.status(500).json({ error: err.message });
          } else {
            res.status(200).json({ url: data.Location });
          }
        });
      }
    }
    
  3. Document Upload Form:

    export default function DocumentUpload() {
      const uploadDocument = async (e) => {
        e.preventDefault();
        const formData = new FormData();
        formData.append("file", e.target.file.files[0]);
        await axios.post("/api/upload", formData);
      };
    
      return (
        <form onSubmit={uploadDocument}>
          <input type="file" name="file" />
          <button type="submit">Upload</button>
        </form>
      );
    }
    

This will allow users to upload files to AWS S3 and share them securely.


Testing

Testing is crucial to ensure that your client portal functions correctly. Here’s how to test each feature:

Unit Testing

Use a testing framework like Jest to write unit tests for your components and API routes.

npm install jest @testing-library/react @testing-library/jest-dom

Create a test file for your component, e.g., Login.test.js:

import { render, screen } from "@testing-library/react";
import Login from "./Login";

test("renders login form", () => {
  render(<Login />);
  expect(screen.getByText(/Login/)).toBeInTheDocument();
});

Integration Testing

Integration testing ensures that different parts of your application work together as expected. You can use a tool like Cypress:

npm install cypress

Write integration tests to simulate

user interactions across different parts of the portal.

End-to-End Testing

End-to-end testing checks the entire application flow from start to finish. Cypress can also be used for this purpose. Write tests that simulate real user scenarios, such as registering, logging in, sending messages, and uploading documents.


Deployment

Once the client portal is built and tested, it’s time to deploy it. Next.js offers several deployment options:

Vercel

Vercel is the official platform for Next.js, providing seamless deployment:

  1. Push your project to GitHub.
  2. Sign up for Vercel and link your GitHub account.
  3. Import your project and deploy.

Netlify

Netlify also supports Next.js:

  1. Push your project to GitHub.
  2. Sign up for Netlify and link your GitHub account.
  3. Import your project, set the build command to next build, and deploy.

Self-Hosting

You can also deploy your Next.js app on your own server. Here’s a basic setup using Node.js:

  1. Build your application:

    npm run build
    
  2. Start the server:

    npm start
    
  3. Configure your server (e.g., Nginx) to proxy requests to the Node.js process.

Each method has its pros and cons, so choose the one that best fits your needs.


Conclusion

We’ve covered a lot of ground in this guide, from introducing Next.js and its basics to planning, building, testing, and deploying a client portal. By following the steps outlined in this blog, you should have a working client portal that you can customize further according to your specific needs. The key takeaway is that Next.js provides a robust foundation for building modern web applications with ease, and with a bit of planning and coding, you can create a client portal that meets the needs of your business.


Additional Resources

To further expand your knowledge and skills, here are some additional resources:

These resources will help you deepen your understanding and take your Next.js projects to the next level.


About Prateeksha Web Design

Prateeksha Web Design Company is a leading digital solution provider specializing in website designs, development, and digital marketing. Recently, they have incorporated Next.js into their services, using it to create client portals from scratch. This service allows for improved user-interface and a highly optimized, server-rendered React application, ensuring a seamless experience for the user.

Prateeksha Web Design can guide you through Next.js, assisting in the creation of a customized client portal from scratch. If you have any questions or concerns, please feel free to get in touch with us.

Interested in learning more? Contact us today.

Sumeet Shroff

Sumeet Shroff

Sumeet Shroff, a distinguished author and expert in the field of next js client portal, is renowned for his insightful exploration of creating a client portal from scratch using Next.js.
Loading...

Get 20% off on your first order

Get Started Now