Next.js application using TypeScript and Prisma. The implementation follows the MVC (Model-View-Controller) pattern.

Jun 04, 202415 mins read

pexels-suzyhazelwood-2536965.jpg

Model (Prisma Schema)
First, define the schema in your Prisma schema file (schema.prisma):

model Compare {
  id        Int      @id @default(autoincrement())
  productId Int
  userId    Int
  createdAt DateTime @default(now())
}

 

Controller
Next, create a controller function to handle the addToCompare logic. This will be located in a file like controllers/compareController.ts.

import { NextApiRequest, NextApiResponse } from 'next';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export const addToCompare = async (req: NextApiRequest, res: NextApiResponse) => {
  const { productId, userId } = req.body;

  if (!productId || !userId) {
    return res.status(400).json({ error: 'Product ID and User ID are required' });
  }

  // Fetch the compare list from the database
  const compareList = await prisma.compare.findMany({
    where: { userId },
    orderBy: { createdAt: 'asc' }
  });

  if (compareList.length >= 3) {
    // If there are already 3 items, remove the oldest one
    const oldestItem = compareList[0];
    await prisma.compare.delete({
      where: { id: oldestItem.id }
    });
  }

  // Add the new item to the compare list
  await prisma.compare.create({
    data: {
      productId,
      userId
    }
  });

  const updatedCompareList = await prisma.compare.findMany({
    where: { userId },
    orderBy: { createdAt: 'asc' }
  });

  res.status(200).json(updatedCompareList);
};

 

Route
Create a Next.js API route that uses this controller. This will be located in a file like pages/api/compare.ts.

import { NextApiRequest, NextApiResponse } from 'next';
import { addToCompare } from '../../controllers/compareController';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    await addToCompare(req, res);
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

 

View
In Next.js, views are typically handled by React components. You can create a component to display the compare list. This will be located in a file like components/CompareList.tsx.

import React, { useEffect, useState } from 'react';

interface Product {
  id: number;
  productId: number;
  userId: number;
  createdAt: string;
}

const CompareList = () => {
  const [compareList, setCompareList] = useState<Product[]>([]);

  useEffect(() => {
    // Fetch the compare list from the API
    const fetchCompareList = async () => {
      const response = await fetch('/api/compare', { method: 'GET' });
      const data = await response.json();
      setCompareList(data);
    };

    fetchCompareList();
  }, []);

  return (
    <div>
      <h2>Compare List</h2>
      <ul>
        {compareList.map((item) => (
          <li key={item.id}>{item.productId}</li>
        ))}
      </ul>
    </div>
  );
};

export default CompareList;

 

Client-Side Integration
Finally, create a function to handle adding items to the compare list and integrate it with a component, such as a product detail page.

import React from 'react';

const ProductDetail = ({ productId }) => {
  const addToCompare = async () => {
    const response = await fetch('/api/compare', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ productId, userId: 1 }) // Assume userId is 1 for this example
    });

    if (response.ok) {
      alert('Product added to compare list');
    } else {
      alert('Failed to add product to compare list');
    }
  };

  return (
    <div>
      <h1>Product Detail</h1>
      <button onClick={addToCompare}>Add to Compare</button>
    </div>
  );
};

export default ProductDetail;

 

In this setup:

The Prisma schema defines the Compare model.
The controller (addToCompare) handles the business logic of adding products to the compare list.
The API route (pages/api/compare.ts) handles HTTP requests and invokes the controller.
The view (components/CompareList.tsx) displays the compare list.
The client-side integration (ProductDetail component) allows users to add products to the compare list.
This structure follows the MVC pattern while utilizing the features of Next.js and Prisma.

Share
Newsletter

Subscribe our newsletter