Commit c7253d41 authored by 박상호's avatar 박상호 🎼
Browse files

Merge remote-tracking branch 'origin/ourMaster' into sangho

parents db86a0b7 02b3814f
......@@ -10,6 +10,7 @@ import Admin from './Pages/Admin';
import ProductRegist from './Pages/ProductRegist';
import ShoppingCart from './Pages/ShoppingCart';
import Payment from './Pages/Payment';
import PaymentCompleted from './Pages/PaymentCompleted';
import Account from './Pages/Account';
import MainNav from './Components/MainNav';
import SubNav from './Components/SubNav';
......@@ -39,6 +40,9 @@ function App() {
<PrivateRoute path="/payment">
<Payment />
</PrivateRoute>
<PrivateRoute path="/paymentcompleted">
<PaymentCompleted />
</PrivateRoute>
<PrivateRoute path="/account">
<Account />
</PrivateRoute>
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { isAdmin } from '../utils/auth';
function PrivateRoute({path, children}) {
function PrivateRoute({ path, children }) {
if (isAdmin()) {
return (
<Route path={path}>
......@@ -10,7 +10,7 @@ function PrivateRoute({path, children}) {
</Route>
)
} else {
alert('한이 없습니다. 죄송합니다.');
alert('한이 없습니다. 죄송합니다.');
return (
<Redirect to='/' />
)
......
import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom';
import axios from 'axios';
import catchError from '../utils/catchErrors';
import { Card, Button } from 'react-bootstrap';
function AllCard({ id, name, price, main_img }) {
const [success, setSuccess] = useState(false)
const [error, setError] = useState('')
const cardRef = useRef(null)
async function handleDelete() {
const pro_id = cardRef.current.id
try {
setError('')
const response = await axios.delete(`/api/product/delete?pro_id=${pro_id}`)
alert('해당 상품을 성공적으로 삭제하였습니다.')
setSuccess(true)
} catch (error) {
catchError(error, setError)
setSuccess(false)
}
}
if (success) {
return <Redirect to="/admin" />
}
return (
<Card id={id} ref={cardRef} className="m-3" style={{ width: "18rem" }}>
<Card.Img variant="top" src={main_img && `/images/${main_img}`} style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</Card.Title>
<Card.Text>{price} </Card.Text>
<Button className="float-right" onClick={handleDelete}>삭제</Button>
</Card.Body>
</Card>
)
}
export default AllCard
\ No newline at end of file
......@@ -2,38 +2,36 @@ import React from 'react'
import { Card, Row, Col } from 'react-bootstrap';
function CartCard(props) {
console.log(props)
return (
<>
{props.cart.map((e) => (
<Card>
<Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteCart} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>가격: {e.productId.price}</Card.Text>
<Card.Text>옵션: {e.size}/{e.color}</Card.Text>
<Card.Text>수량</Card.Text>
<div>
<input type="image" name={String(e._id)} alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={props.minusNum} />
<input type="number" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
<input type="image" name={String(e._id)} alt="플러스" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={props.plusNum} />
</div>
</Card.Body>
</Col>
</Row>
</Card>
))
<Card>
<Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteCart} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text className="mb-0">가격: {e.productId.price}</Card.Text>
<Card.Text className="mb-0">옵션: {e.size}/{e.color}</Card.Text>
<Card.Text >수량</Card.Text>
<div>
<input type="image" name={String(e._id)} alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={props.minusNum} />
<input type="number" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
<input type="image" name={String(e._id)} alt="플러스" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={props.plusNum} />
</div>
</Card.Body>
</Col>
</Row>
</Card>
))
}
</>
)
}
......
import React, { useState, useEffect, useRef } from 'react';
import { Card, Button } from 'react-bootstrap';
import React from 'react';
import { Card } from 'react-bootstrap';
function ListCard({ id, name, price, main_img }) {
function handleDelete(e) {
const card = e.target.parentNode.parentNode
alert('해당 상품을 성공적으로 삭제하였습니다.')
card.remove()
}
return (
<Card id={id} className="m-3" style={{ width: "18rem" }}>
<Card.Img variant="top" src={main_img && `/images/${main_img}`} style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</Card.Title>
<Card.Text>{price} </Card.Text>
{/* <Button className="float-right" onClick={handleDelete}>삭제</Button> */}
</Card.Body>
</Card>
)
......
......@@ -21,7 +21,7 @@ function MainNav() {
<img alt="카트" src="/icon/cart.svg" width="30" height="30" />
</Nav.Link>
</>
: (
: (
<>
<Nav.Link className="text-light" href='/login'>Login</Nav.Link>
<Nav.Link className="text-light" href='/signup'>Sign Up</Nav.Link>
......
import React from 'react'
import { Card, Col, Row } from 'react-bootstrap'
function OrderCard(props) {
return (
<Card >
<Card.Title className="font-weight-bold mt-4 text-center"> 주문 현황</Card.Title>
{
props.ordered.map((e) => (
<Card.Body className='m-1'>
{e.products.length > 1 ?
<Card.Header className="font-weight-bold mb-3 text-center" style={{ background: '#F7F3F3' }}>
{e.products[0].productId.pro_name} {e.products.length - 1}
</Card.Header>
: (
<Card.Header className="font-weight-bold mb-3 text-center" style={{ background: '#F7F3F3' }}>
{e.products[0].productId.pro_name}
</Card.Header>)}
<Col>
<Row>
<Card.Text> 주문번호 : <strong>{e._id}</strong> </Card.Text>
</Row>
<Row>
<Card.Text> 결제금액 : <strong>{e.total}</strong> </Card.Text>
</Row>
<Row>
<Card.Text> 배송지 : <strong> {e.receiverInfo.address} - {e.receiverInfo.address2}</strong> </Card.Text>
</Row>
<Row>
<Card.Text> 주문날짜 : <strong> {e.createdAt.substring(0, 10)}</strong> </Card.Text>
</Row>
</Col>
</Card.Body>
)
)
}
</Card>
)
}
export default OrderCard
import { Pagination } from "react-bootstrap";
import React from 'react';
import { Pagination } from 'react-bootstrap';
function pagination() {
let active = 1;
let items = [];
for (let number = 1; number <= 5; number++) {
items.push(
<Pagination.Item key={number} active={number === active}>
{number}
</Pagination.Item>,
);
}
function Paginations({ index, totalPages, handlePage }) {
return (
<Pagination className="justify-content-center">{items}</Pagination>
<Pagination className="d-flex justify-content-center">
<style type="text/css">
{`
.page-link, .page-link:hover {
color: #91877F;
margin: 0;
border: 0;
}
.page-link:focus {
box-shadow: 0 0 0 0;
}
.page-item.active .page-link {
background-color: #CDC5C2;
border-color: #CDC5C2;
color: #fff;
}
`}
</style>
<Pagination.First onClick={() => handlePage(1)} />
{index === 1 ? <Pagination.Prev onClick={()=>handlePage(index)} /> : <Pagination.Prev onClick={()=>handlePage(index - 1)} />}
{index === totalPages && index > 4 ? <Pagination.Item onClick={()=>handlePage(index - 4)}>{index - 4}</Pagination.Item> : ""}
{index > 3 && index >= totalPages-1 ? <Pagination.Item onClick={()=>handlePage(index - 3)}>{index - 3}</Pagination.Item> : ""}
{index < 3 ? "" : <Pagination.Item onClick={()=>handlePage(index - 2)}>{index - 2}</Pagination.Item>}
{index === 1 ? "" : <Pagination.Item onClick={()=>handlePage(index - 1)}>{index - 1}</Pagination.Item>}
<Pagination.Item active>{index}</Pagination.Item>
{index === totalPages ? "" : <Pagination.Item onClick={()=>handlePage(index + 1)}>{index + 1}</Pagination.Item>}
{index > totalPages-2 ? "" : <Pagination.Item onClick={()=>handlePage(index + 2)}>{index + 2}</Pagination.Item>}
{index < totalPages-3 && index >= 1 ? <Pagination.Item onClick={()=>handlePage(index + 3)}>{index + 3}</Pagination.Item> : ""}
{index < totalPages-4 && index >= 1 ? <Pagination.Item onClick={()=>handlePage(index + 4)}>{index + 4}</Pagination.Item> : ""}
{index === totalPages ? <Pagination.Next onClick={()=>handlePage(index)} /> : <Pagination.Next onClick={()=>handlePage(index + 1)} />}
<Pagination.Last onClick={() =>handlePage(totalPages)} />
</Pagination>
)
}
export default pagination
\ No newline at end of file
export default Paginations
\ No newline at end of file
......@@ -6,22 +6,23 @@ function PaymentCard(props) {
return (
<>
{props.cart.map((e) => (
<Card>
<Row className="mx-1">
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>가격: {e.productId.price}</Card.Text>
<Card.Text>옵션: {e.size}/{e.color}</Card.Text>
<Card.Text>수량: {e.count}</Card.Text>
</Card.Body>
</Col>
</Row>
</Card>
))
<Card>
<Row className="mx-1">
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteOrder} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>가격: {e.productId.price}</Card.Text>
<Card.Text>옵션: {e.size}/{e.color}</Card.Text>
<Card.Text>수량: {e.count}</Card.Text>
</Card.Body>
</Col>
</Row>
</Card>
))
}
</>
)
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { isAuthenticated } from '../utils/auth';
function PrivateRoute({path, children}) {
function PrivateRoute({ path, children }) {
if (isAuthenticated()) {
return (
<Route path={path}>
......
......@@ -15,8 +15,7 @@ function SubNav() {
Object.keys(response.data[0]).forEach((ele) => {
const url = ele.toLowerCase()
list.push(
<Nav.Link href={`/categories/${url}`}>{ele}
</Nav.Link>
<Nav.Link href={`/categories/${url}`}>{ele}</Nav.Link>
)
})
setCategoriesDiv(list)
......
import React, { useEffect, useState } from 'react'
import { Card, Image, Container, Row, Col, Button, Form, Modal } from 'react-bootstrap'
import React, { useEffect, useState } from 'react';
import { Card, Image, Container, Row, Col, Button, Form, Modal } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import axios from 'axios';
import catchError from '../utils/catchErrors';
import { isAuthenticated } from '../utils/auth';
import OrderCard from '../Components/OrderCard';
const INIT_ACCOUNT = {
name: "",
......@@ -16,46 +17,37 @@ function Account() {
const [proshow, setProshow] = useState(false)
const [error, setError] = useState("")
const userId = isAuthenticated()
const [ordered, setOrdered] = useState('')
const [ordered, setOrdered] = useState([])
async function getUsername(user) {
// console.log("tlg")
try {
const response = await axios.get(`/api/users/account/${user}`)
setAccount(response.data)
console.log('555555555', response.data);
} catch (error) {
catchError(error, setError)
// console.log('error2222', error)
}
}
useEffect(() => {
getUsername(userId)
getOrdered(userId)
getOrdered()
}, [userId])
const handleChange = (event) => {
const { name, value, files } = event.target
if (files) {
for (const file of files) {
// console.log("name=", name, "value=", value, 'file=', file);
}
setAccount({ ...account, [name]: files })
} else {
console.log("name=", name, "value=", value);
setAccount({ ...account, [name]: value })
}
}
const handleBasic = async (event) => {
const handleBasic = async () => {
const formData = new FormData()
formData.append('avatar', '')
try {
if (userId) {
const response = await axios.put(`/api/users/account/${userId}`, formData)
console.log(response.data)
window.location.reload()
}
} catch (error) {
......@@ -73,7 +65,6 @@ function Account() {
try {
if (userId) {
const response = await axios.put(`/api/users/account/${userId}`, formData)
console.log(response.data)
window.location.reload()
}
} catch (error) {
......@@ -84,18 +75,20 @@ function Account() {
}
}
async function getOrdered({}) {
console.log("object")
async function getOrdered({ }) {
try {
const response = await axios.get(`/api/users/addorder`)
setOrdered(response.data)
console.log('@@@@', response.data);
const response = await axios.post(`/api/users/addorder`, {
userId: userId
})
const a = response.data
setOrdered(a)
console.log("what=", response.data)
} catch (error) {
catchError(error, setError)
}
}
return (
<Container className="px-3">
<style type="text/css">
......@@ -131,7 +124,6 @@ function Account() {
<Col className="px-0">
<Button variant="outline-secondary" onClick={handleBasic}
className="d-flex justify-content-start"><small>기본이미지로</small></Button>
{/* 기본이미지로 보내기 */}
</Col>
<Button variant="secondary" onClick={() => setShow(false)}>취소</Button>
<Button variant="primary" type="submit" onClick={() => setShow(false)}>저장</Button>
......@@ -147,7 +139,6 @@ function Account() {
{account.name}
</strong>
<Modal
size="sm"
show={proshow}
onHide={() => setProshow(false)}>
......@@ -185,12 +176,13 @@ function Account() {
<a href="mailto:shoppingmall_KU@korea.ac.kr">
<small title="메일보내기"> * 문의 : shoppingmall_KU@korea.ac.kr </small>
</a>
{/* 쇼핑몰 문의 메일보내기 */}
</Row>
</Col>
</Row>
</Card>
<Card>
<OrderCard ordered={ordered} />
</Card>
</Container >
)
}
......
import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom';
import ListCard from '../Components/ListCard';
import Pagination from '../Components/Pagination';
import AllCard from '../Components/AllCard';
import Pagination from "../Components/Pagination";
import axios from 'axios';
import { isAdmin } from "../utils/auth";
import catchError from '../utils/catchErrors';
import { Row, Form, FormControl, Button, Card, Container } from 'react-bootstrap';
import { Row, Form, FormControl, Button, Container } from 'react-bootstrap';
function Admin() {
const INIT_STATUS = { indexOfFirst: 0, indexOfLast: 10 }
const [search, setSearch] = useState({ word: '' })
const [productlist, setProductlist] = useState([])
const [status, setStatus] = useState(INIT_STATUS)
const [currentPage, setCurrentPage] = useState(1)
const [error, setError] = useState('')
const role = isAdmin()
const searchref = useRef(null)
const per = 10;
useEffect(() => {
getProductlist()
}, [])
useEffect(() => {
setStatus({ indexOfFirst: (currentPage - 1) * per, indexOfLast: currentPage * per })
}, [currentPage])
function currentPosts(items) {
let currentPosts = 0;
currentPosts = items.slice(status.indexOfFirst, status.indexOfLast);
return currentPosts
}
async function getProductlist() {
try {
setError('')
const response = await axios.get(`/api/product/getproduct/all`)
console.log("response.data=", response.data)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
}
}
function handleSearch() {
function handleChange(event) {
setSearch({ word: event.target.value })
}
function handleSubmit(e) {
async function handleSubmit(e) {
e.preventDefault()
try {
setError('')
const response = await axios.get(`/api/product/getproduct/all?product=${search.word}`)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
} finally {
searchref.current.value = ''
}
}
if(!role) {
alert('죄송합니다.접근 권한이 없습니다.')
return <Redirect to="/" />
if (error) {
alert(`${error}`)
setError('')
searchref.current.value = ''
}
return (
......@@ -47,26 +72,34 @@ function Admin() {
background-color: #CDC5C2;
border-color: #CDC5C2;
}
.btn:hover, .btn:active, .btn:focus {
.btn:hover {
background-color: #91877F;
border-color: #91877F;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #91877F;
border-color: #91877F;
box-shadow: 0 0 0 0;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .show>.btn-primary.dropdown-toggle {
background-color: #91877F;
border-color: #91877F;
}
`}
</style>
<Row as={Form} onSubmit={handleSubmit} className="justify-content-end mx-0 my-5">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<FormControl ref={searchref} type="text" onChange={handleChange} placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="px-2">
<img src="icon/search.svg" width="20" height="20" />
</Button>
<Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button>
</Row>
<Row className="justify-content-center m-5">
{productlist.map(pro => (
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
{currentPosts(productlist).map(pro => (
<AllCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
))}
</Row>
<Pagination />
<Pagination index={currentPage} totalPages={Math.ceil(productlist.length / per)} handlePage={setCurrentPage} />
</Container>
)
}
......
......@@ -21,7 +21,6 @@ function Home() {
async function getProductlist() {
try {
const response = await axios.get(`/api/product/getproduct`)
console.log("res=", response.data)
setProductlist({ bestProduct: response.data.bestProduct, newProduct: response.data.newProduct })
} catch (error) {
catchError(error, setError)
......
......@@ -10,9 +10,7 @@ const INIT_USER = {
id: '',
password: ''
}
function Login() {
const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('')
......@@ -33,7 +31,7 @@ function Login() {
setValidated(true);
try {
setError('')
const response=await axios.post('/api/auth/login', user)
const response = await axios.post('/api/auth/login', user)
handleLogin(response.data)
setSuccess(true)
} catch (error) {
......@@ -43,7 +41,7 @@ function Login() {
if (success) {
alert('로그인 되었습니다.')
window.location.href='/'
window.location.href = '/'
}
return (
......@@ -72,7 +70,6 @@ function Login() {
<Form.Control.Feedback className="text-center" type="invalid"> 아이디를 입력하세요.</Form.Control.Feedback>
</Form.Row>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Row>
<Col sm={4} xs={6} as={Form.Label} for="password">비밀번호</Col>
......
import axios from 'axios';
import React, { useState, useEffect, useRef } from 'react';
import { Redirect, Link, useHistory } from 'react-router-dom';
import DaumPostcode from "react-daum-postcode";
import { Container, Card, Row, Col, Button, Form, FormGroup } from 'react-bootstrap';
import { Redirect, Link } from 'react-router-dom';
import PaymentCard from '../Components/PaymentCard';
import axios from 'axios';
import { isAuthenticated } from '../utils/auth';
import catchErrors from '../utils/catchErrors';
import { Container, Row, Col, Button, Form } from 'react-bootstrap';
function Payment({ match, location }) {
const [cart, setCart] = useState([])
const [order, setOrder] = useState({products: []})
const [order, setOrder] = useState({ products: [] })
const [userData, setUserData] = useState({})
const [error, setError] = useState()
const [paymentWay, setPaymentWay] = useState([])
// const [isAddress, setIsAddress] = useState("");
// const [isZoneCode, setIsZoneCode] = useState();
// const [isPostOpen, setIsPostOpen] = useState();
const [post, setPost] = useState([])
const [redirect, setRedirect] = useState(null)
const [address, setAddress] = useState("")
const [finalPrice, setFinalPrice] = useState(0)
const [num, setNum] = useState(0)
const [paymentWay, setPaymentWay] = useState([])
const [completeState, setCompleteState] = useState(false)
const user = isAuthenticated()
let history = useHistory();
const preCart = []
useEffect(() => {
getUser()
......@@ -39,15 +38,35 @@ function Payment({ match, location }) {
async function getUser() {
const name = localStorage.getItem('name')
const tel = localStorage.getItem('tel')
// const email = localStorage.getItem('email')
setUserData({ name: name, tel: tel })
const email = localStorage.getItem('email')
setUserData({ name: name, tel: tel, email: email })
}
async function getCart() {
try {
setError('')
const response = await axios.get(`/api/cart/showcart/${user}`)
console.log(response.data)
const preCart = response.data.filter((el) => el.checked === true)
if (preCart.length) {
setCart(preCart)
setOrder({ products: preCart })
} else {
alert("주문하실 상품이 없습니다.")
history.push("/home")
}
} catch (error) {
catchErrors(error, setError)
}
}
async function deleteOrder(e) {
try {
setError('')
const response = await axios.post('/api/cart/deletecart', {
userId: user,
cartId: e.target.name
})
const preCart = response.data.products.filter((el) => el.checked === true)
setCart(preCart)
setOrder({ products: preCart })
} catch (error) {
......@@ -57,7 +76,6 @@ function Payment({ match, location }) {
function handleReceiverInfo(e) {
const { name, value } = e.target
console.log(name, value)
setOrder({ ...order, receiverInfo: { ...order.receiverInfo, [name]: value } })
}
......@@ -77,11 +95,9 @@ function Payment({ match, location }) {
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = "";
console.log(data)
if (data.addressType === "R") {
if (data.bname !== "") {
extraAddress += data.bname;
console.log(extraAddress)
}
if (data.buildingName !== "") {
extraAddress +=
......@@ -105,9 +121,9 @@ function Payment({ match, location }) {
function handleClick() {
if (paymentWay.length !== 0) {
setCompleteState(false)
setPaymentWay([])
}
else {
} else {
const a = (
<Row className="justify-content-md-center">
<Col md={6} className="border m-5 p-5">
......@@ -137,34 +153,15 @@ function Payment({ match, location }) {
}
async function kakaopay() {
let itemNames = ""
if (cart.length > 1) {
itemNames = cart[0].productId.pro_name + '' + String(cart.length - 1) + ''
} else {
itemNames = cart[0].productId.pro_name
}
const response = await fetch('/api/kakaopay/test/single', {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
cid: 'TC0ONETIME',
partner_order_id: 'partner_order_id',
partner_user_id: user,
item_name: itemNames,
quantity: cart.length,
total_amount: finalPrice + 2500,
vat_amount: 200,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/payment',
fail_url: 'http://localhost:3000/payment',
cancel_url: 'http://localhost:3000/payment',
})
})
const data = await response.json()
console.log(data)
window.location.href = data.redirect_url
setCompleteState("kakaopay")
setPaymentWay(
<div className="text-center">
<p className=" font-weight-bold" style={{ display: 'inline' }}>'카카오페이'</p><p style={{ display: 'inline' }}>를 선택하셨습니다. </p>
<p>주문하기를 눌러 결제를 이어가주세요.</p>
</div>
)
// window.location.href = data.redirect_url
// setRedirect(data.redirect_url)
}
......@@ -175,6 +172,7 @@ function Payment({ match, location }) {
cartIds.push(el._id)
})
try {
setError('')
const response = await axios.post(`/api/order/addorder`, {
userId: user,
...order,
......@@ -187,120 +185,141 @@ function Payment({ match, location }) {
const response3 = await axios.post(`/api/product/pluspurchase`, {
products: order.products
})
console.log(response.data)
alert("주문이 완료되었습니다.")
return <Redirect to={'/account'} />
if (completeState === "kakaopay") {
let itemNames = ""
if (cart.length > 1) {
itemNames = cart[0].productId.pro_name + '' + String(cart.length - 1) + ''
} else {
itemNames = cart[0].productId.pro_name
}
const response = await fetch('/api/kakaopay/test/single', {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
cid: 'TC0ONETIME',
partner_order_id: 'partner_order_id',
partner_user_id: user,
item_name: itemNames,
quantity: cart.length,
total_amount: finalPrice + 2500,
vat_amount: 200,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/paymentcompleted',
fail_url: 'http://localhost:3000/shoppingcart',
cancel_url: 'http://localhost:3000/shoppingcart',
})
})
const data = await response.json()
} else {
console.log(response.data)
console.log(response2.data)
console.log(response3.data)
alert("주문이 완료되었습니다.")
history.push('/paymentcompleted')
}
} catch (error) {
catchErrors(error, setError)
alert("주문에 실패하셨습니다. 다시 확인해주세요.")
}
}
if (redirect) {
console.log(redirect)
return <Redirect to={'/kakao'} />
}
return (
<div>
{/* {console.log(order)} */}
<Container>
<h3 className="my-5 font-weight-bold text-center">주문/결제</h3>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5>
<Row className="justify-content-md-center">
<Col md={4}>
<Form>
<Form.Group controlId="formBasicName">
<Form.Label>이름</Form.Label>
<Form.Control type="text" value={userData.name} readOnly />
</Form.Group>
<Form.Group controlId="formBasicTel">
<Form.Label>휴대전화</Form.Label>
<Form.Control type="tel" value={userData.tel} readOnly />
</Form.Group>
<Form.Group controlId="formBasicEmail">
<Form.Label>이메일</Form.Label>
<Form.Control type="email" placeholder="이메일 주소를 입력해주세요" />
</Form.Group>
</Form>
</Col>
</Row>
</div>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>받는사람 정보</h5>
<Row className="justify-content-center">
<Col md={8}>
<Form>
<Form.Group>
<Form.Label>이름</Form.Label>
<Form.Control type="text" name="name" onChange={handleReceiverInfo}></Form.Control>
</Form.Group>
<Form.Group>
<Form.Label>휴대전화</Form.Label>
<Form.Control type="text" name="tel" onChange={handleReceiverInfo}></Form.Control>
</Form.Group>
<Form.Group controlId="formBasicAdd">
<Form.Label>주소</Form.Label>
<Form.Row>
<Col xs={4} sm={4}>
<Form.Control type="text" name="postalCode" id="add" onChange={handleReceiverInfo} value={address.code} disabled={(address.code == null) ? false : true} placeholder="우편번호" required ></Form.Control>
</Col>
<Col >
<Button style={{ background: '#91877F', borderColor: '#91877F' }} className="mx-1" onClick={postClick}>우편번호</Button>
{post}
</Col>
</Form.Row>
<Form.Row>
<Col>
<Form.Control type="text" name="address" id="add1" onChange={handleReceiverInfo} value={address.full} disabled={(address.code == null) ? false : true} placeholder="주소" required></Form.Control>
<Form.Control type="text" name="address2" id="add2" onChange={handleReceiverInfo} placeholder="상세주소" required></Form.Control>
<Form.Control.Feedback type="invalid" > 상세 주소를 입력하세요. </Form.Control.Feedback>
</Col>
</Form.Row>
</Form.Group>
</Form>
</Col>
</Row>
</div>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5>
<PaymentCard cart={cart} />
</div>
<div className="p-5 m-3" style={{ background: '#F7F3F3' }}>
<ul className="pl-0" style={{ listStyle: 'none' }}>
<li>
<span className="text-secondary"> 상품금액</span>
<span className="text-secondary float-right">{finalPrice}</span>
</li>
<li>
<span className="text-secondary">배송비</span>
<span className="text-secondary float-right">2500</span>
</li>
</ul>
<div className="my-1 pt-2 border-top font-weight-bold">
결제금액<span className="float-right">{finalPrice + 2500}</span>
</div>
<Container>
<h3 className="my-5 font-weight-bold text-center">주문/결제</h3>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5>
<Row className="justify-content-md-center">
<Col md={4}>
<Form>
<Form.Group controlId="formBasicName">
<Form.Label>이름</Form.Label>
<Form.Control type="text" value={userData.name} readOnly />
</Form.Group>
<Form.Group controlId="formBasicTel">
<Form.Label>휴대전화</Form.Label>
<Form.Control type="tel" value={userData.tel} readOnly />
</Form.Group>
<Form.Group controlId="formBasicEmail">
<Form.Label>이메일</Form.Label>
<Form.Control type="email" value={userData.email} readOnly />
</Form.Group>
</Form>
</Col>
</Row>
</div>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>받는사람 정보</h5>
<Row className="justify-content-center">
<Col md={8}>
<Form>
<Form.Group>
<Form.Label>이름</Form.Label>
<Form.Control type="text" name="name" onChange={handleReceiverInfo}></Form.Control>
</Form.Group>
<Form.Group>
<Form.Label>휴대전화</Form.Label>
<Form.Control type="text" name="tel" onChange={handleReceiverInfo}></Form.Control>
</Form.Group>
<Form.Group controlId="formBasicAdd">
<Form.Label>주소</Form.Label>
<Form.Row>
<Col xs={4} sm={4}>
<Form.Control type="text" name="postalCode" id="add" onChange={handleReceiverInfo} value={address.code} disabled={(address.code == null) ? false : true} placeholder="우편번호" required ></Form.Control>
</Col>
<Col >
<Button style={{ background: '#91877F', borderColor: '#91877F' }} className="mx-1" onClick={postClick}>우편번호</Button>
{post}
</Col>
</Form.Row>
<Form.Row>
<Col>
<Form.Control type="text" name="address" id="add1" onChange={handleReceiverInfo} value={address.full} disabled={(address.code == null) ? false : true} placeholder="주소" required></Form.Control>
<Form.Control type="text" name="address2" id="add2" onChange={handleReceiverInfo} placeholder="상세주소" required></Form.Control>
<Form.Control.Feedback type="invalid" > 상세 주소를 입력하세요. </Form.Control.Feedback>
</Col>
</Form.Row>
</Form.Group>
</Form>
</Col>
</Row>
</div>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5>
<PaymentCard cart={cart} deleteOrder={deleteOrder} />
</div>
<div className="p-5 m-3" style={{ background: '#F7F3F3' }}>
<ul className="pl-0" style={{ listStyle: 'none' }}>
<li>
<span className="text-secondary"> 상품금액</span>
<span className="text-secondary float-right">{finalPrice}</span>
</li>
<li>
<span className="text-secondary">배송비</span>
<span className="text-secondary float-right">2500</span>
</li>
</ul>
<div className="my-1 pt-2 border-top font-weight-bold">
결제금액<span className="float-right">{finalPrice + 2500}</span>
</div>
<div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>결제수단</h5>
<div className="text-center m-3">
<Button variant="success" className="align-top" onClick={handleClick} >무통장입금</Button>
<input type="image" alt="카카오페이결제" src="icon/payment_icon_yellow_small.png" onClick={kakaopay} />
<Button className="align-top m-1" variant="success" onClick={handleClick} style={{ height: '42px' }}>무통장입금</Button>
<Button className="align-top m-1 p-0" style={{ borderColor: "#ffeb00" }} type="button" onClick={kakaopay} alt="카카오페이"><img src="icon/payment_icon_yellow_small2.png" /></Button>
</div>
{paymentWay}
</div>
<div className="text-center">
<Button className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} onClick={paymentCompleted} block>결제완료</Button>
<Button type="button" onClick={paymentCompleted} className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} block>결제완료</Button>
</div>
</Container>
</div>
{paymentWay}
</div>
<div className="text-center">
<Button className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} onClick={paymentCompleted} block>결제완료</Button>
</div>
</Container>
)
}
......
import React, { useState, useEffect } from 'react'
import axios from 'axios';
import { isAuthenticated } from '../utils/auth'
import catchErrors from '../utils/catchErrors';
import { Card, Row, Col, Button, Alert } from 'react-bootstrap';
import { Link } from 'react-router-dom';
function PaymentCompleted() {
const user = isAuthenticated()
const [error, setError] = useState()
const [order, setOrder] = useState([])
const [total, setTotal] = useState(0)
const [receiverInfo, setReceiverInfo] = useState({})
const [num, setNum] = useState('')
useEffect(() => {
getOrder()
}, [user])
async function getOrder() {
try {
setError('')
const response = await axios.get(`/api/order/showorder/${user}`)
console.log(response.data)
setNum(response.data._id)
setOrder(response.data.products)
setTotal(response.data.total)
setReceiverInfo(response.data.receiverInfo)
} catch (error) {
catchErrors(error, setError)
}
}
return (
<div>
<div className="mx-3 my-5 text-center px-3 py-4 border">
<div className="mb-1">
<h5 className=" font-weight-bold" style={{ display: 'inline' }}>고객님의 </h5>
<h5 className=" font-weight-bold text-danger" style={{ display: 'inline' }}>주문이 완료</h5>
<h5 className=" font-weight-bold " style={{ display: 'inline' }}>되었습니다!</h5>
</div>
<div className="my-2">주문번호: {num}</div>
<div className="mb-0">주문내역 확인은 마이페이지의 </div>
<div> "주문/배송조회"에서 하실 있습니다.</div>
</div>
<h3 className="text-center font-weight-bold my-3">주문내역</h3>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>받는사람 정보</h5>
<div className="m-3">
<Row>
<Col xs={4} className="text-right">이름</Col>
<Col>{receiverInfo.name}</Col>
</Row>
<Row>
<Col xs={4} className="text-right">전화번호</Col>
<Col>{receiverInfo.tel}</Col>
</Row>
<Row>
<Col xs={4} className="text-right">주소</Col>
<Col>{receiverInfo.address}{receiverInfo.address2}</Col>
</Row>
</div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문 상품 정보</h5>
{order.map((e) => (
<Card className="mx-2">
<Row className="mx-1">
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text className="mb-0">가격: {e.productId.price}</Card.Text>
<Card.Text className="mb-0">옵션: {e.size}/{e.color}</Card.Text>
<Card.Text>수량: {e.count}</Card.Text>
</Card.Body>
</Col>
</Row>
</Card>
))
}
<Row className="m-3 font-weight-bold py-3" style={{ background: '#F7F3F3' }}>
<Col xs={6} className="text-right"> 결제금액:</Col>
<Col>{total}</Col>
</Row>
<div className="text-center my-3">
<Button href="/" className="mx-1" style={{ background: "#91877F", borderColor: '#91877F', width: "7rem" }}>홈으로</Button>
<Button href="/account" className="mx-1" style={{ background: "#91877F", borderColor: '#91877F', width: "7rem" }}>마이페이지</Button>
</div>
</div>
)
}
export default PaymentCompleted
import axios from 'axios';
import React, { useState, useEffect, useRef } from 'react';
import { Row, Col, Form, Card, Button, Image } from 'react-bootstrap';
import { Redirect } from 'react-router-dom';
import { Redirect, useHistory } from 'react-router-dom';
import axios from 'axios';
import catchErrors from '../utils/catchErrors';
import { Row, Col, Form, Card, Button, Modal, Image } from 'react-bootstrap';
function Product({ match, location }) {
......@@ -14,14 +14,16 @@ function Product({ match, location }) {
const [selected, setSelected] = useState({ sizes: false, colors: false })
const [count, setCount] = useState(1)
const [price, setPrice] = useState(0)
const [show, setShow] = useState(false);
let history = useHistory();
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const replace = product.description.replaceAll('{\n\n}', '<br />')
console.log("replaceALL Description= ", replace)
useEffect(() => {
if (size && color) {
pushOptions()
console.log(cart)
// console.log(cart)
}
}, [size, color])
......@@ -31,13 +33,29 @@ function Product({ match, location }) {
}
function pushOptions() {
setCart([...cart, { color, size, productId: product.id, count: 1 }])
selected.sizes = false
selected.colors = false
console.log(product)
setColor("")
setSize("")
setPrice(product.price + price)
// console.log(cart)
const a = cart.map(el => {
const rObj = {}
rObj["color"] = el.color;
rObj["size"] = el.size;
return rObj
})
const isDuplicated = a.some(el => el.color === color && el.size === size)
if (isDuplicated) {
selected.sizes = false
selected.colors = false
setColor("")
setSize("")
alert("이미 선택한 옵션입니다.")
} else {
selected.sizes = false
selected.colors = false
setCart([...cart, { color, size, productId: product.id, count: 1, checked: false }])
setColor("")
setSize("")
setPrice(product.price + price)
}
}
function handleChange(e) {
......@@ -79,20 +97,42 @@ function Product({ match, location }) {
setCount(e.value)
}
async function addCart() {
async function addCart(event) {
console.log(cart)
if (localStorage.getItem('id')) {
// preCart(color, size, count), productId(productlist에서 props), userId(로컬) 를 보내줌
try {
setError('')
const response = await axios.put('/api/cart/addcart', {
userId: localStorage.getItem('id'),
products: cart
})
console.log(response)
} catch (error) {
catchErrors(error, setError)
if (cart.length < 1) {
alert("옵션을 선택해주세요")
}
else if (localStorage.getItem('id')) {
if (event.target.name === "shoppingcart") {
// preCart(color, size, count), productId(productlist에서 props), userId(로컬) 를 보내줌
try {
setError('')
const response = await axios.put('/api/cart/addcart', {
userId: localStorage.getItem('id'),
products: cart
})
console.log(response.data)
setShow(true)
} catch (error) {
catchErrors(error, setError)
}
} else {
try {
setError('')
cart.map((el) => {
el.checked = true
})
const response = await axios.put('/api/cart/addcart', {
userId: localStorage.getItem('id'),
products: cart
})
console.log(response.data)
history.push("/payment")
} catch (error) {
catchErrors(error, setError)
}
}
} else {
alert("로그인을 해주세요.")
return <Redirect to='/login' />
......@@ -102,7 +142,6 @@ function Product({ match, location }) {
return (
<div>
{console.log(cart)}
<style type="text/css">
{`
.btn {
......@@ -116,6 +155,16 @@ function Product({ match, location }) {
}
`}
</style>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>장바구니에 상품담기</Modal.Title>
</Modal.Header>
<Modal.Body>정상적으로 장바구니에 상품을 담았습니다.</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>쇼핑계속하기</Button>
<Button variant="primary" href='/shoppingcart'>장바구니로 이동</Button>
</Modal.Footer>
</Modal>
<Row className="justify-content-center mt-5 mx-0">
<Col sm={11} md={4}>
<img src={`/images/${product.main_img}`} style={{ objectFit: "contain", width: "100%" }} />
......@@ -157,8 +206,8 @@ function Product({ match, location }) {
<Col className="text-right">{price}</Col>
</Row>
<Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}>
<Button type='button' onClick={addCart} style={{ width: "49%" }}>장바구니</Button>
<Button style={{ width: "49%" }}>구매하기</Button>
<Button type='button' name="shoppingcart" onClick={addCart} style={{ width: "49%" }}>장바구니</Button>
<Button type='button' name="payment" onClick={addCart} style={{ width: "49%" }}>구매하기</Button>
</Row>
</Form>
</Col>
......
......@@ -4,9 +4,6 @@ import { Row, Col, Button, Form, Container, Alert, Spinner } from 'react-bootstr
import axios from 'axios';
import catchErrors from '../utils/catchErrors';
let preColors = []
let colorHtml = []
let list = []
function ProductsRegist() {
const INIT_PRODUCT = {
......@@ -21,11 +18,13 @@ function ProductsRegist() {
main_image: [],
detail_image: []
}
const [preColors, setPreColors] = useState([])
const [categories, setCategories] = useState({ 0: [], 1: [[]] })
const [product, setProduct] = useState(INIT_PRODUCT)
const [categoryNum, setCategoryNum] = useState('')
const [tag, setTag] = useState(0)
const [subCate, setSubCate] = useState('')
const [subCate, setSubCate] = useState([])
const [cateList, setCateList] = useState([])
const [color, setColor] = useState({})
const [error, setError] = useState('')
const [success, setSuccess] = useState(false)
......@@ -50,38 +49,22 @@ function ProductsRegist() {
isProduct ? setDisabled(false) : setDisabled(true)
}, [product])
function addCategory(e) {
if (selectRef.current.value === '') {
alert('하위 분류를 반드시 선택해 주세요.')
} else {
list.push(
<div>
<span name={subCate} >{product["main_category"]} / {subCate} </span>
<input name={subCate} type="image" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right align-middle" onClick={deleteCategory} />
</div>)
setTag(tag + 1)
selectRef.current.selectedIndex = 0
}
}
function deleteCategory(e) {
e.target.parentNode.remove()
const index = product["sub_category"].findIndex((item) => { return item === e.target.name })
product["sub_category"].splice(index, 1)
setSubCate('')
console.log(product["sub_category"].length)
const pdcate = product.sub_category.filter((el) => el !== e.target.name)
setProduct({ ...product, "sub_category": pdcate })
setSubCate([])
}
function handleCategory(e) {
const { name, value, selectedIndex } = e.target
if (name === "main_category") {
setProduct({ ...product, [name]: value })
setCategoryNum(selectedIndex - 1)
}
if (name === "sub_category") {
product[name].push(value)
setSubCate(value)
} else {
setProduct({ ...product, [name]: value })
else {
subCate.push(value)
setProduct({ ...product, [name]: subCate })
selectRef.current.selectedIndex = 0
}
}
......@@ -90,23 +73,15 @@ function ProductsRegist() {
}
function addColor() {
preColors.push(color["colors"])
colorHtml.push(
<div>
<span>{color["colors"]}</span>
<input name={subCate} type="image" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right align-middle" onClick={deleteColor} />
</div>
)
colorRef.current.value = ''
setProduct({ ...product, "colors": preColors })
setProduct({ ...product, "colors":[...product.colors, color["colors"]] })
}
function deleteColor(e) {
// console.log("e.name=",e.target.name)
e.target.parentNode.remove()
product["colors"].splice(e.name, 1)
// setColor({})
// console.log(product)
console.log(product.colors)
console.log(e.target.name)
const pdcolors = product.colors.filter((el) => el !== e.target.name)
setProduct({ ...product, "colors": pdcolors })
}
function handleColor(e) {
......@@ -134,13 +109,13 @@ function ProductsRegist() {
console.log(product)
const formData = new FormData();
for (let key in product) {
if (key === "main_image" || key === "detail_image") {
if (key === "main_image") {
formData.append(key, product[key][0])
} else if(key === "sizes" || key === "colors" || key === 'sub_category'){
for (let i = 0; i < product[key].length ; i++){
} else if (key === "sizes" || key === "colors" || key === "sub_category" || key === "detail_image") {
for (let i = 0; i < product[key].length; i++) {
formData.append([key], product[key][i])
}
}
}
else {
formData.append(key, product[key])
}
......@@ -165,6 +140,7 @@ function ProductsRegist() {
return (
<Container>
{console.log(product)}
<Row className="justify-content-md-center">
<Col md={8} className="border p-1" style={{ background: '#F7F3F3' }}>
{error && <Alert variant="danger" className="text-center">{error}</Alert>}
......@@ -201,11 +177,15 @@ function ProductsRegist() {
)))}
</Form.Control>
</Col>
<Col >
<Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addCategory}>추가</Button>
</Col>
</Row>
{list.map((element) => element)}
{product.sub_category.map((el) => (
<div className="my-2">
<p name={el} className="mb-0" style={{ display: 'inline-block'}} >{product["main_category"]} / {el} </p>
<Button name={el} type="button" className="float-right p-0 btn-light" style={{ display: 'inline-block' }} onClick={deleteCategory} >
<img className="align-top" name={el} alt="삭제" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" />
</Button>
</div>
))}
</Form.Group>
<Form.Group>
<Form.Label>사이즈</Form.Label>
......@@ -238,14 +218,21 @@ function ProductsRegist() {
<Form.Group>
<Form.Label>색상</Form.Label>
<Row>
<Col md={9} xs={9} className="pr-1">
<Col md={9} xs={9} className="pr-0">
<Form.Control as="input" ref={colorRef} name="colors" placeholder="색상" onChange={handleColor} />
</Col>
<Col className="pl-1">
<Col className="pl-0">
<Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addColor}>추가</Button>
</Col>
</Row>
{colorHtml.map((element) => element)}
{product.colors.map((el) => (
<div className="my-2">
<p className="mb-0" style={{ display: 'inline-block' }}>{el}</p>
<Button style={{ display: 'inline-block' }} name={el} type="button" className="float-right p-0 btn-light" onClick={deleteColor}>
<img className="align-top" name={el} alt="삭제" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" />
</Button>
</div>
))}
</Form.Group>
<Form.Group controlId="productDescriptionform">
<Form.Label>상품설명</Form.Label>
......@@ -257,7 +244,7 @@ function ProductsRegist() {
</Form.Group>
<Form.Group>
<Form.Label>상세이미지</Form.Label>
<Form.File id="productImageform" name="detail_image" onChange={handleChange} />
<Form.File id="productImageform" name="detail_image" onChange={handleChange} multiple />
</Form.Group>
<Button type="submit" style={{ background: '#91877F', borderColor: '#91877F' }} block>
{loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />}{' '}등록
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment