상세 컨텐츠

본문 제목

Next.js와 Shadcn UI를 사용한 간단한 POS 시스템 구축

Dev Type

by ai developer 2025. 2. 3. 16:11

본문

Shadcn UI를 활용을 연습할 겸, 간단히 POS를 만드는 토이 프로젝트를 진행해 봤습니다.

POS 시스템은 주문을 관리하고, 결제를 처리하며, 재고를 관리하는 데 사용합니다.

Shadcn은 기본적으로 TailwindCSS를 활용합니다.

기본 기능을 구현해 보겠습니다.

프로젝트 설정

먼저, Next.js 프로젝트를 생성하고 필요한 패키지를 설치합니다.

npx create-next-app@latest simple-pos --typescript
cd simple-pos

 

Shadcn UI는 Tailwind CSS를 기반으로 한 컴포넌트 라이브러리입니다. Shadcn UI를 설치하기 위해 다음 명령어를 실행합니다.

npm install @shadcn/ui

기본 구조 설정

프로젝트의 기본 구조를 설정합니다. app 디렉토리 내에 page.tsx 파일을 수정하고, 기본적인 레이아웃을 구성합니다.


Shadcn UI는 Tailwind CSS를 기반으로 한 컴포넌트 라이브러리입니다. Shadcn UI를 설치하기 위해 다음 명령어를 실행합니다.

npx shadcn@latest add button

 

// src/app/page.tsx
import { Button } from "../components/ui/button";

export default function Home() {
  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Simple POS System</h1>
      <Button>Add Product</Button>
    </div>
  );
}

제품 목록 표시

POS 시스템에서 제품 목록을 표시하는 기능을 추가해보겠습니다. 제품 데이터를 관리하기 위해 data.ts 파일을 생성합니다.

// data.ts
export interface Product {
  id: number;
  name: string;
  price: number;
}

export const products: Product[] = [
  { id: 1, name: "Laptop", price: 1200 },
  { id: 2, name: "Smartphone", price: 800 },
  { id: 3, name: "Tablet", price: 600 },
];

 

이제 page.tsx 파일에서 제품 목록을 표시합니다.

// src/app/page.tsx
import { Button } from "../components/ui/button";
import {
  Card,
  CardHeader,
  CardContent,
  CardFooter,
} from "../components/ui/card";
import { products, Product } from "../data";

export default function Home() {
  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Simple POS System</h1>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        {products.map((product: Product) => (
          <Card key={product.id}>
            <CardHeader>
              <h2 className="text-xl font-semibold">{product.name}</h2>
            </CardHeader>
            <CardContent>
              <p className="text-gray-600">${product.price}</p>
            </CardContent>
            <CardFooter>
              <Button>Add to Cart</Button>
            </CardFooter>
          </Card>
        ))}
      </div>
    </div>
  );
}

장바구니 기능 추가

장바구니 기능을 추가하기 위해 상태 관리를 도입합니다. useState 훅을 사용하여 장바구니 상태를 관리합니다.

// src/app/page.tsx
"use client";
import { useState } from "react";
import { Button } from "../components/ui/button";
import {
  Card,
  CardHeader,
  CardContent,
  CardFooter,
} from "../components/ui/card";
import { products, Product } from "../data";

export default function Home() {
  const [cart, setCart] = useState<Product[]>([]);

  const addToCart = (product: Product) => {
    setCart([...cart, product]);
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Simple POS System</h1>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        {products.map((product: Product) => (
          <Card key={product.id}>
            <CardHeader>
              <h2 className="text-xl font-semibold">{product.name}</h2>
            </CardHeader>
            <CardContent>
              <p className="text-gray-600">${product.price}</p>
            </CardContent>
            <CardFooter>
              <Button onClick={() => addToCart(product)}>Add to Cart</Button>
            </CardFooter>
          </Card>
        ))}
      </div>
      <div className="mt-8">
        <h2 className="text-xl font-bold mb-4">Cart</h2>
        <ul>
          {cart.map((item: Product, index: number) => (
            <li key={index} className="mb-2">
              {item.name} - ${item.price}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

결제 기능 추가

마지막으로, 간단한 결제 기능을 추가합니다. 장바구니에 있는 제품들의 총 금액을 계산하고, 결제 버튼을 추가합니다.

// pages/index.tsx
import { useState } from 'react';
import { Button, Card, CardHeader, CardContent, CardFooter } from '@shadcn/ui';
import { products, Product } from '../data';

export default function Home() {
  const [cart, setCart] = useState<Product[]>([]);

  const addToCart = (product: Product) => {
    setCart([...cart, product]);
  };

  const totalAmount = cart.reduce((sum: number, item: Product) => sum + item.price, 0);

  const handleCheckout = () => {
    alert(`Total Amount: $${totalAmount}`);
    setCart([]);
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Simple POS System</h1>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        {products.map((product: Product) => (
          <Card key={product.id}>
            <CardHeader>
              <h2 className="text-xl font-semibold">{product.name}</h2>
            </CardHeader>
            <CardContent>
              <p className="text-gray-600">${product.price}</p>
            </CardContent>
            <CardFooter>
              <Button onClick={() => addToCart(product)}>Add to Cart</Button>
            </CardFooter>
          </Card>
        ))}
      </div>
      <div className="mt-8">
        <h2 className="text-xl font-bold mb-4">Cart</h2>
        <ul>
          {cart.map((item: Product, index: number) => (
            <li key={index} className="mb-2">
              {item.name} - ${item.price}
            </li>
          ))}
        </ul>
        <p className="text-xl font-bold mt-4">Total: ${totalAmount}</p>
        <Button className="mt-4" onClick={handleCheckout}>
          Checkout
        </Button>
      </div>
    </div>
  );
}

결론

Next.js와 Shadcn UI를 사용하여 간단한 POS 시스템을 구축하는 방법을 알아보았습니다. 제품 목록을 표시하고, 장바구니에 제품을 추가하며, 결제를 처리하는 기본적인 기능을 구현했습니다. 이 프로젝트를 확장하여 더 많은 기능을 추가할 수 있습니다. 예를 들어, 재고 관리, 사용자 인증, 주문 내역 조회 등을 추가할 수 있습니다.

 

도움이 되셨기를 바랍니다. 추가 질문이나 피드백이 있다면 댓글로 남겨주세요. 감사합니다!

 

https://github.com/hanhyeonkyu/simple-pos

 

GitHub - hanhyeonkyu/simple-pos

Contribute to hanhyeonkyu/simple-pos development by creating an account on GitHub.

github.com

 

300x250

관련글 더보기

댓글 영역