Commit 0912b817 authored by kusang96's avatar kusang96
Browse files

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

parents be0a7340 cbd30cd3
...@@ -13,11 +13,9 @@ import Account from './Pages/Account'; ...@@ -13,11 +13,9 @@ 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';
function App() { function App() {
return ( return (
<div>
<Router> <Router>
<MainNav /> <MainNav />
<SubNav /> <SubNav />
...@@ -25,8 +23,8 @@ function App() { ...@@ -25,8 +23,8 @@ function App() {
<Route exact path="/" component={Home} /> <Route exact path="/" component={Home} />
<Route path="/login" component={Login} /> <Route path="/login" component={Login} />
<Route path="/signup" component={Signup} /> <Route path="/signup" component={Signup} />
{/* <Route path="/product" component={Product} /> */} <Route path="/products/:productId" component={Product} />
<Route path="/product/:product" component={ProductsList} /> <Route path="/categories/:main" component={ProductsList} />
<Route path="/admin" component={Admin} /> <Route path="/admin" component={Admin} />
<Route path="/regist" component={ProductRegist} /> <Route path="/regist" component={ProductRegist} />
<Route path="/shoppingcart" component={ShoppingCart} /> <Route path="/shoppingcart" component={ShoppingCart} />
...@@ -36,10 +34,7 @@ function App() { ...@@ -36,10 +34,7 @@ function App() {
<Redirect path="/" to="/" /> <Redirect path="/" to="/" />
</Switch> </Switch>
</Router> </Router>
</div>
) )
} }
export default App; export default App;
\ No newline at end of file
import React, { useState, useEffect, useRef } from 'react';
function card(props) {
const [card, setCard] = useState([...props])
return (
<Card className="mt-5">
<Card.Img varient="top" src={} style={{ objectFit: "contain", height: "22rem" }}></Card.Img>
<Card.Body>
<Card.Title></Card.Title>
<Card.Text></Card.Text>
<Card.Text></Card.Text>
</Card.Body>
</Card>
)
}
export default card
\ No newline at end of file
import React from 'react'
import { Card, Button, Container, Row, Col } from 'react-bootstrap';
function CartCard(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" id="exampleCheck1" />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src={e.productId.main_image && `/images/${e.productId.main_image}`} style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" name={String(e._id)} alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={props.deleteCart} />
<Card.Title className="font-weight-bold mt-3">{e.productId.pro_name}</Card.Title>
<Card.Text>가격: {e.productId.price}</Card.Text>
<Card.Text>옵션: {e.sizes}/{e.colors}</Card.Text>
<Card.Text>수량</Card.Text>
<div>
<input type="image" alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={props.minusNum} />
<input type="text" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder={e.count} value={e.count} readOnly></input>
<input type="image" 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>
))
}
</>
)
}
export default CartCard
import React, { useState, useEffect, useRef } from 'react';
import { Card } from 'react-bootstrap';
function ListCard({ id, name, price, main_img }) {
return (
<Card id={id} className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<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>
</Card.Body>
</Card>
)
}
export default ListCard
\ No newline at end of file
import React from 'react'; import React from 'react';
import { Navbar, Nav } from 'react-bootstrap'; import { Navbar, Nav } from 'react-bootstrap';
import { handleLogout, isAuthenticated } from '../utils/auth' import { handleLogout, isAuthenticated } from '../utils/auth';
function MainNav() { function MainNav() {
const user = isAuthenticated() const user = isAuthenticated()
...@@ -8,7 +8,7 @@ function MainNav() { ...@@ -8,7 +8,7 @@ function MainNav() {
return ( return (
<Navbar sticky="top" style={{ background: "#CDC5C2" }}> <Navbar sticky="top" style={{ background: "#CDC5C2" }}>
<Navbar.Brand href="/home" className="text-light"> <Navbar.Brand href="/home" className="text-light">
<img alt="로고" src="icon/footprint.svg" width="24" height="24" /> <img alt="로고" src="/icon/footprint.svg" width="24" height="24" />
{' '}KU# {' '}KU#
</Navbar.Brand> </Navbar.Brand>
<Nav> <Nav>
...@@ -20,10 +20,10 @@ function MainNav() { ...@@ -20,10 +20,10 @@ function MainNav() {
</> </>
)} )}
<Nav.Link href="/shoppingcart"> <Nav.Link href="/shoppingcart">
<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 href="/admin"> <Nav.Link href="/admin">
<img alt="관리자" src="icon/option.svg" width="30" height="30" /> <img alt="관리자" src="/icon/option.svg" width="30" height="30" />
</Nav.Link> </Nav.Link>
</Nav> </Nav>
</Navbar> </Navbar>
......
...@@ -16,7 +16,7 @@ function SubNav() { ...@@ -16,7 +16,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 as={Link} to={`/product/${url}`}>{ele}</Nav.Link> <Nav.Link as={Link} to={`/categories/${url}`}>{ele}</Nav.Link>
) )
}) })
setCategorysDiv(list) setCategorysDiv(list)
......
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import ListCard from '../Components/ListCard';
import axios from 'axios';
import catchError from '../utils/catchErrors';
import { Card, Container, Row } from 'react-bootstrap'; import { Card, Container, Row } from 'react-bootstrap';
function Home() { function Home() {
const [productlist, setProductlist] = useState([])
const [error, setError] = useState('')
useEffect(() => {
getProductlist()
}, [])
async function getProductlist() {
try {
const response = await axios.get(`/api/product/getproduct`)
console.log(response.data)
setProductlist(response.data)
} catch (error) {
catchError(error, setError)
}
}
return ( return (
<div> <div>
...@@ -12,43 +29,44 @@ function Home() { ...@@ -12,43 +29,44 @@ function Home() {
<div className="my-4"> <div className="my-4">
<h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem" }}><u>Best</u></h2> <h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem" }}><u>Best</u></h2>
<Row className="justify-content-center mx-0"> <Row className="justify-content-center mx-0">
<ListCard productlist={productlist} />
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}> <Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" /> <Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body> <Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title> <Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
......
...@@ -3,32 +3,57 @@ import React, { useState, useEffect, useRef } from 'react'; ...@@ -3,32 +3,57 @@ import React, { useState, useEffect, useRef } from 'react';
import { Row, Col, Form, Card, Button } from 'react-bootstrap'; import { Row, Col, Form, Card, Button } from 'react-bootstrap';
import catchErrors from '../utils/catchErrors'; import catchErrors from '../utils/catchErrors';
function Product() { const INIT_PRODUCT = {
const [product, setProduct] = useState() pro_name: '스키니진',
const [select, setSelect] = useState({ color: "", size: "" }) price: 12000,
const [cart, setCart] = useState() count: 1,
const [error, setError] = useState('') main_category: 'PANTS',
sub_category: ['SKINNY JEANS'],
sizes: ['L', 'M'],
colors: ['연청', '진청'],
main_image: "a8f4d63ead77717f940a2b27deb707a6",
productId:"5ffda03428faf35de8319360"
}
const preCart = []
function Product({ match, location }) {
const [product, setProduct] = useState(INIT_PRODUCT)
const [cart, setCart] = useState(INIT_PRODUCT)
const [error, setError] = useState('')
const [selected, setSelected] = useState({ sizes: false, colors: false })
const [n, setN] = useState(1)
async function getProduct(user){ useEffect(() => {
console.log(user) if (selected.sizes === true && selected.colors === true) {
try { pushOptions()
const response = await axios.get('/api/product/productone') console.log(preCart)
setProduct(response.data)
console.log(response.data)
} catch (error) {
catchErrors(error, setError)
}
} }
}, [cart])
function handleClick(e) { function handleClick(e) {
const box = e.target.parentNode.parentNode const box = e.target.parentNode.parentNode
box.style.display = "none" box.style.display = "none"
} }
function pushOptions() {
preCart.push(cart)
selected.sizes = false
selected.colors = false
setN(n+1)
}
function handleChange(e) { function handleChange(e) {
const { name, value } = e.target const { name, value } = e.target
setSelect({ ...select, [name]: value }) if (e.target.name === "sizes") {
setCart({ ...cart, [name]: value })
selected.sizes = true
} else if (e.target.name === "colors") {
setCart({ ...cart, [name]: value })
selected.colors = true
}
// setCart({ ...cart, [name]: value })
// handleCreate()
} }
function listDelete(e) { function listDelete(e) {
...@@ -38,60 +63,54 @@ function Product() { ...@@ -38,60 +63,54 @@ function Product() {
} }
function handleCreate() { function handleCreate() {
console.log("실행", "cart=", cart) // if (product !== undefined) {
if (cart !== undefined) { // if (product.colors !== "" && product.sizes !== "") {
if (cart.color !== "") { // cart.push(
const list = document.getElementById('list') // <div className="d-flex justify-content-between my-2" >
list.style.borderBottom = "1px solid" // <p>{product.color} {product.size} </p>
const shopping = document.createElement('div') // <input name="count" type="number" min="0" max="10" style="width: 40px" onChange={handleChange} />
shopping.className = "d-flex justify-content-between my-2" // <p style="margin-bottom: 0px">{product.price}</p>
shopping.innerHTML = `${cart.color} / ${cart.size} // </div>
<input type="number" min="0" max="10" value="1" style="width: 40px" /> // )
<p style="margin-bottom: 0px">14,000원</p>` // const list = document.getElementById('list')
const deleteA = document.createElement('a') // list.style.borderBottom = "1px solid"
deleteA.innerText = 'X' // const shopping = document.createElement('div')
deleteA.addEventListener('click', listDelete) // shopping.className = "d-flex justify-content-between my-2"
shopping.appendChild(deleteA) // shopping.innerHTML = `${product.color} / ${product.size}
list.appendChild(shopping) // <input type="number" min="0" max="10" value="1" style="width: 40px" />
} // <p style="margin-bottom: 0px">14,000원</p>`
} // const deleteA = document.createElement('a')
// deleteA.innerText = 'X'
// deleteA.addEventListener('click', listDelete)
// shopping.appendChild(deleteA)
// list.appendChild(shopping)
// }
// }
} }
async function addCart() { async function addCart() {
// color, size, count, productObjectId(productlist에서 props), userId(로컬) 를 보내줌 // color, size, count, productId(productlist에서 props), userId(로컬) 를 보내줌
try { try {
// setError('') // setError('')
const response = await axios.post('/api/addcart', { const response = await axios.put('/api/cart/addcart', {
userId: "jiwon5393", userId: localStorage.getItem('loginStatus'),
productObjectId: "5ff7fd63d41cae4ecce51dd1", productId: "a8f4d63ead77717f940a2b27deb707a6",
color: "red", products: preCart
size: "free",
count: "1"
}) })
console.log(response) console.log(response)
}catch(error){ } catch (error) {
// catchErrors(error, setError) catchErrors(error, setError)
}
alert("상품등록이 완료되었습니다.")
} }
useEffect(() => {
if (Object.keys(select).length == 2) {
setCart({ ...select })
setSelect({})
} }
}, [select])
useEffect(() => { // useEffect(() => {
handleCreate() // handleCreate()
getProduct() // }, [product])
}, [cart])
return ( return (
<div> <div>
{/* {getProduct} */} {console.log("실행", "product=", product)}
<style type="text/css"> <style type="text/css">
{` {`
.btn { .btn {
...@@ -115,22 +134,23 @@ function Product() { ...@@ -115,22 +134,23 @@ function Product() {
<Form style={{ borderBottom: "1px solid" }}> <Form style={{ borderBottom: "1px solid" }}>
<Form.Group style={{ borderBottom: "1px solid", paddingBottom: "2rem" }}> <Form.Group style={{ borderBottom: "1px solid", paddingBottom: "2rem" }}>
<Form.Label>색상</Form.Label> <Form.Label>색상</Form.Label>
<Form.Control as="select" className="mb-2" name="color" defaultValue="옵션 선택" onChange={handleChange}> <Form.Control as="select" className="mb-2" name="colors" defaultValue="옵션 선택" onChange={handleChange}>
<option>옵션선택</option> <option>옵션선택</option>
<option>브릭레드(스트랩포함)</option> {product.colors.map((e) => (
<option>베이지(스트랩포함)</option> <option>{e}</option>
<option>블랙(스트랩포함)</option> ))}
</Form.Control> </Form.Control>
<Form.Label>사이즈</Form.Label> <Form.Label>사이즈</Form.Label>
<Form.Control as="select" className="mb-2" name="size" defaultValue="옵션 선택" onChange={handleChange}> <Form.Control as="select" className="mb-2" name="sizes" defaultValue="옵션 선택" onChange={handleChange}>
<option>옵션선택</option> <option>옵션선택</option>
<option>M</option> {product.sizes.map((e) => (
<option>L</option> <option>{e}</option>
<option>XL</option> ))}
<option>FREE</option>
</Form.Control> </Form.Control>
</Form.Group> </Form.Group>
<div id="list"></div> {preCart.map((e) => (
<div>{e.colors}/{e.sizes}</div>
))}
<Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}> <Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}>
<Col> 금액</Col> <Col> 금액</Col>
<Col className="text-right">14,000</Col> <Col className="text-right">14,000</Col>
......
...@@ -98,18 +98,18 @@ function ProductsRegist() { ...@@ -98,18 +98,18 @@ function ProductsRegist() {
} }
product["sizes"] = sizes product["sizes"] = sizes
const formData = new FormData(); const formData = new FormData();
for (const key in product) { for (let key in product) {
console.log("product[key]=", product[key]) if (key === "main_image" || key === "detail_image") {
if (key == "main_image" || key == "detail_image") { console.log(product[key][0])
for (const file of product[key]) { formData.append(key, product[key][0])
formData.append(key, file)
}
} else { } else {
formData.append(key, product[key]) formData.append(key, product[key])
} }
} }
try { try {
const response = await axios.post('/api/product/regist', formData) const response = axios.post('/api/product/regist', formData)
// setSuccess(true)
console.log(response)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
} }
......
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import ListCard from '../Components/ListCard';
import Pagination from '../Components/Pagination'; import Pagination from '../Components/Pagination';
import { Container, Row, Col, Form, FormControl, Button, Card, Dropdown } from 'react-bootstrap'; import axios from 'axios';
import catchError from '../utils/catchErrors';
import { isAuthenticated } from '../utils/auth';
import { Container, Row, Col, Form, FormControl, Button, Dropdown } from 'react-bootstrap';
function ProductsList(props) { function ProductsList({ match }) {
const const [mainCategory, setMainCategory] = useState('')
const [sub, setSub] = useState(['PADDED JACKET', 'JACKET', 'JUMPER', 'COAT', 'FLEECE', 'CARDIGAN / VEST']) const [sub, setSub] = useState(['PADDED JACKET', 'JACKET', 'JUMPER', 'COAT', 'FLEECE', 'CARDIGAN / VEST'])
const [productlist, setProductlist] = useState([])
const [error, setError] = useState('')
// useEffect(() => { // const user=isAuthenticated()
// getProfile(user)
// }, [user]) useEffect(() => {
setMainCategory(match.params.main.toUpperCase())
}, [match.params.main])
useEffect(() => {
getProductlist()
}, [mainCategory])
// async function getProfile(user){ // async function getProfile(user){
// console.log(user) // console.log(user)
...@@ -20,15 +33,43 @@ function ProductsList(props) { ...@@ -20,15 +33,43 @@ function ProductsList(props) {
// } // }
// } // }
function handleSearch() {
}
async function handleClick(subCategory) {
try {
const response = await axios.get(`/api/product/getproduct/${subCategory}`)
console.log("response.data=", response.data)
setProductlist(response.data)
} catch (error) {
catchError(error, setError)
}
}
function handleSubmit(e) { function handleSubmit(e) {
e.preventDefault() e.preventDefault()
} }
async function getProductlist() {
try {
const response = await axios.get(`/api/product/getproduct/${mainCategory}`)
console.log("response.data=", response.data)
setProductlist(response.data)
} catch (error) {
catchError(error, setError)
}
}
return ( return (
<div> <div>
{console.log("match.params=",props.match.params.product)}
<style type="text/css"> <style type="text/css">
{` {`
a, a:hover, a:active {
color: #000;
text-decoration: none;
}
.btn { .btn {
background-color: #CDC5C2; background-color: #CDC5C2;
border-color: #CDC5C2; border-color: #CDC5C2;
...@@ -43,14 +84,14 @@ function ProductsList(props) { ...@@ -43,14 +84,14 @@ function ProductsList(props) {
<Container> <Container>
<Row className="justify-content-center" > <Row className="justify-content-center" >
<Col sm={10} xs={12} > <Col sm={10} xs={12} >
<h1 style={{ fontSize: "3rem" }} className="text-center">OUTER</h1> <h1 style={{ fontSize: "3rem" }} className="text-center">{mainCategory}</h1>
<div className="text-center">{sub.map((ele) => ( <div className="text-center">{sub.map((ele) => (
<Button className="m-1">{ele}</Button> <Button className="m-1" onClick={(ele) => handleClick(ele)}>{ele}</Button>
))}</div> ))}</div>
</Col> </Col>
</Row> </Row>
<Row className="justify-content-between mx-0 my-5"> <Row className="justify-content-end mx-0 my-5">
<Form as={Row} onSubmit={handleSubmit} className="justify-content-end mx-0"> {/* <Form as={Row} onSubmit={handleSubmit} className="justify-content-end mx-0"> */}
<Dropdown> <Dropdown>
<Dropdown.Toggle className="mx-2">정렬</Dropdown.Toggle> <Dropdown.Toggle className="mx-2">정렬</Dropdown.Toggle>
<Dropdown.Menu> <Dropdown.Menu>
...@@ -60,64 +101,32 @@ function ProductsList(props) { ...@@ -60,64 +101,32 @@ function ProductsList(props) {
<Dropdown.Item>높은가격</Dropdown.Item> <Dropdown.Item>높은가격</Dropdown.Item>
</Dropdown.Menu> </Dropdown.Menu>
</Dropdown> </Dropdown>
<Form as={Row} onSubmit={handleSubmit} className="justify-content-end mx-0"> <Form as={Row} onSubmit={handleSearch} className="justify-content-end mx-0">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} /> <FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="search px-2"> <Button type="submit" className="search px-2">
<img src="icon/search.svg" width="20" height="20" /> <img src="/icon/search.svg" width="20" height="20" />
</Button> </Button>
</Form> </Form>
</Form> {/* </Form> */}
</Row> </Row>
<Row md={8} sm={12} className="justify-content-start m-2"> <Row md={8} sm={12} className="justify-content-start m-2">
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}> {productlist.map(pro => (
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67460/1607053816_0.jpg" style={{ objectFit: "contain", height: "22rem" }} /> <Link to={{
<Card.Body> pathname: `/products/${pro._id}`,
<Card.Title>케이시앵글부츠(SH)</Card.Title> state: {
<Card.Text>가격 : 12,000</Card.Text> id: pro._id,
</Card.Body> name: pro.pro_name,
</Card> price: pro.price,
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}> colors: pro.colors,
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/48705/1552562469_0.jpg" style={{ objectFit: "contain", height: "22rem" }} /> sizes: pro.sizes,
<Card.Body> description: pro.description,
<Card.Title>메리제인플랫(SH)</Card.Title> main_img: pro.main_imgUrl,
<Card.Text>가격 : 12,000</Card.Text> detail_imgs: pro.detail_imgUrls
</Card.Body> }
</Card> }}>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}> <ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/53386/1567390097_2.jpg" style={{ objectFit: "contain", height: "22rem" }} /> </Link>
<Card.Body> ))}
<Card.Title>솔티드스니커즈(SH)</Card.Title>
<Card.Text>가격 : 12,000</Card.Text>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/61286/1587540563_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>버켄슬리퍼(SH)</Card.Title>
<Card.Text>가격 : 12,000</Card.Text>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://hotping.co.kr/web/product/big/202011/b8f4c6471955b80fc3991b7d6df8926a.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>크레센도 하이힐펌프스</Card.Title>
<Card.Text>가격 : 12,000</Card.Text>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://hotping.co.kr/web/product/big/202011/888e4e8d6a2c2e7da385b079151fcba2.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>어텀솔져1cm 스웨이드로퍼</Card.Title>
<Card.Text>가격 : 12,000</Card.Text>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://hotping.co.kr/web/product/big/202007/3308564012eb14e6c11ed621fa7555fb.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>포웰3.5cm 스니커즈</Card.Title>
<Card.Text>가격 : 12,000</Card.Text>
</Card.Body>
</Card>
</Row> </Row>
</Container> </Container>
{/* <Pagination postsPerPage={postsPerPage} totalPosts={posts.length} paginate={paginate} /> */} {/* <Pagination postsPerPage={postsPerPage} totalPosts={posts.length} paginate={paginate} /> */}
......
...@@ -2,9 +2,19 @@ import React, { useState, useEffect, useRef } from 'react'; ...@@ -2,9 +2,19 @@ import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom'; import { Redirect } from 'react-router-dom';
import { Card, Button, Container, Row, Col } from 'react-bootstrap'; import { Card, Button, Container, Row, Col } from 'react-bootstrap';
import axios from 'axios'; import axios from 'axios';
import catchErrors from '../utils/catchErrors';
import { isAuthenticated } from '../utils/auth'
import CartCard from '../Components/CartCard';
function ShoppingCart() { function ShoppingCart() {
const [num, setNum] = useState(0) const [num, setNum] = useState(0)
const [error, setError] = useState('')
const [cart, setCart] = useState()
const user = isAuthenticated()
useEffect(() => {
getCart()
}, [user])
function plusNum() { function plusNum() {
setNum(num + 1) setNum(num + 1)
...@@ -18,46 +28,41 @@ function ShoppingCart() { ...@@ -18,46 +28,41 @@ function ShoppingCart() {
} }
} }
function deleteCart() { async function deleteCart(e) {
//장바구니 DB에서 해당 항목 삭제 //장바구니 DB에서 해당 항목 삭제
console.log(e.target.name)
try {
const response = await axios.post('/api/cart/deletecart', { cartId: e.target.name })
console.log(response.data)
} catch (error) {
catchErrors(error, setError)
}
console.log('카트에 담긴 항목을 삭제했습니다.') console.log('카트에 담긴 항목을 삭제했습니다.')
} }
// async function getCart(){ async function getCart() {
// const response = await axios.get('/') // const userId= localStorage.getItem('loginStatus')
// } try {
const response = await axios.get(`/api/cart/showcart/${user}`)
console.log(response.data)
setCart(response.data)
} catch (error) {
catchErrors(error, setError)
}
}
return ( return (
<div> <div>
{/* {getCart} */} {/* {getCart()} */}
{/* {console.log(user)} */}
{/* {console.log(cart)} */}
<Container className="justify-content-center"> <Container className="justify-content-center">
<h3 className="my-5 font-weight-bold text-center">장바구니</h3> <h3 className="my-5 font-weight-bold text-center">장바구니</h3>
<div> <div>
<h4 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h4> <h4 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h4>
<Card> {cart?<CartCard cart={cart} deleteCart={deleteCart} minusNum={minusNum} plusNum={plusNum} num={num} />:<div></div>}
<Row className="mx-1">
<Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" id="exampleCheck1" />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src="icon/asd.jpg" style={{ width: '20rem' }} />
</Col>
<Col md={6} className="p-2">
<Card.Body>
<input type="image" alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" onClick={deleteCart} />
<Card.Title className="font-weight-bold mt-3">제품명</Card.Title>
<Card.Text>가격</Card.Text>
<Card.Text>옵션</Card.Text>
<Card.Text>수량</Card.Text>
<div>
<input type="image" alt="마이너스" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={minusNum} />
<input type="text" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder="1" value={num} readOnly></input>
<input type="image" alt="플러스" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={plusNum} />
</div>
</Card.Body>
</Col>
</Row>
</Card>
</div> </div>
<div className="p-5 m-5" style={{ background: '#F7F3F3' }}> <div className="p-5 m-5" style={{ background: '#F7F3F3' }}>
<ul className="pl-0" style={{ listStyle: 'none' }}> <ul className="pl-0" style={{ listStyle: 'none' }}>
......
...@@ -2,6 +2,7 @@ import React, { useState } from 'react'; ...@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import axios from 'axios' import axios from 'axios'
import { Form, Col, Container, Button, Row, Alert } from 'react-bootstrap' import { Form, Col, Container, Button, Row, Alert } from 'react-bootstrap'
import catchErrors from '../utils/catchErrors' import catchErrors from '../utils/catchErrors'
import { Redirect } from 'react-router-dom';
const INIT_USER = { const INIT_USER = {
name: '', name: '',
...@@ -13,9 +14,9 @@ const INIT_USER = { ...@@ -13,9 +14,9 @@ const INIT_USER = {
} }
function Signup() { function Signup() {
const [user, setUser] = useState('') const [user, setUser] = useState(INIT_USER)
const [error, setError] = useState('') const [error, setError] = useState('')
const [success, setSuccess] = useState(false)
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
function handleChange(event) { function handleChange(event) {
...@@ -26,7 +27,6 @@ function Signup() { ...@@ -26,7 +27,6 @@ function Signup() {
async function handleSubmit(event) { async function handleSubmit(event) {
event.preventDefault() event.preventDefault()
const form = event.currentTarget; const form = event.currentTarget;
console.log(form)
if (form.checkValidity() === false) { if (form.checkValidity() === false) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
...@@ -38,13 +38,14 @@ function Signup() { ...@@ -38,13 +38,14 @@ function Signup() {
setError('') setError('')
const response = await axios.post('/api/users/signup', user) const response = await axios.post('/api/users/signup', user)
console.log(response.data) console.log(response.data)
setSuccess(true)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
} }
}
}
function checkPassword(event) { function checkPassword(event) {
const p1 = user.password const p1 = user.password
const p2 = user.password2 const p2 = user.password2
...@@ -60,11 +61,15 @@ function Signup() { ...@@ -60,11 +61,15 @@ function Signup() {
} }
} }
if (success) {
alert('회원가입 되었습니다.')
return <Redirect to='/login'/>
}
return ( return (
<div> <div>
{console.log(user)}
<Container className="my-5"> <Container className="my-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col md={6} xs={10} className="border" style={{ background: '#F7F3F3' }}> <Col md={6} xs={10} className="border" style={{ background: '#F7F3F3' }}>
<h2 className="text-center mt-5">Sign Up</h2> <h2 className="text-center mt-5">Sign Up</h2>
...@@ -185,7 +190,7 @@ function Signup() { ...@@ -185,7 +190,7 @@ function Signup() {
</Row> </Row>
</Container> </Container>
</div> </div>
) )
} }
export default Signup export default Signup
\ No newline at end of file
...@@ -24,6 +24,7 @@ app.use(express.json()) ...@@ -24,6 +24,7 @@ app.use(express.json())
app.use(cors()) app.use(cors())
app.use(express.static(path.join(process.cwd(), 'dist'))) app.use(express.static(path.join(process.cwd(), 'dist')))
// app.use(bodyParser.urlencoded({ extended: true })) // app.use(bodyParser.urlencoded({ extended: true }))
app.use('/images', express.static('uploads/'))
// app.use('/', indexRouter); // app.use('/', indexRouter);
app.use('/', kakaopayRoutes) app.use('/', kakaopayRoutes)
...@@ -31,7 +32,7 @@ app.use('/api/categorys',categoryRouter) ...@@ -31,7 +32,7 @@ app.use('/api/categorys',categoryRouter)
app.use('/api/users',userRouter) app.use('/api/users',userRouter)
app.use('/api/auth',authRouter) app.use('/api/auth',authRouter)
app.use('/api/product', productRouter) app.use('/api/product', productRouter)
app.use('/api/addcart', cartRouter) app.use('/api/cart', cartRouter)
app.listen(config.port, () => { app.listen(config.port, () => {
console.info('Server started on port %s.', config.port) console.info('Server started on port %s.', config.port)
......
import Cart from "../schemas/Cart.js"; import Cart from "../schemas/Cart.js";
import Product from '../schemas/Product.js'
const addcart = async (req, res) => {
const cart = async (req, res) => { // console.log(req.body)
const { userId, productObjectId, color, size, count } = req.body const { userId, products} = req.body
// console.log('req.body=', req.body)
// const {userId, productObjectId, }
// const { user, pro_name, price, main_image } = req.body
// color, size, count, productObjectId(productlist에서 props), userId(로컬)
try { try {
const product = await Product.find({ _id: productObjectId }) const cart = await Cart.findOne({ userId: userId })
if (product) { console.log(cart)
// console.log(product) // const newProduct = { products: products }
const { pro_name, price, main_image } = product[0] // const newProduct = {...newProduct}
const products = { productObjectId, color, size, count, pro_name, price, main_image } // console.log(newProduct)
// console.log(products) console.log(products)
const newCart = await new Cart({ await Cart.updateOne(
userId, products { _id: cart._id },
}).save() // { $addToSet: { products: newProduct } }
console.log(newCart) {$set: {products: products}}
res.json(newCart) )
res.status(200).send('Cart updated')
}
// const newCart = await new Cart({
// user, pro_name, price, stock, main_category, sub_category, main_image
// }).save()
// const asdf = await Cart.find({ user })
// console.log(newCart)
// res.json(newCart)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
res.status(500).send('죄송합니다. 다시 입력해 주십시오.') res.status(500).send('죄송합니다. 다시 입력해 주십시오.')
} }
}
// try { const showcart = async (req, res) => {
// const user = await // const {userId} = req.body
// User.findById(id) // console.log(req.cart)
// if (!user) { // console.log(req.id)
// console.log(error)
// res.status(404).send('사용자를 찾을 수 없습니다') try {
// } const cart = await Cart.findOne({ userId: req.id }).populate({
// req.profile = user path: 'products.productId',
// next() model: 'Product'
// } catch (error) { })
// console.log(error) res.status(200).json(cart.products)
// res.status(500).send('사용자 아이디 실패') } catch (error) {
// } console.log(error)
res.status(500).send('쇼핑카트를 불러오지 못했습니다.')
}
} }
export default { cart } const deletecart = async (req, res) => {
\ No newline at end of file console.log(req.body)
const { cartId } = req.body
try {
await Cart.remove({ _id: cartId })
res.send("삭제완료")
// res.json()
} catch (error) {
console.log(error)
res.status(500).send('해당 카트를 삭제하지 못했습니다.')
}
}
const userById = async (req, res, next, id) => {
try {
const cart = await Cart.findOne({ userId: id })
if (!cart) {
res.status(404).send("사용자를 찾을 수 없습니다.")
}
req.cart = cart
req.id = id
next()
} catch (error) {
res.status(500).send("사용자 아이디 검색 실패")
}
}
export default { addcart, showcart, deletecart, userById }
\ No newline at end of file
...@@ -29,4 +29,25 @@ const regist = async (req, res) => { ...@@ -29,4 +29,25 @@ const regist = async (req, res) => {
} }
} }
export default { imageUpload, regist } const getlist=(req,res)=>{
\ No newline at end of file try {
res.json(req.productslist)
} catch (error) {
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
const categoryId = async (req, res, next, category) => {
try {
const productslist = await Product.find({main_category:category})
if (!productslist) {
res.status(404).send('상품을 찾을 수 없습니다.')
}
req.productslist = productslist
next()
} catch (error) {
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
export default { imageUpload, regist, categoryId, getlist }
\ No newline at end of file
import Cart from "../schemas/Cart.js";
import User from "../schemas/User.js"; import User from "../schemas/User.js";
import isLength from 'validator/lib/isLength.js'; import isLength from 'validator/lib/isLength.js';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
const signup = async (req, res) => { const signup = async (req, res) => {
console.log(req.body)
const { name, number1, number2, id, password, tel } = req.body const { name, number1, number2, id, password, tel } = req.body
console.log(req.body)
try { try {
if(!isLength(password,{min:8, max:15})){ if (!isLength(password, { min: 8, max: 15 })) {
return res.status(422).send('비밀번호는 8-15자리로 입력해주세요.') return res.status(422).send('비밀번호는 8-15자리로 입력해주세요.')
} }
const user=await User.findOne({id}) const user = await User.findOne({ id })
if(user){ if (user) {
return res.status(422).send(`${id}가 이미 사용중입니다.`) return res.status(422).send(`${id}가 이미 사용중입니다.`)
} }
const hash=await bcrypt.hash(password,10) const hash = await bcrypt.hash(password, 10)
const newUser = await new User ({ const newUser = await new User({
name, name,
number1, number1,
number2, number2,
id, id,
password:hash, password: hash,
tel, tel,
}).save() }).save()
await new Cart({ userId: newUser._id }).save()
console.log(newUser) console.log(newUser)
res.json(newUser) res.json(newUser)
......
...@@ -6,7 +6,7 @@ const router = express.Router() ...@@ -6,7 +6,7 @@ const router = express.Router()
router.route('/login') router.route('/login')
.post(authCtrl.login) .post(authCtrl.login)
router.route('/logout') router.route('/logout')
.get(authCtrl.logout) .get(authCtrl.logout)
export default router export default router
\ No newline at end of file
...@@ -4,8 +4,16 @@ import cartCtrl from '../controllers/cart.controller.js'; ...@@ -4,8 +4,16 @@ import cartCtrl from '../controllers/cart.controller.js';
const router = express.Router() const router = express.Router()
router.route('/') router.route('/addcart')
.post(cartCtrl.cart) .put(cartCtrl.addcart)
// .get() // .get()
router.route('/showcart/:userId')
.get(cartCtrl.showcart)
router.param('userId', cartCtrl.userById)
router.route('/deletecart')
.post(cartCtrl.deletecart)
export default router export default router
\ No newline at end of file
...@@ -7,7 +7,9 @@ const router = express.Router() ...@@ -7,7 +7,9 @@ const router = express.Router()
router.route('/regist') router.route('/regist')
.post(productCtrl.imageUpload, productCtrl.regist) .post(productCtrl.imageUpload, productCtrl.regist)
// router.route('/productone') router.route('/getproduct/:category')
// .get(productCtrl.getProduct) .get(productCtrl.getlist)
router.param('category', productCtrl.categoryId)
export default router export default router
\ No newline at end of file
import mongoose from 'mongoose' import mongoose from 'mongoose'
const { String, Number, Array, ObjectId } = mongoose.Schema.Types const { String, Number, Array, ObjectId } = mongoose.Schema.Types
const productschema = new mongoose.Schema ({ const CartSchema = new mongoose.Schema({
pro_name: { userId: {
type: String, type: ObjectId,
required: true ref: 'User'
}, },
price:{ products: {
type: [
{
count: {
type: Number, type: Number,
required: true default: 1
},
main_image: {
type: String,
required: true
}, },
color:{ productId: {
type: String, type: ObjectId,
required: true ref: 'Product'
}, },
size:{ sizes: {
type: String, type: String
required: true
}, },
productObjectId: { colors: {
type: ObjectId, type: String
required: true
} }
})
const CartSchema = new mongoose.Schema({
userId: {
type: String,
// required: true
},
products : {
type: [productschema],
required: true
} }
]
}, { }
timestamps: true
}) })
export default mongoose.models.Cart || mongoose.model('Cart', CartSchema) export default mongoose.models.Cart || mongoose.model('Cart', CartSchema)
\ 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