티스토리 뷰

반응형

📌 NestJS + Prisma + Next.js로 만드는 웹 애플리케이션 첫걸음 - 애자일 쇼핑몰 프로젝트 - 관리자 페이지 개발 (상품 관리, 주문 관리)

1. 관리자 페이지의 필요성

쇼핑몰 운영에는 상품 관리, 주문 처리, 사용자 관리 등의 기능이 필요합니다.
이를 위해 관리자가 상품을 추가/수정/삭제하고, 주문을 처리할 수 있는 관리자 페이지를 구축해야 합니다.

관리자 페이지에서 제공할 주요 기능:

  • 상품 관리: 상품 등록, 수정, 삭제
  • 주문 관리: 주문 상태 변경 (처리 중 → 배송 중 → 배송 완료)
  • 사용자 관리: 사용자 목록 및 계정 관리 (선택적)

💡 이 챕터에서는 Next.js로 관리자 페이지를 구축하고, NestJS API를 연동하는 방법을 다룹니다.


2. 관리자 페이지 접근 권한 설정

2.1. 관리자 권한을 확인하는 미들웨어 생성

💡 관리자만 접근할 수 있도록 인증 미들웨어를 추가합니다.

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class AdminGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.user?.role === 'admin';
  }
}

이제 @UseGuards(AdminGuard)를 적용하여 관리자만 접근 가능하도록 설정할 수 있습니다.


2.2. 관리자 인증 적용

💡 관리자 페이지에 접근할 때 로그인된 사용자의 권한을 확인합니다.

import { useAuth } from '../context/AuthContext';
import { useRouter } from 'next/router';

export default function AdminPage() {
  const { user } = useAuth();
  const router = useRouter();

  if (!user || user.role !== 'admin') {
    router.push('/login');
    return <p>관리자 권한이 필요합니다.</p>;
  }

  return (
    <div>
      <h1>관리자 페이지</h1>
      <p>상품과 주문을 관리할 수 있습니다.</p>
    </div>
  );
}

이제 관리자가 아니면 관리자 페이지에 접근할 수 없습니다.


3. 상품 관리 기능 구현

3.1. 백엔드(NestJS) - 상품 API 확장

💡 상품 생성, 수정, 삭제 API 추가 (products.controller.ts)

import { Controller, Get, Post, Put, Delete, Body, Param, UseGuards } from '@nestjs/common';
import { ProductsService } from './products.service';
import { AdminGuard } from '../auth/admin.guard';

@Controller('products')
export class ProductsController {
  constructor(private readonly productsService: ProductsService) {}

  @Post()
  @UseGuards(AdminGuard)
  async createProduct(@Body() productData) {
    return this.productsService.createProduct(productData);
  }

  @Put(':id')
  @UseGuards(AdminGuard)
  async updateProduct(@Param('id') id: string, @Body() productData) {
    return this.productsService.updateProduct(+id, productData);
  }

  @Delete(':id')
  @UseGuards(AdminGuard)
  async deleteProduct(@Param('id') id: string) {
    return this.productsService.deleteProduct(+id);
  }
}

이제 관리자가 상품을 등록, 수정, 삭제할 수 있습니다.


3.2. 프론트엔드(Next.js) - 상품 관리 UI

반응형

💡 상품 목록 및 관리 (pages/admin/products.tsx)

import { useEffect, useState } from 'react';
import { api } from '../../utils/api';

export default function AdminProducts() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    api.get('/products').then((res) => setProducts(res.data));
  }, []);

  const handleDelete = async (id) => {
    await api.delete(`/products/${id}`);
    setProducts(products.filter((p) => p.id !== id));
  };

  return (
    <div>
      <h1>상품 관리</h1>
      <a href="/admin/products/new">상품 추가</a>
      {products.map((product) => (
        <div key={product.id}>
          <p>{product.name} - {product.price}원</p>
          <a href={`/admin/products/edit/${product.id}`}>수정</a>
          <button onClick={() => handleDelete(product.id)}>삭제</button>
        </div>
      ))}
    </div>
  );
}

이제 관리자가 상품을 추가, 수정, 삭제할 수 있습니다.


4. 주문 관리 기능 구현

4.1. 백엔드(NestJS) - 주문 상태 업데이트 API

💡 관리자가 주문 상태를 변경할 수 있도록 API를 추가합니다.

import { Controller, Patch, Param, Body, UseGuards } from '@nestjs/common';
import { OrdersService } from './orders.service';
import { AdminGuard } from '../auth/admin.guard';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Patch(':id')
  @UseGuards(AdminGuard)
  async updateOrderStatus(@Param('id') id: string, @Body() { status }) {
    return this.ordersService.updateOrderStatus(+id, status);
  }
}

이제 관리자가 주문 상태를 변경할 수 있습니다.


4.2. 프론트엔드(Next.js) - 주문 관리 UI

💡 관리자 주문 관리 페이지 (pages/admin/orders.tsx)

import { useEffect, useState } from 'react';
import { api } from '../../utils/api';

export default function AdminOrders() {
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    api.get('/orders').then((res) => setOrders(res.data));
  }, []);

  const updateOrderStatus = async (id, status) => {
    await api.patch(`/orders/${id}`, { status });
    setOrders(orders.map(order => order.id === id ? { ...order, status } : order));
  };

  return (
    <div>
      <h1>주문 관리</h1>
      {orders.map((order) => (
        <div key={order.id}>
          <p>주문 번호: {order.id}</p>
          <p>총 금액: {order.totalAmount}원</p>
          <p>현재 상태: {order.status}</p>
          <button onClick={() => updateOrderStatus(order.id, 'shipped')}>배송 중</button>
          <button onClick={() => updateOrderStatus(order.id, 'delivered')}>배송 완료</button>
        </div>
      ))}
    </div>
  );
}

이제 관리자가 주문 상태를 변경할 수 있습니다.


5. 관리자 페이지 정리

관리자 권한이 있는 사용자만 접근 가능하도록 설정
상품 추가, 수정, 삭제 기능 구현
주문 목록 조회 및 상태 변경 기능 구현
관리자가 쇼핑몰 운영을 원활하게 할 수 있도록 UI 구성


🎯 마무리하며

이번 챕터에서는 관리자를 위한 쇼핑몰 운영 기능(상품 관리, 주문 관리)을 구현하는 방법을 살펴봤습니다.
다음 단계에서는 6.1. 성능 최적화 및 캐싱 전략을 다룰 예정입니다. 🚀

 

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함
반응형