Commit f1936e20 authored by kusang96's avatar kusang96
Browse files

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

parents f31064c6 40e214a6
...@@ -10,6 +10,7 @@ import Admin from './Pages/Admin'; ...@@ -10,6 +10,7 @@ import Admin from './Pages/Admin';
import ProductRegist from './Pages/ProductRegist'; import ProductRegist from './Pages/ProductRegist';
import ShoppingCart from './Pages/ShoppingCart'; import ShoppingCart from './Pages/ShoppingCart';
import Payment from './Pages/Payment'; import Payment from './Pages/Payment';
import PaymentCompleted from './Pages/PaymentCompleted';
import Account from './Pages/Account'; import Account from './Pages/Account';
import MainNav from './Components/MainNav'; import MainNav from './Components/MainNav';
import SubNav from './Components/SubNav'; import SubNav from './Components/SubNav';
...@@ -39,6 +40,9 @@ function App() { ...@@ -39,6 +40,9 @@ function App() {
<PrivateRoute path="/payment"> <PrivateRoute path="/payment">
<Payment /> <Payment />
</PrivateRoute> </PrivateRoute>
<PrivateRoute path="/paymentcompleted">
<PaymentCompleted />
</PrivateRoute>
<PrivateRoute path="/account"> <PrivateRoute path="/account">
<Account /> <Account />
</PrivateRoute> </PrivateRoute>
......
...@@ -18,9 +18,9 @@ function CartCard(props) { ...@@ -18,9 +18,9 @@ function CartCard(props) {
<Card.Body> <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} /> <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.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>가격: {e.productId.price}</Card.Text> <Card.Text className="mb-0">가격: {e.productId.price}</Card.Text>
<Card.Text>옵션: {e.size}/{e.color}</Card.Text> <Card.Text className="mb-0">옵션: {e.size}/{e.color}</Card.Text>
<Card.Text>수량</Card.Text> <Card.Text >수량</Card.Text>
<div> <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="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="number" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
......
...@@ -6,22 +6,23 @@ function PaymentCard(props) { ...@@ -6,22 +6,23 @@ function PaymentCard(props) {
return ( return (
<> <>
{props.cart.map((e) => ( {props.cart.map((e) => (
<Card> <Card>
<Row className="mx-1"> <Row className="mx-1">
<Col className="text-center"> <Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} /> <Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col> </Col>
<Col md={6} className="p-2"> <Col md={6} className="p-2">
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title> <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.Text>가격: {e.productId.price}</Card.Text> <Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>옵션: {e.size}/{e.color}</Card.Text> <Card.Text>가격: {e.productId.price}</Card.Text>
<Card.Text>수량: {e.count}</Card.Text> <Card.Text>옵션: {e.size}/{e.color}</Card.Text>
</Card.Body> <Card.Text>수량: {e.count}</Card.Text>
</Col> </Card.Body>
</Row> </Col>
</Card> </Row>
)) </Card>
))
} }
</> </>
) )
......
...@@ -2,7 +2,7 @@ import axios from 'axios'; ...@@ -2,7 +2,7 @@ import axios from 'axios';
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import DaumPostcode from "react-daum-postcode"; import DaumPostcode from "react-daum-postcode";
import { Container, Card, Row, Col, Button, Form, FormGroup } from 'react-bootstrap'; import { Container, Card, Row, Col, Button, Form, FormGroup } from 'react-bootstrap';
import { Redirect, Link } from 'react-router-dom'; import { Redirect, Link, useHistory } from 'react-router-dom';
import PaymentCard from '../Components/PaymentCard'; import PaymentCard from '../Components/PaymentCard';
import { isAuthenticated } from '../utils/auth'; import { isAuthenticated } from '../utils/auth';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
...@@ -12,16 +12,15 @@ function Payment({ match, location }) { ...@@ -12,16 +12,15 @@ function Payment({ match, location }) {
const [order, setOrder] = useState({products: []}) const [order, setOrder] = useState({products: []})
const [userData, setUserData] = useState({}) const [userData, setUserData] = useState({})
const [error, setError] = 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 [post, setPost] = useState([])
const [redirect, setRedirect] = useState(null) const [redirect, setRedirect] = useState(null)
const [address, setAddress] = useState("") const [address, setAddress] = useState("")
const [finalPrice, setFinalPrice] = useState(0) const [finalPrice, setFinalPrice] = useState(0)
const [num, setNum] = useState(0) const [paymentWay, setPaymentWay] = useState([])
const [completeState, setCompleteState] = useState(false)
const user = isAuthenticated() const user = isAuthenticated()
let history = useHistory();
const preCart = []
useEffect(() => { useEffect(() => {
getUser() getUser()
...@@ -39,15 +38,37 @@ function Payment({ match, location }) { ...@@ -39,15 +38,37 @@ function Payment({ match, location }) {
async function getUser() { async function getUser() {
const name = localStorage.getItem('name') const name = localStorage.getItem('name')
const tel = localStorage.getItem('tel') const tel = localStorage.getItem('tel')
// const email = localStorage.getItem('email') const email = localStorage.getItem('email')
setUserData({ name: name, tel: tel }) setUserData({ name: name, tel: tel, email: email })
} }
async function getCart() { async function getCart() {
try { try {
setError('')
const response = await axios.get(`/api/cart/showcart/${user}`) const response = await axios.get(`/api/cart/showcart/${user}`)
console.log(response.data) console.log(response.data)
const preCart = response.data.filter((el) => el.checked === true) 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
})
console.log(response.data)
const preCart = response.data.products.filter((el) => el.checked === true)
setCart(preCart) setCart(preCart)
setOrder({ products: preCart }) setOrder({ products: preCart })
} catch (error) { } catch (error) {
...@@ -105,9 +126,9 @@ function Payment({ match, location }) { ...@@ -105,9 +126,9 @@ function Payment({ match, location }) {
function handleClick() { function handleClick() {
if (paymentWay.length !== 0) { if (paymentWay.length !== 0) {
setCompleteState(false)
setPaymentWay([]) setPaymentWay([])
} } else {
else {
const a = ( const a = (
<Row className="justify-content-md-center"> <Row className="justify-content-md-center">
<Col md={6} className="border m-5 p-5"> <Col md={6} className="border m-5 p-5">
...@@ -137,34 +158,15 @@ function Payment({ match, location }) { ...@@ -137,34 +158,15 @@ function Payment({ match, location }) {
} }
async function kakaopay() { async function kakaopay() {
let itemNames = ""
if (cart.length > 1) { setCompleteState("kakaopay")
itemNames = cart[0].productId.pro_name + '' + String(cart.length - 1) + '' setPaymentWay(
} else { <div className="text-center">
itemNames = cart[0].productId.pro_name <p className=" font-weight-bold" style={{ display: 'inline' }}>'카카오페이'</p><p style={{ display: 'inline' }}>를 선택하셨습니다. </p>
} <p>주문하기를 눌러 결제를 이어가주세요.</p>
const response = await fetch('/api/kakaopay/test/single', { </div>
method: "POST", )
headers: { // window.location.href = data.redirect_url
'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
// setRedirect(data.redirect_url) // setRedirect(data.redirect_url)
} }
...@@ -175,6 +177,7 @@ function Payment({ match, location }) { ...@@ -175,6 +177,7 @@ function Payment({ match, location }) {
cartIds.push(el._id) cartIds.push(el._id)
}) })
try { try {
setError('')
const response = await axios.post(`/api/order/addorder`, { const response = await axios.post(`/api/order/addorder`, {
userId: user, userId: user,
...order, ...order,
...@@ -187,25 +190,49 @@ function Payment({ match, location }) { ...@@ -187,25 +190,49 @@ function Payment({ match, location }) {
const response3 = await axios.post(`/api/product/pluspurchase`, { const response3 = await axios.post(`/api/product/pluspurchase`, {
products: order.products products: order.products
}) })
console.log(response.data) if (completeState === "kakaopay") {
alert("주문이 완료되었습니다.") let itemNames = ""
return <Redirect to={'/account'} /> 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) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
alert("주문에 실패하셨습니다. 다시 확인해주세요.") alert("주문에 실패하셨습니다. 다시 확인해주세요.")
} }
} }
if (redirect) {
console.log(redirect)
return <Redirect to={'/kakao'} />
}
return ( return (
<div> <div>
{/* {console.log(order)} */} {/* {console.log(completeState)} */}
<Container> <Container>
<h3 className="my-5 font-weight-bold text-center">주문/결제</h3> <h3 className="my-5 font-weight-bold text-center">주문/결제</h3>
<div> <div>
...@@ -223,7 +250,7 @@ function Payment({ match, location }) { ...@@ -223,7 +250,7 @@ function Payment({ match, location }) {
</Form.Group> </Form.Group>
<Form.Group controlId="formBasicEmail"> <Form.Group controlId="formBasicEmail">
<Form.Label>이메일</Form.Label> <Form.Label>이메일</Form.Label>
<Form.Control type="email" placeholder="이메일 주소를 입력해주세요" /> <Form.Control type="email" value={userData.email} readOnly />
</Form.Group> </Form.Group>
</Form> </Form>
</Col> </Col>
...@@ -266,10 +293,9 @@ function Payment({ match, location }) { ...@@ -266,10 +293,9 @@ function Payment({ match, location }) {
</Col> </Col>
</Row> </Row>
</div> </div>
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5>
<PaymentCard cart={cart} /> <PaymentCard cart={cart} deleteOrder={deleteOrder} />
</div> </div>
<div className="p-5 m-3" style={{ background: '#F7F3F3' }}> <div className="p-5 m-3" style={{ background: '#F7F3F3' }}>
...@@ -287,17 +313,16 @@ function Payment({ match, location }) { ...@@ -287,17 +313,16 @@ function Payment({ match, location }) {
결제금액<span className="float-right">{finalPrice + 2500}</span> 결제금액<span className="float-right">{finalPrice + 2500}</span>
</div> </div>
</div> </div>
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>결제수단</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>결제수단</h5>
<div className="text-center m-3"> <div className="text-center m-3">
<Button variant="success" className="align-top" onClick={handleClick} >무통장입금</Button> <Button className="align-top m-1" variant="success" onClick={handleClick} style={{ height: '42px' }}>무통장입금</Button>
<input type="image" alt="카카오페이결제" src="icon/payment_icon_yellow_small.png" onClick={kakaopay} /> <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> </div>
{paymentWay} {paymentWay}
</div> </div>
<div className="text-center"> <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> </div>
</Container> </Container>
</div> </div>
......
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 axios from 'axios';
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Row, Col, Form, Card, Button, Image } from 'react-bootstrap'; import { Row, Col, Form, Card, Button, Modal, Image } from 'react-bootstrap';
import { Redirect } from 'react-router-dom'; import { Redirect, useHistory } from 'react-router-dom';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
...@@ -14,18 +14,18 @@ function Product({ match, location }) { ...@@ -14,18 +14,18 @@ function Product({ match, location }) {
const [selected, setSelected] = useState({ sizes: false, colors: false }) const [selected, setSelected] = useState({ sizes: false, colors: false })
const [count, setCount] = useState(1) const [count, setCount] = useState(1)
const [price, setPrice] = useState(0) 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', '<br />') const replace = product.description.replaceAll('\n', '<br />')
// const replace = product.description.replaceAll('\n', '<br />')
// const replace = product.description.replaceAll(/\n/, '<br />')
console.log("objectasdasd", replace) console.log("objectasdasd", replace)
useEffect(() => { useEffect(() => {
if (size && color) { if (size && color) {
pushOptions() pushOptions()
console.log(cart) // console.log(cart)
} }
}, [size, color]) }, [size, color])
...@@ -35,13 +35,29 @@ function Product({ match, location }) { ...@@ -35,13 +35,29 @@ function Product({ match, location }) {
} }
function pushOptions() { function pushOptions() {
setCart([...cart, { color, size, productId: product.id, count: 1 }]) // console.log(cart)
selected.sizes = false const a = cart.map(el => {
selected.colors = false const rObj = {}
console.log(product) rObj["color"] = el.color;
setColor("") rObj["size"] = el.size;
setSize("") return rObj
setPrice(product.price + price) })
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) { function handleChange(e) {
...@@ -83,20 +99,42 @@ function Product({ match, location }) { ...@@ -83,20 +99,42 @@ function Product({ match, location }) {
setCount(e.value) setCount(e.value)
} }
async function addCart() { async function addCart(event) {
console.log(cart) console.log(cart)
if (localStorage.getItem('id')) { if (cart.length < 1) {
// preCart(color, size, count), productId(productlist에서 props), userId(로컬) 를 보내줌 alert("옵션을 선택해주세요")
try { }
setError('') else if (localStorage.getItem('id')) {
const response = await axios.put('/api/cart/addcart', { if (event.target.name === "shoppingcart") {
userId: localStorage.getItem('id'), // preCart(color, size, count), productId(productlist에서 props), userId(로컬) 를 보내줌
products: cart try {
}) setError('')
console.log(response) const response = await axios.put('/api/cart/addcart', {
} catch (error) { userId: localStorage.getItem('id'),
catchErrors(error, setError) 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 { } else {
alert("로그인을 해주세요.") alert("로그인을 해주세요.")
return <Redirect to='/login' /> return <Redirect to='/login' />
...@@ -106,7 +144,17 @@ function Product({ match, location }) { ...@@ -106,7 +144,17 @@ function Product({ match, location }) {
return ( return (
<div> <div>
{console.log(cart)} <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>
{/* {console.log(cart)} */}
<style type="text/css"> <style type="text/css">
{` {`
.btn { .btn {
...@@ -161,8 +209,8 @@ function Product({ match, location }) { ...@@ -161,8 +209,8 @@ function Product({ match, location }) {
<Col className="text-right">{price}</Col> <Col className="text-right">{price}</Col>
</Row> </Row>
<Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}> <Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}>
<Button type='button' onClick={addCart} style={{ width: "49%" }}>장바구니</Button> <Button type='button' name="shoppingcart" onClick={addCart} style={{ width: "49%" }}>장바구니</Button>
<Button style={{ width: "49%" }}>구매하기</Button> <Button type='button' name="payment" onClick={addCart} style={{ width: "49%" }}>구매하기</Button>
</Row> </Row>
</Form> </Form>
</Col> </Col>
...@@ -173,19 +221,19 @@ function Product({ match, location }) { ...@@ -173,19 +221,19 @@ function Product({ match, location }) {
설명 설명
</h3> </h3>
<Col className='justify-content-center '> <Col className='justify-content-center '>
<h2 className='p-2 text-center border' style={{background : '#CDC5C2'}}>{product.name} </h2> <h2 className='p-2 text-center border' style={{ background: '#CDC5C2' }}>{product.name} </h2>
<> <>
<Image src={`/images/${product.main_img}`} style={{ objectFit: "contain", maxWidth: "100%"}} /> <Image src={`/images/${product.main_img}`} style={{ objectFit: "contain", maxWidth: "100%" }} />
</> </>
<Card className='m-3 d-flex justify-content-center'> <Card className='m-3 d-flex justify-content-center'>
<Card.Body className='text-center'> <Card.Body className='text-center'>
{replace} {replace}
</Card.Body> </Card.Body>
</Card> </Card>
<> <>
<h4 className='my-4 text-center'>[ Detail Images ]</h4> <h4 className='my-4 text-center'>[ Detail Images ]</h4>
<Image src={`/images/${product.detail_imgs}`} style={{ objectFit: "contain", maxWidth: "100%"}}/> <Image src={`/images/${product.detail_imgs}`} style={{ objectFit: "contain", maxWidth: "100%" }} />
</> </>
</Col> </Col>
</Col> </Col>
</Row> </Row>
......
...@@ -4,9 +4,6 @@ import { Row, Col, Button, Form, Container, Alert, Spinner } from 'react-bootstr ...@@ -4,9 +4,6 @@ import { Row, Col, Button, Form, Container, Alert, Spinner } from 'react-bootstr
import axios from 'axios'; import axios from 'axios';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
let preColors = []
let colorHtml = []
let list = []
function ProductsRegist() { function ProductsRegist() {
const INIT_PRODUCT = { const INIT_PRODUCT = {
...@@ -21,11 +18,13 @@ function ProductsRegist() { ...@@ -21,11 +18,13 @@ function ProductsRegist() {
main_image: [], main_image: [],
detail_image: [] detail_image: []
} }
const [preColors, setPreColors] = useState([])
const [categories, setCategories] = useState({ 0: [], 1: [[]] }) const [categories, setCategories] = useState({ 0: [], 1: [[]] })
const [product, setProduct] = useState(INIT_PRODUCT) const [product, setProduct] = useState(INIT_PRODUCT)
const [categoryNum, setCategoryNum] = useState('') const [categoryNum, setCategoryNum] = useState('')
const [tag, setTag] = useState(0) const [tag, setTag] = useState(0)
const [subCate, setSubCate] = useState('') const [subCate, setSubCate] = useState([])
const [cateList, setCateList] = useState([])
const [color, setColor] = useState({}) const [color, setColor] = useState({})
const [error, setError] = useState('') const [error, setError] = useState('')
const [success, setSuccess] = useState(false) const [success, setSuccess] = useState(false)
...@@ -50,38 +49,22 @@ function ProductsRegist() { ...@@ -50,38 +49,22 @@ function ProductsRegist() {
isProduct ? setDisabled(false) : setDisabled(true) isProduct ? setDisabled(false) : setDisabled(true)
}, [product]) }, [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) { function deleteCategory(e) {
e.target.parentNode.remove() const pdcate = product.sub_category.filter((el) => el !== e.target.name)
const index = product["sub_category"].findIndex((item) => { return item === e.target.name }) setProduct({ ...product, "sub_category": pdcate })
product["sub_category"].splice(index, 1) setSubCate([])
setSubCate('')
console.log(product["sub_category"].length)
} }
function handleCategory(e) { function handleCategory(e) {
const { name, value, selectedIndex } = e.target const { name, value, selectedIndex } = e.target
if (name === "main_category") { if (name === "main_category") {
setProduct({ ...product, [name]: value })
setCategoryNum(selectedIndex - 1) setCategoryNum(selectedIndex - 1)
} }
if (name === "sub_category") { else {
product[name].push(value) subCate.push(value)
setSubCate(value) setProduct({ ...product, [name]: subCate })
} else { selectRef.current.selectedIndex = 0
setProduct({ ...product, [name]: value })
} }
} }
...@@ -90,20 +73,15 @@ function ProductsRegist() { ...@@ -90,20 +73,15 @@ function ProductsRegist() {
} }
function addColor() { 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 = '' colorRef.current.value = ''
setProduct({ ...product, "colors": preColors }) setProduct({ ...product, "colors":[...product.colors, color["colors"]] })
} }
function deleteColor(e) { function deleteColor(e) {
e.target.parentNode.remove() console.log(product.colors)
product["colors"].splice(e.name, 1) console.log(e.target.name)
const pdcolors = product.colors.filter((el) => el !== e.target.name)
setProduct({ ...product, "colors": pdcolors })
} }
function handleColor(e) { function handleColor(e) {
...@@ -133,11 +111,11 @@ function ProductsRegist() { ...@@ -133,11 +111,11 @@ function ProductsRegist() {
for (let key in product) { for (let key in product) {
if (key === "main_image" || key === "detail_image") { if (key === "main_image" || key === "detail_image") {
formData.append(key, product[key][0]) formData.append(key, product[key][0])
} else if(key === "sizes" || key === "colors" || key === 'sub_category'){ } else if (key === "sizes" || key === "colors" || key === "sub_category") {
for (let i = 0; i < product[key].length ; i++){ for (let i = 0; i < product[key].length; i++) {
formData.append([key], product[key][i]) formData.append([key], product[key][i])
} }
} }
else { else {
formData.append(key, product[key]) formData.append(key, product[key])
} }
...@@ -162,6 +140,7 @@ function ProductsRegist() { ...@@ -162,6 +140,7 @@ function ProductsRegist() {
return ( return (
<Container> <Container>
{console.log(product)}
<Row className="justify-content-md-center"> <Row className="justify-content-md-center">
<Col md={8} className="border p-1" style={{ background: '#F7F3F3' }}> <Col md={8} className="border p-1" style={{ background: '#F7F3F3' }}>
{error && <Alert variant="danger" className="text-center">{error}</Alert>} {error && <Alert variant="danger" className="text-center">{error}</Alert>}
...@@ -198,11 +177,15 @@ function ProductsRegist() { ...@@ -198,11 +177,15 @@ function ProductsRegist() {
)))} )))}
</Form.Control> </Form.Control>
</Col> </Col>
<Col >
<Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addCategory}>추가</Button>
</Col>
</Row> </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.Group> <Form.Group>
<Form.Label>사이즈</Form.Label> <Form.Label>사이즈</Form.Label>
...@@ -235,14 +218,21 @@ function ProductsRegist() { ...@@ -235,14 +218,21 @@ function ProductsRegist() {
<Form.Group> <Form.Group>
<Form.Label>색상</Form.Label> <Form.Label>색상</Form.Label>
<Row> <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} /> <Form.Control as="input" ref={colorRef} name="colors" placeholder="색상" onChange={handleColor} />
</Col> </Col>
<Col className="pl-1"> <Col className="pl-0">
<Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addColor}>추가</Button> <Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addColor}>추가</Button>
</Col> </Col>
</Row> </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>
<Form.Group controlId="productDescriptionform"> <Form.Group controlId="productDescriptionform">
<Form.Label>상품설명</Form.Label> <Form.Label>상품설명</Form.Label>
......
...@@ -17,6 +17,8 @@ function ProductsList({ match }) { ...@@ -17,6 +17,8 @@ function ProductsList({ match }) {
const indexOfLast = currentPage * postsPerPage; const indexOfLast = currentPage * postsPerPage;
const indexOfFirst = indexOfLast - postsPerPage; const indexOfFirst = indexOfLast - postsPerPage;
const [sortingName, setSortingName] = useState('정렬')
function currentPosts(tmp) { function currentPosts(tmp) {
let currentPosts = 0; let currentPosts = 0;
currentPosts = tmp.slice(indexOfFirst, indexOfLast); currentPosts = tmp.slice(indexOfFirst, indexOfLast);
...@@ -70,11 +72,60 @@ function ProductsList({ match }) { ...@@ -70,11 +72,60 @@ function ProductsList({ match }) {
} }
async function handleSort(method) { async function handleSort(method) {
try { console.log(method)
const response = await axios.get(`/api/product/getproduct/?q=${method}`) if (method === "purchase") {
setProductlist(response.data) console.log("thisispurchase")
} catch (error) { productlist.sort(function (a, b) {
catchError(error, setError) if (a.purchase > b.purchase) {
return -1;
}
if (a.purchase < b.purchase) {
return 1;
}
// a must be equal to b
return 0;
});
setSortingName("인기상품")
} else if(method === "newest"){
console.log("thisisnewest")
productlist.sort(function (a, b) {
if (a.createdAt > b.createdAt) {
return -1;
}
if (a.createdAt < b.createdAt) {
return 1;
}
// a must be equal to b
return 0;
});
setSortingName("신상품")
} else if(method === "lowest"){
console.log("thisislowest")
productlist.sort(function (a, b) {
if (a.price > b.price) {
return 1;
}
if (a.price < b.price) {
return -1;
}
// a must be equal to b
return 0;
});
setSortingName("낮은가격")
} else {
console.log("thisispurchase")
productlist.sort(function (a, b) {
if (a.price > b.price) {
return -1;
}
if (a.price < b.price) {
return 1;
}
// a must be equal to b
return 0;
});
setSortingName("높은가격")
} }
} }
...@@ -94,6 +145,7 @@ function ProductsList({ match }) { ...@@ -94,6 +145,7 @@ function ProductsList({ match }) {
return ( return (
<Container> <Container>
{console.log(productlist)}
<style type="text/css"> <style type="text/css">
{` {`
a, a:hover, a:active { a, a:hover, a:active {
...@@ -120,22 +172,22 @@ function ProductsList({ match }) { ...@@ -120,22 +172,22 @@ function ProductsList({ match }) {
</div> </div>
</Col> </Col>
</Row> </Row>
<Row className="justify-content-end mx-0 my-5"> <Row className="justify-content-end mx-0 mt-5 mb-3">
<Dropdown> <Form inline onSubmit={handleSearch} className="justify-content-end mx-0 my-2">
<Dropdown.Toggle variant="secondary" className="mx-2">정렬</Dropdown.Toggle> <FormControl type="text" onChange={handleChange} placeholder="Search" style={{ width: "13rem" }} />
<Dropdown.Menu> <Button type="submit" className="px-2 mr-2">
<Dropdown.Item>인기상품</Dropdown.Item>
<Dropdown.Item>신상품</Dropdown.Item>
<Dropdown.Item>낮은가격</Dropdown.Item>
<Dropdown.Item>높은가격</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Form as={Row} onSubmit={handleSearch} className="justify-content-end mx-0">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="search px-2" variant="secondary">
<img src="/icon/search.svg" width="20" height="20" /> <img src="/icon/search.svg" width="20" height="20" />
</Button> </Button>
</Form> </Form>
<Dropdown className="my-2">
<Dropdown.Toggle className="mx-2">{sortingName}</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item as="button" onClick={() => handleSort('purchase')}>인기상품</Dropdown.Item>
<Dropdown.Item as="button" onClick={() => handleSort('newest')}>신상품</Dropdown.Item>
<Dropdown.Item as="button" onClick={() => handleSort('lowest')}>낮은가격</Dropdown.Item>
<Dropdown.Item as="button" onClick={() => handleSort('highest')}>높은가격</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Row> </Row>
<Row md={8} sm={12} className="justify-content-center m-2"> <Row md={8} sm={12} className="justify-content-center m-2">
{productlist.length > 0 ? {productlist.length > 0 ?
......
...@@ -15,7 +15,7 @@ function ShoppingCart() { ...@@ -15,7 +15,7 @@ function ShoppingCart() {
useEffect(() => { useEffect(() => {
getCart() getCart()
console.log(cart) // console.log(cart)
}, [user]) }, [user])
function plusNum(e) { function plusNum(e) {
...@@ -59,7 +59,7 @@ function ShoppingCart() { ...@@ -59,7 +59,7 @@ function ShoppingCart() {
async function deleteCart(e) { async function deleteCart(e) {
//장바구니 DB에서 해당 항목 삭제 //장바구니 DB에서 해당 항목 삭제
console.log(e.target.name) // console.log(e.target.name)
try { try {
const response = await axios.post('/api/cart/deletecart', { const response = await axios.post('/api/cart/deletecart', {
userId: user, userId: user,
...@@ -70,7 +70,7 @@ function ShoppingCart() { ...@@ -70,7 +70,7 @@ function ShoppingCart() {
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
} }
console.log('카트에 담긴 항목을 삭제했습니다.') // console.log('카트에 담긴 항목을 삭제했습니다.')
} }
async function getCart() { async function getCart() {
...@@ -102,7 +102,7 @@ function ShoppingCart() { ...@@ -102,7 +102,7 @@ function ShoppingCart() {
return ( return (
<div> <div>
{console.log(cart)} {/* {console.log(cart)} */}
<Container className="justify-content-center"> <Container className="justify-content-center">
<h1 className="my-5 font-weight-bold text-center">장바구니</h1> <h1 className="my-5 font-weight-bold text-center">장바구니</h1>
<div> <div>
......
import axios from "axios"; import axios from "axios";
export function handleLogin({ userId, role, name, tel }) { export function handleLogin({ userId, role, name, tel, email }) {
localStorage.setItem('id', userId) localStorage.setItem('id', userId)
localStorage.setItem('role', role) localStorage.setItem('role', role)
localStorage.setItem('name', name) localStorage.setItem('name', name)
localStorage.setItem('tel', tel) localStorage.setItem('tel', tel)
localStorage.setItem('email', email)
} }
export async function handleLogout() { export async function handleLogout() {
......
...@@ -7,7 +7,7 @@ const login = async (req, res) => { ...@@ -7,7 +7,7 @@ const login = async (req, res) => {
const { id, password } = req.body const { id, password } = req.body
console.log(id, password) console.log(id, password)
try { try {
const user = await User.findOne({ id }).select('password role name tel') const user = await User.findOne({ id }).select('password role name tel email')
console.log('u=', user) console.log('u=', user)
if (!user) { if (!user) {
return res.status(404).send(`${id}가 존재하지 않습니다.`) return res.status(404).send(`${id}가 존재하지 않습니다.`)
...@@ -23,7 +23,7 @@ const login = async (req, res) => { ...@@ -23,7 +23,7 @@ const login = async (req, res) => {
httpOnly: true, httpOnly: true,
secure: config.env === 'production' secure: config.env === 'production'
}) })
res.json({ userId: user._id, role: user.role, name: user.name, tel: user.tel }) res.json({ userId: user._id, role: user.role, name: user.name, tel: user.tel, email:user.email })
} else { } else {
res.status(401).send('비밀번호가 일치하지 않습니다.') res.status(401).send('비밀번호가 일치하지 않습니다.')
......
...@@ -58,7 +58,6 @@ const deleteCart = async (req, res) => { ...@@ -58,7 +58,6 @@ const deleteCart = async (req, res) => {
path: 'products.productId', path: 'products.productId',
model: 'Product' model: 'Product'
}) })
// res.send("삭제완료")
res.json(cart) res.json(cart)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
...@@ -80,7 +79,7 @@ const deleteCart2 = async (req, res) => { ...@@ -80,7 +79,7 @@ const deleteCart2 = async (req, res) => {
model: 'Product' model: 'Product'
}) })
} }
res.send("주문완료 쇼핑카트 삭제") res.send("주문완료 쇼핑카트에서 삭제")
// res.json(cart) // res.json(cart)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
......
import Order from "../schemas/Order.js"; import Order from "../schemas/Order.js";
import User from "../schemas/User.js";
const addorder = async (req, res) => { const addorder = async (req, res) => {
const { userId, products, receiverInfo, total } = req.body const { userId, products, receiverInfo, total } = req.body
...@@ -26,11 +27,12 @@ const Ordered = async (req, res) => { ...@@ -26,11 +27,12 @@ const Ordered = async (req, res) => {
const showorder = async (req, res) => { const showorder = async (req, res) => {
try { try {
const order = await Order.findOne({ userId: req.id }).populate({ const order = await Order.find({ userId: req.userId }).sort({_id:-1}).limit(1).populate({
path: 'products.productId', path: 'products.productId',
model: 'Product' model: 'Product'
}) })
res.status(200).json(order.products) console.log(order)
res.status(200).json(order[0])
} catch (error) { } catch (error) {
console.log(error) console.log(error)
res.status(500).send('쇼핑카트를 불러오지 못했습니다.') res.status(500).send('쇼핑카트를 불러오지 못했습니다.')
...@@ -38,7 +40,19 @@ const showorder = async (req, res) => { ...@@ -38,7 +40,19 @@ const showorder = async (req, res) => {
} }
const orderById = async (req, res, next, id) => {
try {
const user = await User.findById(id)
if (!user) {
res.status(404).send('사용자를 찾을 수 없습니다')
}
req.userId = user
next()
} catch (error) {
console.log(error);
res.status(500).send('사용자 아이디 검색 실패')
}
}
export default { addorder, showorder, orderById , Ordered}
export default { addorder, showorder, Ordered }
\ No newline at end of file
...@@ -96,12 +96,18 @@ const plusPurchase = async (req, res) => { ...@@ -96,12 +96,18 @@ const plusPurchase = async (req, res) => {
{ _id: products[i].productId._id } { _id: products[i].productId._id }
) )
const purchase = product.purchase const purchase = product.purchase
const stock = product.stock
await Product.updateOne( await Product.updateOne(
{ _id: products[i].productId._id }, { _id: products[i].productId._id },
{ $set: { purchase: count + purchase } } { $set:
{
purchase: count + purchase,
stock: stock - count
}
}
) )
} }
res.send("구매수 늘리기 성공") res.send("구매수 늘리기, 재고수 줄이기 성공")
} catch (error) { } catch (error) {
res.status(500).send('구매숫자를 늘리지 못함') res.status(500).send('구매숫자를 늘리지 못함')
} }
......
...@@ -11,5 +11,6 @@ router.route('/addorder') ...@@ -11,5 +11,6 @@ router.route('/addorder')
router.route('/showorder/:userId') router.route('/showorder/:userId')
.get(orderCtrl.showorder) .get(orderCtrl.showorder)
router.param('userId', orderCtrl.orderById)
export default router export default router
\ No newline at end of file
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