관리자 페이지를 구현하기 위한 전체 코드(프론트엔드, 백엔드, API-재고 관리 시스템을 기반으로)
관리자는 상품 추가/수정/삭제와 주문 내역 확인이 가능해야 함.
1. 시스템 아키텍처
[React Admin Frontend] ← HTTP → [Flask Backend API] ←→ [메모리 DB]
2. 백엔드 (Python Flask)
(1) server.py 확장 (관리자 API 추가)
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
# 임시 DB (상품 & 주문 데이터)
products = {
"A": { "id": "A", "name": "상품 A", "price": 10000, "stock": 10 },
"B": { "id": "B", "name": "상품 B", "price": 20000, "stock": 5 }
}
orders = []
# ----------------------------
# 관리자 전용 API
# ----------------------------
# 1. 모든 상품 조회 (GET)
@app.route('/api/admin/products', methods=['GET'])
def get_all_products():
return jsonify(list(products.values()))
# 2. 상품 추가 (POST)
@app.route('/api/admin/products', methods=['POST'])
def add_product():
data = request.get_json()
product_id = data['id']
if product_id in products:
return jsonify({ "success": False, "error": "이미 존재하는 상품 ID" }), 400
products[product_id] = data
return jsonify({ "success": True, "product": data })
# 3. 상품 수정 (PUT)
@app.route('/api/admin/products/<product_id>', methods=['PUT'])
def update_product(product_id):
if product_id not in products:
return jsonify({ "success": False, "error": "상품 없음" }), 404
data = request.get_json()
products[product_id].update(data)
return jsonify({ "success": True, "product": products[product_id] })
# 4. 상품 삭제 (DELETE)
@app.route('/api/admin/products/<product_id>', methods=['DELETE'])
def delete_product(product_id):
if product_id not in products:
return jsonify({ "success": False, "error": "상품 없음" }), 404
del products[product_id]
return jsonify({ "success": True })
# 5. 모든 주문 내역 조회 (GET)
@app.route('/api/admin/orders', methods=['GET'])
def get_all_orders():
return jsonify(orders)
if __name__ == '__main__':
app.run(debug=True, port=5000)
3. 프론트엔드 (React)
(1) 관리자 페이지 컴포넌트 구조
src/
├── AdminProductList.js // 상품 목록 & 삭제
├── AdminAddProduct.js // 상품 추가 폼
├── AdminEditProduct.js // 상품 수정 폼
├── AdminOrderHistory.js // 주문 내역
└── App.js // 라우팅
(2) src/AdminProductList.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function AdminProductList() {
const [products, setProducts] = useState([]);
// 상품 데이터 불러오기
useEffect(() => {
axios.get('http://localhost:5000/api/admin/products')
.then(res => setProducts(res.data))
.catch(err => console.error("상품 불러오기 실패:", err));
}, []);
// 상품 삭제
const handleDelete = (productId) => {
if (window.confirm("정말 삭제하시겠습니까?")) {
axios.delete(`http://localhost:5000/api/admin/products/${productId}`)
.then(() => {
setProducts(products.filter(p => p.id !== productId));
})
.catch(err => console.error("삭제 실패:", err));
}
};
return (
<div>
<h2>상품 관리</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>이름</th>
<th>가격</th>
<th>재고</th>
<th>액션</th>
</tr>
</thead>
<tbody>
{products.map(product => (
<tr key={product.id}>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{product.price}원</td>
<td>{product.stock}</td>
<td>
<button onClick={() => handleDelete(product.id)}>삭제</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default AdminProductList;
(3) src/AdminAddProduct.js
import React, { useState } from 'react';
import axios from 'axios';
function AdminAddProduct() {
const [formData, setFormData] = useState({
id: "",
name: "",
price: 0,
stock: 0
});
const handleSubmit = (e) => {
e.preventDefault();
axios.post('http://localhost:5000/api/admin/products', formData)
.then(res => {
alert("상품 추가 성공!");
setFormData({ id: "", name: "", price: 0, stock: 0 });
})
.catch(err => alert("추가 실패: " + err.response?.data.error));
};
return (
<div>
<h2>상품 추가</h2>
<form onSubmit={handleSubmit}>
<input
placeholder="상품 ID"
value={formData.id}
onChange={(e) => setFormData({ ...formData, id: e.target.value })}
required
/>
<input
placeholder="상품명"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
required
/>
<input
type="number"
placeholder="가격"
value={formData.price}
onChange={(e) => setFormData({ ...formData, price: e.target.value })}
required
/>
<input
type="number"
placeholder="재고"
value={formData.stock}
onChange={(e) => setFormData({ ...formData, stock: e.target.value })}
required
/>
<button type="submit">추가</button>
</form>
</div>
);
}
export default AdminAddProduct;
(4) src/AdminOrderHistory.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function AdminOrderHistory() {
const [orders, setOrders] = useState([]);
useEffect(() => {
axios.get('http://localhost:5000/api/admin/orders')
.then(res => setOrders(res.data))
.catch(err => console.error("주문 불러오기 실패:", err));
}, []);
return (
<div>
<h2>주문 내역</h2>
<ul>
{orders.map((order, index) => (
<li key={index}>
{order.productId} - {order.quantity}개
</li>
))}
</ul>
</div>
);
}
export default AdminOrderHistory;
(5) src/App.js (라우팅)
import React from 'react';
import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom';
import AdminProductList from './AdminProductList';
import AdminAddProduct from './AdminAddProduct';
import AdminOrderHistory from './AdminOrderHistory';
function App() {
return (
<Router>
<div>
<nav>
<Link to="/">상품 관리</Link>
<Link to="/add">상품 추가</Link>
<Link to="/orders">주문 내역</Link>
</nav>
<Routes>
<Route path="/" element={<AdminProductList />} />
<Route path="/add" element={<AdminAddProduct />} />
<Route path="/orders" element={<AdminOrderHistory />} />
</Routes>
</div>
</Router>
);
}
export default App;
4. 실행 방법
- 백엔드 실행
python server.py # http://localhost:5000
- 프론트엔드 실행
cd frontend npm start # http://localhost:3000
5. 기능 설명
기능 | API 엔드포인트 | HTTP 메서드 |
---|---|---|
상품 전체 조회 | /api/admin/products |
GET |
상품 추가 | /api/admin/products |
POST |
상품 수정 | /api/admin/products/{id} |
PUT |
상품 삭제 | /api/admin/products/{id} |
DELETE |
주문 내역 조회 | /api/admin/orders |
GET |
6. 추가 고려 사항
- 인증/인가: JWT 토큰을 이용한 관리자 권한 검증 추가 필요
- 유효성 검사: 프론트/백엔드 모두에서 입력값 검증 강화
- 페이징: 대량 데이터 처리 시 페이지네이션 구현
- 실시간 업데이트: WebSocket을 이용한 실시간 동기화
- 데이터베이스: SQLite, MySQL 등 영구 저장소 연동
이 코드를 기반으로 관리자 페이지를 완성하고 필요에 따라 기능을 확장해보세요! 🔧
'Programming' 카테고리의 다른 글
Flask : Python으로 웹서버를 만들기 위한 마이크로 프레임워크 (0) | 2025.02.18 |
---|---|
풀스택 프레임워크 Vs 마이크로 프레임워크 비교 (1) | 2025.02.17 |
쇼핑몰 재고관리에 쓰이는 코드 모음 (0) | 2025.02.15 |
API(Application Programming Interface)의 원리 (0) | 2025.02.14 |