Commit b2494d11 authored by kusang96's avatar kusang96
Browse files

Merge branch 'kimpen' into ourMaster

parents 333e946e 34c5f591
......@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { isAdmin } from '../utils/auth';
function PrivateRoute({path, children}) {
function PrivateRoute({ path, children }) {
if (isAdmin()) {
return (
<Route path={path}>
......
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 }) {
function handleDelete(e) {
const card = e.target.parentNode.parentNode
alert('해당 상품을 성공적으로 삭제하였습니다.')
card.remove()
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} className="m-3" style={{ width: "18rem" }}>
<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>
......
......@@ -2,38 +2,36 @@ import React from 'react'
import { Card, Row, Col } from 'react-bootstrap';
function CartCard(props) {
console.log(props)
return (
<>
{props.cart.map((e) => (
<Card>
<Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteCart} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text className="mb-0">가격: {e.productId.price}</Card.Text>
<Card.Text className="mb-0">옵션: {e.size}/{e.color}</Card.Text>
<Card.Text >수량</Card.Text>
<div>
<input type="image" name={String(e._id)} alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={props.minusNum} />
<input type="number" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
<input type="image" name={String(e._id)} alt="플러스" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={props.plusNum} />
</div>
</Card.Body>
</Col>
</Row>
</Card>
))
<Card>
<Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" name={String(e._id)} onChange={props.checkedCart} />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_imgUrl && `/images/${e.productId.main_imgUrl}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteCart} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text className="mb-0">가격: {e.productId.price}</Card.Text>
<Card.Text className="mb-0">옵션: {e.size}/{e.color}</Card.Text>
<Card.Text >수량</Card.Text>
<div>
<input type="image" name={String(e._id)} alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={props.minusNum} />
<input type="number" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
<input type="image" name={String(e._id)} alt="플러스" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={props.plusNum} />
</div>
</Card.Body>
</Col>
</Row>
</Card>
))
}
</>
)
}
......
import React, { useState, useEffect, useRef } from 'react';
import { Card, Button } from 'react-bootstrap';
import React from 'react';
import { Card } from 'react-bootstrap';
function ListCard({ id, name, price, main_img }) {
function handleDelete(e) {
const card = e.target.parentNode.parentNode
alert('해당 상품을 성공적으로 삭제하였습니다.')
card.remove()
}
return (
<Card id={id} className="m-3" style={{ width: "18rem" }}>
......
......@@ -21,7 +21,7 @@ function MainNav() {
<img alt="카트" src="/icon/cart.svg" width="30" height="30" />
</Nav.Link>
</>
: (
: (
<>
<Nav.Link className="text-light" href='/login'>Login</Nav.Link>
<Nav.Link className="text-light" href='/signup'>Sign Up</Nav.Link>
......
import { Pagination } from "react-bootstrap";
import React from 'react';
function Paginations({ index, endPage, handlePage }) {
function Paginations({ index, totalPages, handlePage }) {
return (
<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 === endPage-1 ? <Pagination.Item onClick={()=>handlePage(index - 3)}>{index - 3}</Pagination.Item> : ""}
{index === endPage ? <Pagination.Item onClick={()=>handlePage(index - 4)}>{index - 4}</Pagination.Item> : ""}
{index === endPage ? <Pagination.Item onClick={()=>handlePage(index - 3)}>{index - 3}</Pagination.Item> : ""}
{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 === endPage ? "" : <Pagination.Item onClick={()=>handlePage(index + 1)}>{index + 1}</Pagination.Item>}
{index > endPage-2 ? "" : <Pagination.Item onClick={()=>handlePage(index + 2)}>{index + 2}</Pagination.Item>}
{index === 1 ? <Pagination.Item onClick={()=>handlePage(index + 3)}>{index + 3}</Pagination.Item> : ""}
{index === 1 ? <Pagination.Item onClick={()=>handlePage(index + 4)}>{index + 4}</Pagination.Item> : ""}
{index === 2 ? <Pagination.Item onClick={()=>handlePage(index + 3)}>{index + 3}</Pagination.Item> : ""}
{index === endPage ? "" : <Pagination.Next onClick={()=>handlePage(index + 1)} />}
{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(endPage)} />
<Pagination.Last onClick={() =>handlePage(totalPages)} />
</Pagination>
)
}
......
......@@ -2,7 +2,7 @@ import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { isAuthenticated } from '../utils/auth';
function PrivateRoute({path, children}) {
function PrivateRoute({ path, children }) {
if (isAuthenticated()) {
return (
<Route path={path}>
......
import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom';
import AllCard from '../Components/AllCard';
import Pagination from "../Components/Pagination";
import axios from 'axios';
......@@ -11,38 +10,31 @@ function Admin() {
const [search, setSearch] = useState({ word: '' })
const [productlist, setProductlist] = useState([])
const [status, setStatus] = useState(INIT_STATUS)
const [currentPage, setCurrentPage] = useState(1);
const [per, setPer] = useState(10);
const [currentPage, setCurrentPage] = useState(1)
const [error, setError] = useState('')
const searchref = useRef(null)
const indexOfLast = currentPage * per;
const indexOfFirst = indexOfLast - per;
const per = 10;
useEffect(() => {
getProductlist()
}, [])
function paginate(items, index, itemNumber) {
const posts = [];
const startIndex = (index - 1) * itemNumber
for (var i = 0; i < itemNumber; i++) {
posts.push(items[(startIndex + i)])
}
return posts
}
useEffect(() => {
setStatus({ indexOfFirst: (currentPage - 1) * per, indexOfLast: currentPage * per })
}, [currentPage])
function currentPosts(tmp) {
function currentPosts(items) {
let currentPosts = 0;
currentPosts = tmp.slice(indexOfFirst, indexOfLast);
console.log("postsPerPage=",currentPage)
return currentPosts;
currentPosts = items.slice(status.indexOfFirst, status.indexOfLast);
return currentPosts
}
async function getProductlist() {
try {
setError('')
const response = await axios.get(`/api/product/getproduct/all`)
console.log("response.data=", response.data)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
}
......@@ -57,8 +49,8 @@ function Admin() {
try {
setError('')
const response = await axios.get(`/api/product/getproduct/all?product=${search.word}`)
console.log("response.data=", response.data)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
} finally {
......@@ -80,8 +72,16 @@ function Admin() {
background-color: #CDC5C2;
border-color: #CDC5C2;
}
.btn:hover, .btn:active, .btn:focus {
.btn:hover {
background-color: #91877F;
border-color: #91877F;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #91877F;
border-color: #91877F;
box-shadow: 0 0 0 0;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .show>.btn-primary.dropdown-toggle {
background-color: #91877F;
border-color: #91877F;
}
......@@ -99,7 +99,7 @@ function Admin() {
<AllCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
))}
</Row>
<Pagination index={currentPage} totalPosts={Math.ceil(productlist.length / per)} handlePage={setCurrentPage} />
<Pagination index={currentPage} totalPages={Math.ceil(productlist.length / per)} handlePage={setCurrentPage} />
</Container>
)
}
......
......@@ -11,7 +11,6 @@ const INIT_USER = {
password: ''
}
function Login() {
const [validated, setValidated] = useState(false);
const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('')
......@@ -71,7 +70,6 @@ function Login() {
<Form.Control.Feedback className="text-center" type="invalid"> 아이디를 입력하세요.</Form.Control.Feedback>
</Form.Row>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Row>
<Col sm={4} xs={6} as={Form.Label} for="password">비밀번호</Col>
......
import axios from 'axios';
import React, { useState, useEffect, useRef } from 'react';
import DaumPostcode from "react-daum-postcode";
import { Container, Row, Col, Button, Form } from 'react-bootstrap';
import { Redirect, Link, useHistory } from 'react-router-dom';
import DaumPostcode from "react-daum-postcode";
import PaymentCard from '../Components/PaymentCard';
import axios from 'axios';
import { isAuthenticated } from '../utils/auth';
import catchErrors from '../utils/catchErrors';
import { Container, Row, Col, Button, Form } from 'react-bootstrap';
function Payment({ match, location }) {
const [cart, setCart] = useState([])
......@@ -46,7 +46,6 @@ function Payment({ match, location }) {
try {
setError('')
const response = await axios.get(`/api/cart/showcart/${user}`)
console.log(response.data)
const preCart = response.data.filter((el) => el.checked === true)
if (preCart.length) {
setCart(preCart)
......@@ -67,7 +66,6 @@ function Payment({ match, location }) {
userId: user,
cartId: e.target.name
})
console.log(response.data)
const preCart = response.data.products.filter((el) => el.checked === true)
setCart(preCart)
setOrder({ products: preCart })
......@@ -78,7 +76,6 @@ function Payment({ match, location }) {
function handleReceiverInfo(e) {
const { name, value } = e.target
console.log(name, value)
setOrder({ ...order, receiverInfo: { ...order.receiverInfo, [name]: value } })
}
......@@ -98,11 +95,9 @@ function Payment({ match, location }) {
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = "";
console.log(data)
if (data.addressType === "R") {
if (data.bname !== "") {
extraAddress += data.bname;
console.log(extraAddress)
}
if (data.buildingName !== "") {
extraAddress +=
......
......@@ -7,23 +7,17 @@ import catchError from '../utils/catchErrors';
import { Container, Row, Col, Form, FormControl, Button, Dropdown, ButtonGroup, Image } from 'react-bootstrap';
function ProductsList({ match }) {
const INIT_STATUS = { indexOfFirst: 0, indexOfLast: 10 }
const [search, setSearch] = useState({ word: '' })
const [sortingName, setSortingName] = useState('정렬')
const [mainCategory, setMainCategory] = useState(match.params.main.toUpperCase())
const [subCategory, setSubCategory] = useState([])
const [productlist, setProductlist] = useState([])
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage, setPostsPerPage] = useState(6);
const [status, setStatus] = useState(INIT_STATUS)
const [currentPage, setCurrentPage] = useState(1)
const [error, setError] = useState('')
const indexOfLast = currentPage * postsPerPage;
const indexOfFirst = indexOfLast - postsPerPage;
const searchref = useRef(null)
function currentPosts(tmp) {
let currentPosts = 0;
currentPosts = tmp.slice(indexOfFirst, indexOfLast);
return currentPosts;
}
const per = 10;
useEffect(() => {
setMainCategory(match.params.main.toUpperCase())
......@@ -35,6 +29,16 @@ function ProductsList({ match }) {
getProductlist()
}, [mainCategory])
useEffect(() => {
setStatus({ indexOfFirst: (currentPage - 1) * per, indexOfLast: currentPage * per })
}, [currentPage])
function currentPosts(items) {
let currentPosts = '';
currentPosts = items.slice(status.indexOfFirst, status.indexOfLast);
return currentPosts
}
function handleChange(event) {
setSearch({ word: event.target.value })
}
......@@ -44,8 +48,8 @@ function ProductsList({ match }) {
try {
setError('')
const response = await axios.get(`/api/product/getproduct/main/${mainCategory}?product=${search.word}`)
console.log("response.data=", response.data)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
} finally {
......@@ -58,7 +62,6 @@ function ProductsList({ match }) {
setError('')
const response = await axios.get(`/api/categories/sub/${mainCategory}`)
setSubCategory(Object.values(response.data)[0])
console.log("object value=", Object.values(response.data));
} catch (error) {
catchError(error, setError)
}
......@@ -69,6 +72,7 @@ function ProductsList({ match }) {
setError('')
const response = await axios.get(`/api/product/getproduct/main/${mainCategory}`)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
}
......@@ -136,9 +140,10 @@ function ProductsList({ match }) {
async function handleSubname(e) {
const subname = e.target.name
try {
setError('')
const response = await axios.get(`/api/product/getproduct/sub?subname=${subname}`)
console.log("subname response data=", response.data)
setProductlist(response.data)
setCurrentPage(1)
} catch (error) {
catchError(error, setError)
}
......@@ -161,11 +166,23 @@ function ProductsList({ match }) {
.btn {
background-color: #CDC5C2;
border-color: #CDC5C2;
border-radius: 0;
}
.btn:hover, .btn:focus {
background-color: #91877F;
border-color: #91877F;
box-shadow: 0 0 0 0;
}
.btn:hover {
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .show>.btn-primary.dropdown-toggle {
background-color: #91877F;
border-color: #91877F;
}
.show>.btn-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0;
}
.dropdown-item {
color: #91877F;
}
.dropdown-item:hover, .dropdown-item:active {
background-color: #91877F;
color: #fff;
......@@ -177,15 +194,20 @@ function ProductsList({ match }) {
<div className="text-center">
<h1 style={{ fontSize: "5.5vmax" }} className="text-center m-1 py-3">{mainCategory}</h1>
<ButtonGroup className="mb-3" style={{ display: "inline" }}>
{subCategory.map(el =>
(<Button className="m-1" style={{ fontSize: "0.8vw" }} name={el} onClick={handleSubname}>{el}</Button>))}
{subCategory.map(el =>(<Button className="m-1" style={{ fontSize: "0.8vw" }} name={el} onClick={handleSubname}>{el}</Button>))}
</ButtonGroup>
</div>
</Col>
</Row>
<Row className="justify-content-end mx-0 mt-5 mb-3">
<Dropdown>
<Dropdown.Toggle className="mx-2">정렬</Dropdown.Toggle>
<Form inline onSubmit={handleSearch} className="justify-content-end mx-0 my-2">
<FormControl ref={searchref} type="text" onChange={handleChange} placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="px-2 mr-2">
<img src="/icon/search.svg" width="20" height="20" />
</Button>
</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>
......@@ -193,16 +215,10 @@ function ProductsList({ match }) {
<Dropdown.Item as="button" onClick={() => handleSort('highest')}>높은가격</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Form inline onSubmit={handleSearch} className="justify-content-end mx-0 my-2">
<FormControl ref={searchref} type="text" onChange={handleChange} placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="px-2 mr-2">
<img src="/icon/search.svg" width="20" height="20" />
</Button>
</Form>
</Row>
<Row md={8} sm={12} className="justify-content-center m-2">
{productlist.length > 0 ?
productlist.map(pro => (
currentPosts(productlist).map(pro => (
<Link to={{
pathname: `/product/${pro._id}`,
state: {
......@@ -226,6 +242,7 @@ function ProductsList({ match }) {
)
}
</Row>
{productlist.length != 0 ? <Pagination index={currentPage} totalPages={Math.ceil(productlist.length / per)} handlePage={setCurrentPage} /> : ''}
</Container>
)
}
......
......@@ -9,7 +9,6 @@ const imageUpload = upload.fields([
])
const regist = async (req, res) => {
console.log("req.body=", req.body)
try {
const { pro_name, price, stock, main_category, sub_category, description, colors, sizes } = req.body
const main_img = req.files['main_image'][0]
......@@ -24,7 +23,6 @@ const regist = async (req, res) => {
}).save()
res.json(newProduct)
} catch (error) {
console.log(error)
res.status(500).send('제품 정보 등록에 실패하였습니다. 다시 진행해 주십시오.')
}
}
......@@ -33,8 +31,6 @@ const getToHome = async (req, res) => {
try {
const bestProduct = await Product.find({}).sort({ purchase: -1 }).limit(6)
const newProduct = await Product.find({}).sort({ createdAt: -1 }).limit(6)
// console.log("best=", bestProduct)
// console.log("new=", newProduct)
res.json({ bestProduct, newProduct })
} catch {
res.status(500).send('상품을 불러오지 못했습니다.')
......@@ -69,7 +65,6 @@ const getlist = (req, res) => {
const categoryId = async (req, res, next, category) => {
console.log("req=", req.query.product)
try {
if (req.query.product) {
const productslist = await Product.find({ main_category: category, pro_name: { $regex: new RegExp(req.query.product) } })
......@@ -89,13 +84,11 @@ const categoryId = async (req, res, next, category) => {
}
const subname = async (req, res) => {
console.log("req.query", req.query)
try {
const findSubname = await Product.find({ sub_category: req.query.subname })
console.log("findSubname111=", findSubname)
res.send(findSubname)
} catch (error) {
res.send('상품을 불러오지 못했습니다.')
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
......@@ -111,11 +104,12 @@ const plusPurchase = async (req, res) => {
const stock = product.stock
await Product.updateOne(
{ _id: products[i].productId._id },
{ $set:
{
purchase: count + purchase,
stock: stock - count
}
{
$set:
{
purchase: count + purchase,
stock: stock - count
}
}
)
}
......@@ -125,4 +119,17 @@ const plusPurchase = async (req, res) => {
}
}
export default { imageUpload, regist, getToHome, getAll, categoryId, getlist, subname, plusPurchase }
\ No newline at end of file
const deletePro = async (req, res) => {
const pro_id = req.query.pro_id
try {
const productOne = await Product.findById(pro_id)
if (productOne) {
await Product.remove({ _id: pro_id })
}
res.send('삭제 성공')
} catch (error) {
res.status(500).send('삭제할 상품을 찾지 못하거나 삭제 중 문제가 발생했습니다.')
}
}
export default { imageUpload, regist, getToHome, getAll, categoryId, getlist, subname, plusPurchase, deletePro }
\ No newline at end of file
......@@ -22,7 +22,9 @@ router.route('/getproduct/sub')
router.route('/pluspurchase')
.post(productCtrl.plusPurchase)
router.route('/delete')
.delete(productCtrl.deletePro)
router.param('category', productCtrl.categoryId)
// router.param('subname',productCtrl.subcategoryId)
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