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'; ...@@ -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>
......
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom'; import { Redirect, Route } from 'react-router-dom';
import { isAdmin } from '../utils/auth'; import { isAdmin } from '../utils/auth';
function PrivateRoute({path, children}) { function PrivateRoute({ path, children }) {
if (isAdmin()) { if (isAdmin()) {
return ( return (
<Route path={path}> <Route path={path}>
...@@ -10,7 +10,7 @@ function PrivateRoute({path, children}) { ...@@ -10,7 +10,7 @@ function PrivateRoute({path, children}) {
</Route> </Route>
) )
} else { } else {
alert('한이 없습니다. 죄송합니다.'); alert('한이 없습니다. 죄송합니다.');
return ( return (
<Redirect to='/' /> <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' ...@@ -2,38 +2,36 @@ import React from 'react'
import { Card, Row, Col } from 'react-bootstrap'; import { Card, Row, Col } from 'react-bootstrap';
function CartCard(props) { function CartCard(props) {
console.log(props)
return ( return (
<> <>
{props.cart.map((e) => ( {props.cart.map((e) => (
<Card> <Card>
<Row className="mx-1"> <Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto"> <Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} /> <input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} />
</Col> </Col>
<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>
<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>
<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} /> <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> </div>
</Card.Body> </Card.Body>
</Col> </Col>
</Row> </Row>
</Card> </Card>
)) ))
} }
</> </>
) )
} }
......
import React, { useState, useEffect, useRef } from 'react'; import React from 'react';
import { Card, Button } from 'react-bootstrap'; import { Card } from 'react-bootstrap';
function ListCard({ id, name, price, main_img }) { function ListCard({ id, name, price, main_img }) {
function handleDelete(e) {
const card = e.target.parentNode.parentNode
alert('해당 상품을 성공적으로 삭제하였습니다.')
card.remove()
}
return ( return (
<Card id={id} className="m-3" style={{ width: "18rem" }}> <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.Img variant="top" src={main_img && `/images/${main_img}`} style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</Card.Title> <Card.Title style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</Card.Title>
<Card.Text>{price} </Card.Text> <Card.Text>{price} </Card.Text>
{/* <Button className="float-right" onClick={handleDelete}>삭제</Button> */}
</Card.Body> </Card.Body>
</Card> </Card>
) )
......
...@@ -21,7 +21,7 @@ function MainNav() { ...@@ -21,7 +21,7 @@ function MainNav() {
<img alt="카트" src="/icon/cart.svg" width="30" height="30" /> <img alt="카트" src="/icon/cart.svg" width="30" height="30" />
</Nav.Link> </Nav.Link>
</> </>
: ( : (
<> <>
<Nav.Link className="text-light" href='/login'>Login</Nav.Link> <Nav.Link className="text-light" href='/login'>Login</Nav.Link>
<Nav.Link className="text-light" href='/signup'>Sign Up</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 React from 'react';
import { Pagination } from 'react-bootstrap';
function Paginations({ index, totalPages, handlePage }) {
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>,
);
}
return ( 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 export default Paginations
\ No newline at end of file \ No newline at end of file
...@@ -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 React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom'; import { Redirect, Route } from 'react-router-dom';
import { isAuthenticated } from '../utils/auth'; import { isAuthenticated } from '../utils/auth';
function PrivateRoute({path, children}) { function PrivateRoute({ path, children }) {
if (isAuthenticated()) { if (isAuthenticated()) {
return ( return (
<Route path={path}> <Route path={path}>
......
...@@ -15,8 +15,7 @@ function SubNav() { ...@@ -15,8 +15,7 @@ function SubNav() {
Object.keys(response.data[0]).forEach((ele) => { Object.keys(response.data[0]).forEach((ele) => {
const url = ele.toLowerCase() const url = ele.toLowerCase()
list.push( list.push(
<Nav.Link href={`/categories/${url}`}>{ele} <Nav.Link href={`/categories/${url}`}>{ele}</Nav.Link>
</Nav.Link>
) )
}) })
setCategoriesDiv(list) setCategoriesDiv(list)
......
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react';
import { Card, Image, Container, Row, Col, Button, Form, Modal } from 'react-bootstrap' import { Card, Image, Container, Row, Col, Button, Form, Modal } from 'react-bootstrap';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import axios from 'axios'; import axios from 'axios';
import catchError from '../utils/catchErrors'; import catchError from '../utils/catchErrors';
import { isAuthenticated } from '../utils/auth'; import { isAuthenticated } from '../utils/auth';
import OrderCard from '../Components/OrderCard';
const INIT_ACCOUNT = { const INIT_ACCOUNT = {
name: "", name: "",
...@@ -16,46 +17,37 @@ function Account() { ...@@ -16,46 +17,37 @@ function Account() {
const [proshow, setProshow] = useState(false) const [proshow, setProshow] = useState(false)
const [error, setError] = useState("") const [error, setError] = useState("")
const userId = isAuthenticated() const userId = isAuthenticated()
const [ordered, setOrdered] = useState('') const [ordered, setOrdered] = useState([])
async function getUsername(user) { async function getUsername(user) {
// console.log("tlg")
try { try {
const response = await axios.get(`/api/users/account/${user}`) const response = await axios.get(`/api/users/account/${user}`)
setAccount(response.data) setAccount(response.data)
console.log('555555555', response.data);
} catch (error) { } catch (error) {
catchError(error, setError) catchError(error, setError)
// console.log('error2222', error)
} }
} }
useEffect(() => { useEffect(() => {
getUsername(userId) getUsername(userId)
getOrdered(userId) getOrdered()
}, [userId]) }, [userId])
const handleChange = (event) => { const handleChange = (event) => {
const { name, value, files } = event.target const { name, value, files } = event.target
if (files) { if (files) {
for (const file of files) {
// console.log("name=", name, "value=", value, 'file=', file);
}
setAccount({ ...account, [name]: files }) setAccount({ ...account, [name]: files })
} else { } else {
console.log("name=", name, "value=", value);
setAccount({ ...account, [name]: value }) setAccount({ ...account, [name]: value })
} }
} }
const handleBasic = async (event) => { const handleBasic = async () => {
const formData = new FormData() const formData = new FormData()
formData.append('avatar', '') formData.append('avatar', '')
try { try {
if (userId) { if (userId) {
const response = await axios.put(`/api/users/account/${userId}`, formData) const response = await axios.put(`/api/users/account/${userId}`, formData)
console.log(response.data)
window.location.reload() window.location.reload()
} }
} catch (error) { } catch (error) {
...@@ -73,7 +65,6 @@ function Account() { ...@@ -73,7 +65,6 @@ function Account() {
try { try {
if (userId) { if (userId) {
const response = await axios.put(`/api/users/account/${userId}`, formData) const response = await axios.put(`/api/users/account/${userId}`, formData)
console.log(response.data)
window.location.reload() window.location.reload()
} }
} catch (error) { } catch (error) {
...@@ -84,18 +75,20 @@ function Account() { ...@@ -84,18 +75,20 @@ function Account() {
} }
} }
async function getOrdered({}) { async function getOrdered({ }) {
console.log("object")
try { try {
const response = await axios.get(`/api/users/addorder`) const response = await axios.post(`/api/users/addorder`, {
setOrdered(response.data) userId: userId
console.log('@@@@', response.data); })
const a = response.data
setOrdered(a)
console.log("what=", response.data)
} catch (error) { } catch (error) {
catchError(error, setError) catchError(error, setError)
} }
} }
return ( return (
<Container className="px-3"> <Container className="px-3">
<style type="text/css"> <style type="text/css">
...@@ -131,7 +124,6 @@ function Account() { ...@@ -131,7 +124,6 @@ function Account() {
<Col className="px-0"> <Col className="px-0">
<Button variant="outline-secondary" onClick={handleBasic} <Button variant="outline-secondary" onClick={handleBasic}
className="d-flex justify-content-start"><small>기본이미지로</small></Button> className="d-flex justify-content-start"><small>기본이미지로</small></Button>
{/* 기본이미지로 보내기 */}
</Col> </Col>
<Button variant="secondary" onClick={() => setShow(false)}>취소</Button> <Button variant="secondary" onClick={() => setShow(false)}>취소</Button>
<Button variant="primary" type="submit" onClick={() => setShow(false)}>저장</Button> <Button variant="primary" type="submit" onClick={() => setShow(false)}>저장</Button>
...@@ -147,7 +139,6 @@ function Account() { ...@@ -147,7 +139,6 @@ function Account() {
{account.name} {account.name}
</strong> </strong>
<Modal <Modal
size="sm" size="sm"
show={proshow} show={proshow}
onHide={() => setProshow(false)}> onHide={() => setProshow(false)}>
...@@ -185,12 +176,13 @@ function Account() { ...@@ -185,12 +176,13 @@ function Account() {
<a href="mailto:shoppingmall_KU@korea.ac.kr"> <a href="mailto:shoppingmall_KU@korea.ac.kr">
<small title="메일보내기"> * 문의 : shoppingmall_KU@korea.ac.kr </small> <small title="메일보내기"> * 문의 : shoppingmall_KU@korea.ac.kr </small>
</a> </a>
{/* 쇼핑몰 문의 메일보내기 */}
</Row> </Row>
</Col> </Col>
</Row> </Row>
</Card> </Card>
<Card>
<OrderCard ordered={ordered} />
</Card>
</Container > </Container >
) )
} }
......
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom'; import AllCard from '../Components/AllCard';
import ListCard from '../Components/ListCard'; import Pagination from "../Components/Pagination";
import Pagination from '../Components/Pagination';
import axios from 'axios'; import axios from 'axios';
import { isAdmin } from "../utils/auth";
import catchError from '../utils/catchErrors'; 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() { function Admin() {
const INIT_STATUS = { indexOfFirst: 0, indexOfLast: 10 }
const [search, setSearch] = useState({ word: '' })
const [productlist, setProductlist] = useState([]) const [productlist, setProductlist] = useState([])
const [status, setStatus] = useState(INIT_STATUS)
const [currentPage, setCurrentPage] = useState(1)
const [error, setError] = useState('') const [error, setError] = useState('')
const role = isAdmin() const searchref = useRef(null)
const per = 10;
useEffect(() => { useEffect(() => {
getProductlist() 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() { async function getProductlist() {
try { try {
setError('')
const response = await axios.get(`/api/product/getproduct/all`) const response = await axios.get(`/api/product/getproduct/all`)
console.log("response.data=", response.data)
setProductlist(response.data) setProductlist(response.data)
setCurrentPage(1)
} catch (error) { } catch (error) {
catchError(error, setError) catchError(error, setError)
} }
} }
function handleSearch() { function handleChange(event) {
setSearch({ word: event.target.value })
} }
function handleSubmit(e) { async function handleSubmit(e) {
e.preventDefault() 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) { if (error) {
alert('죄송합니다.접근 권한이 없습니다.') alert(`${error}`)
return <Redirect to="/" /> setError('')
searchref.current.value = ''
} }
return ( return (
...@@ -47,26 +72,34 @@ function Admin() { ...@@ -47,26 +72,34 @@ function Admin() {
background-color: #CDC5C2; background-color: #CDC5C2;
border-color: #CDC5C2; border-color: #CDC5C2;
} }
.btn:hover {
.btn:hover, .btn:active, .btn:focus { 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; background-color: #91877F;
border-color: #91877F; border-color: #91877F;
} }
`} `}
</style> </style>
<Row as={Form} onSubmit={handleSubmit} className="justify-content-end mx-0 my-5"> <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"> <Button type="submit" className="px-2">
<img src="icon/search.svg" width="20" height="20" /> <img src="icon/search.svg" width="20" height="20" />
</Button> </Button>
<Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button> <Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button>
</Row> </Row>
<Row className="justify-content-center m-5"> <Row className="justify-content-center m-5">
{productlist.map(pro => ( {currentPosts(productlist).map(pro => (
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} /> <AllCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
))} ))}
</Row> </Row>
<Pagination /> <Pagination index={currentPage} totalPages={Math.ceil(productlist.length / per)} handlePage={setCurrentPage} />
</Container> </Container>
) )
} }
......
...@@ -21,7 +21,6 @@ function Home() { ...@@ -21,7 +21,6 @@ function Home() {
async function getProductlist() { async function getProductlist() {
try { try {
const response = await axios.get(`/api/product/getproduct`) const response = await axios.get(`/api/product/getproduct`)
console.log("res=", response.data)
setProductlist({ bestProduct: response.data.bestProduct, newProduct: response.data.newProduct }) setProductlist({ bestProduct: response.data.bestProduct, newProduct: response.data.newProduct })
} catch (error) { } catch (error) {
catchError(error, setError) catchError(error, setError)
......
...@@ -10,9 +10,7 @@ const INIT_USER = { ...@@ -10,9 +10,7 @@ const INIT_USER = {
id: '', id: '',
password: '' password: ''
} }
function Login() { function Login() {
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER) const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('') const [error, setError] = useState('')
...@@ -33,7 +31,7 @@ function Login() { ...@@ -33,7 +31,7 @@ function Login() {
setValidated(true); setValidated(true);
try { try {
setError('') setError('')
const response=await axios.post('/api/auth/login', user) const response = await axios.post('/api/auth/login', user)
handleLogin(response.data) handleLogin(response.data)
setSuccess(true) setSuccess(true)
} catch (error) { } catch (error) {
...@@ -43,7 +41,7 @@ function Login() { ...@@ -43,7 +41,7 @@ function Login() {
if (success) { if (success) {
alert('로그인 되었습니다.') alert('로그인 되었습니다.')
window.location.href='/' window.location.href = '/'
} }
return ( return (
...@@ -72,7 +70,6 @@ function Login() { ...@@ -72,7 +70,6 @@ function Login() {
<Form.Control.Feedback className="text-center" type="invalid"> 아이디를 입력하세요.</Form.Control.Feedback> <Form.Control.Feedback className="text-center" type="invalid"> 아이디를 입력하세요.</Form.Control.Feedback>
</Form.Row> </Form.Row>
</Form.Group> </Form.Group>
<Form.Group controlId="formBasicPassword"> <Form.Group controlId="formBasicPassword">
<Form.Row> <Form.Row>
<Col sm={4} xs={6} as={Form.Label} for="password">비밀번호</Col> <Col sm={4} xs={6} as={Form.Label} for="password">비밀번호</Col>
......
import axios from 'axios';
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Redirect, Link, useHistory } from 'react-router-dom';
import DaumPostcode from "react-daum-postcode"; 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 PaymentCard from '../Components/PaymentCard';
import axios from 'axios';
import { isAuthenticated } from '../utils/auth'; import { isAuthenticated } from '../utils/auth';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
import { Container, Row, Col, Button, Form } from 'react-bootstrap';
function Payment({ match, location }) { function Payment({ match, location }) {
const [cart, setCart] = useState([]) const [cart, setCart] = useState([])
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,35 @@ function Payment({ match, location }) { ...@@ -39,15 +38,35 @@ 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)
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
})
const preCart = response.data.products.filter((el) => el.checked === true)
setCart(preCart) setCart(preCart)
setOrder({ products: preCart }) setOrder({ products: preCart })
} catch (error) { } catch (error) {
...@@ -57,7 +76,6 @@ function Payment({ match, location }) { ...@@ -57,7 +76,6 @@ function Payment({ match, location }) {
function handleReceiverInfo(e) { function handleReceiverInfo(e) {
const { name, value } = e.target const { name, value } = e.target
console.log(name, value)
setOrder({ ...order, receiverInfo: { ...order.receiverInfo, [name]: value } }) setOrder({ ...order, receiverInfo: { ...order.receiverInfo, [name]: value } })
} }
...@@ -77,11 +95,9 @@ function Payment({ match, location }) { ...@@ -77,11 +95,9 @@ function Payment({ match, location }) {
const handleComplete = (data) => { const handleComplete = (data) => {
let fullAddress = data.address; let fullAddress = data.address;
let extraAddress = ""; let extraAddress = "";
console.log(data)
if (data.addressType === "R") { if (data.addressType === "R") {
if (data.bname !== "") { if (data.bname !== "") {
extraAddress += data.bname; extraAddress += data.bname;
console.log(extraAddress)
} }
if (data.buildingName !== "") { if (data.buildingName !== "") {
extraAddress += extraAddress +=
...@@ -105,9 +121,9 @@ function Payment({ match, location }) { ...@@ -105,9 +121,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 +153,15 @@ function Payment({ match, location }) { ...@@ -137,34 +153,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 +172,7 @@ function Payment({ match, location }) { ...@@ -175,6 +172,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,120 +185,141 @@ function Payment({ match, location }) { ...@@ -187,120 +185,141 @@ 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> <Container>
{/* {console.log(order)} */} <h3 className="my-5 font-weight-bold text-center">주문/결제</h3>
<Container> <div>
<h3 className="my-5 font-weight-bold text-center">주문/결제</h3> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5>
<div> <Row className="justify-content-md-center">
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5> <Col md={4}>
<Row className="justify-content-md-center"> <Form>
<Col md={4}> <Form.Group controlId="formBasicName">
<Form> <Form.Label>이름</Form.Label>
<Form.Group controlId="formBasicName"> <Form.Control type="text" value={userData.name} readOnly />
<Form.Label>이름</Form.Label> </Form.Group>
<Form.Control type="text" value={userData.name} readOnly /> <Form.Group controlId="formBasicTel">
</Form.Group> <Form.Label>휴대전화</Form.Label>
<Form.Group controlId="formBasicTel"> <Form.Control type="tel" value={userData.tel} readOnly />
<Form.Label>휴대전화</Form.Label> </Form.Group>
<Form.Control type="tel" value={userData.tel} readOnly /> <Form.Group controlId="formBasicEmail">
</Form.Group> <Form.Label>이메일</Form.Label>
<Form.Group controlId="formBasicEmail"> <Form.Control type="email" value={userData.email} readOnly />
<Form.Label>이메일</Form.Label> </Form.Group>
<Form.Control type="email" placeholder="이메일 주소를 입력해주세요" /> </Form>
</Form.Group> </Col>
</Form> </Row>
</Col> </div>
</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">
<div> <Col md={8}>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>받는사람 정보</h5> <Form>
<Row className="justify-content-center"> <Form.Group>
<Col md={8}> <Form.Label>이름</Form.Label>
<Form> <Form.Control type="text" name="name" onChange={handleReceiverInfo}></Form.Control>
<Form.Group> </Form.Group>
<Form.Label>이름</Form.Label> <Form.Group>
<Form.Control type="text" name="name" onChange={handleReceiverInfo}></Form.Control> <Form.Label>휴대전화</Form.Label>
</Form.Group> <Form.Control type="text" name="tel" onChange={handleReceiverInfo}></Form.Control>
<Form.Group> </Form.Group>
<Form.Label>휴대전화</Form.Label> <Form.Group controlId="formBasicAdd">
<Form.Control type="text" name="tel" onChange={handleReceiverInfo}></Form.Control> <Form.Label>주소</Form.Label>
</Form.Group> <Form.Row>
<Form.Group controlId="formBasicAdd"> <Col xs={4} sm={4}>
<Form.Label>주소</Form.Label> <Form.Control type="text" name="postalCode" id="add" onChange={handleReceiverInfo} value={address.code} disabled={(address.code == null) ? false : true} placeholder="우편번호" required ></Form.Control>
<Form.Row> </Col>
<Col xs={4} sm={4}> <Col >
<Form.Control type="text" name="postalCode" id="add" onChange={handleReceiverInfo} value={address.code} disabled={(address.code == null) ? false : true} placeholder="우편번호" required ></Form.Control> <Button style={{ background: '#91877F', borderColor: '#91877F' }} className="mx-1" onClick={postClick}>우편번호</Button>
</Col> {post}
<Col > </Col>
<Button style={{ background: '#91877F', borderColor: '#91877F' }} className="mx-1" onClick={postClick}>우편번호</Button> </Form.Row>
{post} <Form.Row>
</Col> <Col>
</Form.Row> <Form.Control type="text" name="address" id="add1" onChange={handleReceiverInfo} value={address.full} disabled={(address.code == null) ? false : true} placeholder="주소" required></Form.Control>
<Form.Row> <Form.Control type="text" name="address2" id="add2" onChange={handleReceiverInfo} placeholder="상세주소" required></Form.Control>
<Col> <Form.Control.Feedback type="invalid" > 상세 주소를 입력하세요. </Form.Control.Feedback>
<Form.Control type="text" name="address" id="add1" onChange={handleReceiverInfo} value={address.full} disabled={(address.code == null) ? false : true} placeholder="주소" required></Form.Control> </Col>
<Form.Control type="text" name="address2" id="add2" onChange={handleReceiverInfo} placeholder="상세주소" required></Form.Control> </Form.Row>
<Form.Control.Feedback type="invalid" > 상세 주소를 입력하세요. </Form.Control.Feedback> </Form.Group>
</Col> </Form>
</Form.Row> </Col>
</Form.Group> </Row>
</Form> </div>
</Col> <div>
</Row> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5>
</div> <PaymentCard cart={cart} deleteOrder={deleteOrder} />
</div>
<div> <div className="p-5 m-3" style={{ background: '#F7F3F3' }}>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5> <ul className="pl-0" style={{ listStyle: 'none' }}>
<PaymentCard cart={cart} /> <li>
</div> <span className="text-secondary"> 상품금액</span>
<span className="text-secondary float-right">{finalPrice}</span>
<div className="p-5 m-3" style={{ background: '#F7F3F3' }}> </li>
<ul className="pl-0" style={{ listStyle: 'none' }}> <li>
<li> <span className="text-secondary">배송비</span>
<span className="text-secondary"> 상품금액</span> <span className="text-secondary float-right">2500</span>
<span className="text-secondary float-right">{finalPrice}</span> </li>
</li> </ul>
<li> <div className="my-1 pt-2 border-top font-weight-bold">
<span className="text-secondary">배송비</span> 결제금액<span className="float-right">{finalPrice + 2500}</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> </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> {paymentWay}
</div> </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 React, { useState, useEffect, useRef } from 'react';
import { Row, Col, Form, Card, Button, Image } from 'react-bootstrap'; import { Redirect, useHistory } from 'react-router-dom';
import { Redirect } from 'react-router-dom'; import axios from 'axios';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
import { Row, Col, Form, Card, Button, Modal, Image } from 'react-bootstrap';
function Product({ match, location }) { function Product({ match, location }) {
...@@ -14,14 +14,16 @@ function Product({ match, location }) { ...@@ -14,14 +14,16 @@ 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\n}', '<br />') const replace = product.description.replaceAll('{\n\n}', '<br />')
console.log("replaceALL Description= ", replace)
useEffect(() => { useEffect(() => {
if (size && color) { if (size && color) {
pushOptions() pushOptions()
console.log(cart) // console.log(cart)
} }
}, [size, color]) }, [size, color])
...@@ -31,13 +33,29 @@ function Product({ match, location }) { ...@@ -31,13 +33,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) {
...@@ -79,20 +97,42 @@ function Product({ match, location }) { ...@@ -79,20 +97,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' />
...@@ -102,7 +142,6 @@ function Product({ match, location }) { ...@@ -102,7 +142,6 @@ function Product({ match, location }) {
return ( return (
<div> <div>
{console.log(cart)}
<style type="text/css"> <style type="text/css">
{` {`
.btn { .btn {
...@@ -116,6 +155,16 @@ function Product({ match, location }) { ...@@ -116,6 +155,16 @@ function Product({ match, location }) {
} }
`} `}
</style> </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"> <Row className="justify-content-center mt-5 mx-0">
<Col sm={11} md={4}> <Col sm={11} md={4}>
<img src={`/images/${product.main_img}`} style={{ objectFit: "contain", width: "100%" }} /> <img src={`/images/${product.main_img}`} style={{ objectFit: "contain", width: "100%" }} />
...@@ -157,8 +206,8 @@ function Product({ match, location }) { ...@@ -157,8 +206,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>
......
...@@ -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,23 +73,15 @@ function ProductsRegist() { ...@@ -90,23 +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) {
// console.log("e.name=",e.target.name) console.log(product.colors)
e.target.parentNode.remove() console.log(e.target.name)
product["colors"].splice(e.name, 1) const pdcolors = product.colors.filter((el) => el !== e.target.name)
// setColor({}) setProduct({ ...product, "colors": pdcolors })
// console.log(product)
} }
function handleColor(e) { function handleColor(e) {
...@@ -134,13 +109,13 @@ function ProductsRegist() { ...@@ -134,13 +109,13 @@ function ProductsRegist() {
console.log(product) console.log(product)
const formData = new FormData(); const formData = new FormData();
for (let key in product) { for (let key in product) {
if (key === "main_image" || key === "detail_image") { if (key === "main_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" || key === "detail_image") {
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])
} }
...@@ -165,6 +140,7 @@ function ProductsRegist() { ...@@ -165,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>}
...@@ -201,11 +177,15 @@ function ProductsRegist() { ...@@ -201,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>
...@@ -238,14 +218,21 @@ function ProductsRegist() { ...@@ -238,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>
...@@ -257,7 +244,7 @@ function ProductsRegist() { ...@@ -257,7 +244,7 @@ function ProductsRegist() {
</Form.Group> </Form.Group>
<Form.Group> <Form.Group>
<Form.Label>상세이미지</Form.Label> <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> </Form.Group>
<Button type="submit" style={{ background: '#91877F', borderColor: '#91877F' }} block> <Button type="submit" style={{ background: '#91877F', borderColor: '#91877F' }} block>
{loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />}{' '}등록 {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