Commit 43450898 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'ourMaster' into jiwon

parents 28a4a95f 22e80f26
......@@ -24,6 +24,7 @@ function App() {
<Route path="/login" component={Login} />
<Route path="/signup" component={Signup} />
<Route path="/product/:productId" component={Product} />
<Route path="/categories/:main/:sub" component={ProductsList} />
<Route path="/categories/:main" component={ProductsList} />
<Route path="/admin" component={Admin} />
<Route path="/regist" component={ProductRegist} />
......
import React, { useState, useEffect, useRef } from 'react';
import { Card } from 'react-bootstrap';
import { Card, Button } 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="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card id={id} className="m-3" style={{ width: "18rem" }}>
<Card.Img variant="top" src={main_img && `/images/${main_img}`} style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</Card.Title>
<Card.Text>{price} </Card.Text>
<Button className="float-right" onClick={handleDelete}>삭제</Button>
</Card.Body>
</Card>
)
}
}
export default ListCard
\ No newline at end of file
......@@ -8,7 +8,6 @@ function SubNav() {
const [categoriesDiv, setCategoriesDiv] = useState([])
const [error, setError] = useState('')
useEffect(async () => {
try {
const response = await axios.get('/api/categories/main')
......@@ -17,6 +16,7 @@ function SubNav() {
const url = ele.toLowerCase()
list.push(
<Nav.Link as={Link} to={`/categories/${url}`}>{ele}</Nav.Link>
//categories/${SubNav.url}/&{url}
)
})
setCategoriesDiv(list)
......@@ -34,7 +34,7 @@ function SubNav() {
}
`}
</style>
<Nav style={{overflowX: "auto"}}>
<Nav style={{ overflowX: "auto" }}>
{categoriesDiv.map(item => item)}
</Nav>
</Navbar>
......
import React, { useEffect, useState } from 'react'
import { Card, Image, Container, Row, Col, Table, Accordion, Button, Form, Modal, Alert } from 'react-bootstrap'
import { Link } from 'react-router-dom';
import axios from 'axios'
import catchErrors from '../utils/catchErrors';
import axios from 'axios';
import catchError from '../utils/catchErrors';
import { isAuthenticated } from '../utils/auth';
const INIT_ACCOUNT = {
......@@ -10,13 +10,12 @@ const INIT_ACCOUNT = {
avatarUrl: ''
}
function Account() {
const [account, setAccount] = useState(INIT_ACCOUNT)
const [show, setShow] = useState(false);
const [error, setError] = useState("")
const userId = isAuthenticated()
async function getUsername(user) {
// console.log("tlg")
try {
......@@ -24,7 +23,7 @@ function Account() {
setAccount(response.data)
// console.log('555555555', response.data);
} catch (error) {
catchErrors(error, setError)
catchError(error, setError)
// console.log('error2222', error)
}
}
......@@ -33,13 +32,6 @@ function Account() {
getUsername(userId)
}, [userId])
const [show, setShow] = useState(false);
const handleClose = () => setShow(false)
const handleShow = () => setShow(true)
const handleChange = (event) => {
const { name, value, files } = event.target
if (files) {
......@@ -63,7 +55,7 @@ function Account() {
window.location.reload()
}
} catch (error) {
catchErrors(error, setError)
catchError(error, setError)
}
setShow(false)
}
......@@ -81,30 +73,37 @@ function Account() {
window.location.reload()
}
} catch (error) {
catchErrors(error, setError)
catchError(error, setError)
}
} else {
alert("파일을 선택해주세요.")
}
}
}
return (
<Container className="px-3">
<style type="text/css">
{`
a, a:hover, a:active {
color: #91877F;
text-decoration-color: #91877F;
}
`}
</style>
<h3 className="my-4 mx-3 font-weight-bold">My Page</h3>
<Card md={3} className="p-1 mb-4" style={{ background: '#F7F3F3' }}>
<Row className="p-2">
<Col md={5} className="d-flex align-content-center justify-content-center">
<Button variant="outline-light" onClick={handleShow}>
<Button variant="outline-light" onClick={() => setShow(true)}>
{account.avatarUrl ? (
<Image src={account.avatarUrl && `/image/${account.avatarUrl}`} className="img-thumbnail"
<Image src={account.avatarUrl && `/images/${account.avatarUrl}`} className="img-thumbnail"
roundedCircle style={{ objectFit: "cover", width: "10rem", height: "10rem" }} />
) : (
<Image src="/icon/person.svg" className="img-thumbnail"
roundedCircle style={{ objectFit: "cover", width: "10rem", height: "10rem" }} />
)}
</Button>
<Modal show={show} onHide={handleClose}>
<Modal show={show} onHide={() => setShow(false)}>
<Modal.Header closeButton>
<Modal.Title>이미지를 변경하시겠습니까?</Modal.Title>
</Modal.Header>
......@@ -118,8 +117,8 @@ function Account() {
className="d-flex justify-content-start"><small>기본이미지로</small></Button>
{/* 기본이미지로 보내기 */}
</Col>
<Button variant="secondary" onClick={handleClose}>취소</Button>
<Button variant="primary" type="submit" onClick={handleClose}>저장</Button>
<Button variant="secondary" onClick={() => setShow(false)}>취소</Button>
<Button variant="primary" type="submit" onClick={() => setShow(false)}>저장</Button>
</Modal.Footer>
</Form>
</Modal>
......@@ -134,15 +133,15 @@ function Account() {
</Row>
<Row className="px-3">
<Card.Body className="p-2 text-center">
<h4><Link to="/" class="link-warning">
<h4><Link to="/">
<strong title="홈으로">
<Image src="/icon/mypagetiger.svg" width={"30rem"} roundedCircle className="img-thumbnail" >
</Image>KU#
</strong>
</strong>
</Link>
{/* 홈페이지로 돌아가기 */}
방문해주신 <em>{account.name}</em> 님,<br></br>
진심으로 환영합니다! 즐거운 쇼핑 되세요.</h4>
방문해주신 <em>{account.name}</em> 님,<br />
진심으로 환영합니다! 즐거운 쇼핑 되세요.
</h4>
</Card.Body>
</Row>
<Row className="mr-1 text-muted d-flex justify-content-end">
......
import React from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom';
import ListCard from '../Components/ListCard';
import Pagination from '../Components/Pagination';
import axios from 'axios';
import { isAdmin } from "../utils/auth";
import catchError from '../utils/catchErrors';
import { Row, Form, FormControl, Button, Card, Container } from 'react-bootstrap';
function Admin() {
function handleClick(e) {
const card = e.target.parentNode.parentNode
alert('해당 상품을 성공적으로 삭제하였습니다.')
card.remove()
const [productlist, setProductlist] = useState([])
const [error, setError] = useState('')
const role = isAdmin()
useEffect(() => {
getProductlist()
}, [])
async function getProductlist() {
try {
const response = await axios.get(`/api/product/getproduct/all`)
console.log("response.data=", response.data)
setProductlist(response.data)
} catch (error) {
catchError(error, setError)
}
}
function handleSearch() {
}
function handleSubmit(e) {
e.preventDefault()
}
if(!role) {
alert('죄송합니다.접근 권한이 없습니다.')
return <Redirect to="/" />
}
return (
<div>
<Container>
<style type="text/css">
{`
.btn {
......@@ -28,97 +54,20 @@ function Admin() {
}
`}
</style>
<Container>
<Row as={Form} onSubmit={handleSubmit} className="justify-content-end mx-0 my-5">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="px-2">
<img src="icon/search.svg" width="20" height="20" />
</Button>
<Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button>
</Row>
<Row className="justify-content-start m-5">
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67460/1607053816_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>케이시앵글부츠(SH)</Card.Title>
<Card.Text>
재고: 8<br />
구매자 : 10
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/48705/1552562469_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>메리제인플랫(SH)</Card.Title>
<Card.Text>
재고: 20<br />
구매자 : 60
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body>
</Card>
<Card className="mt-5" style={{ width: "18rem", margin: "auto" }}>
<Card.Img variant="top" src="https://img.sonyunara.com/files/goods/53386/1567390097_2.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body>
<Card.Title>솔티드스니커즈(SH)</Card.Title>
<Card.Text>
재고: 34<br />
구매자 : 5
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</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>
재고: 50<br />
구매자 : 18
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</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>
재고: 35<br />
구매자 : 70
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</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>
재고: 40<br />
구매자 : 30
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</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>
재고: 15<br />
구매자 : 50
</Card.Text>
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body>
</Card>
</Row>
<Pagination />
</Container>
</div>
<Row as={Form} onSubmit={handleSubmit} className="justify-content-end mx-0 my-5">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="px-2">
<img src="icon/search.svg" width="20" height="20" />
</Button>
<Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button>
</Row>
<Row className="justify-content-center m-5">
{productlist.map(pro => (
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
))}
</Row>
<Pagination />
</Container>
)
}
......
import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import ListCard from '../Components/ListCard';
import axios from 'axios';
import catchError from '../utils/catchErrors';
import { Card, Container, Row } from 'react-bootstrap';
import { Container, Row } from 'react-bootstrap';
function Home() {
const [productlist, setProductlist] = useState([])
const INIT_PRODUCT = {
bestProduct: [],
newProduct: [],
}
const [productlist, setProductlist] = useState(INIT_PRODUCT)
const [error, setError] = useState('')
useEffect(() => {
......@@ -16,78 +21,67 @@ function Home() {
async function getProductlist() {
try {
const response = await axios.get(`/api/product/getproduct`)
console.log(response.data)
setProductlist(response.data)
console.log("res=", response.data)
setProductlist({ bestProduct: response.data.bestProduct, newProduct: response.data.newProduct })
} catch (error) {
catchError(error, setError)
}
}
return (
<div>
<Container className="my-5">
<div className="my-4">
<h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem" }}><u>Best</u></h2>
<Row className="justify-content-center mx-0">
<ListCard productlist={productlist} />
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
</Row>
</div>
<div className="my-4">
<h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem", marginTop: "2rem" }}><u>New Arrival</u></h2>
<Row className="justify-content-center mx-0">
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
<Card className="mx-1 my-2" style={{ width: '18rem' }}>
<Card.Img className="img-fluid" variant="top" src="/icon/asd.jpg" />
<Card.Body>
<Card.Title className="font-weight-bold">제품명</Card.Title>
<Card.Text>가격</Card.Text>
</Card.Body>
</Card>
</Row>
</div>
</Container>
</div>
<Container>
<style type="text/css">
{`
a, a:hover, a:active {
color: #000;
text-decoration: none;
`}
</style>
<div className="my-4">
<h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem" }}><u>Best</u></h2>
<Row className="justify-content-center mx-0">
{productlist.bestProduct.map(pro => (
<Link to={{
pathname: `/product/${pro._id}`,
state: {
id: pro._id,
name: pro.pro_name,
price: pro.price,
colors: pro.colors,
sizes: pro.sizes,
description: pro.description,
main_img: pro.main_imgUrl,
detail_imgs: pro.detail_imgUrls
}
}}>
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
</Link>
))}
</Row>
</div>
<div className="my-4">
<h2 style={{ marginRight: "5rem", marginLeft: "3rem", marginBottom: "2rem", marginTop: "2rem" }}><u>New Arrival</u></h2>
<Row className="justify-content-center mx-0">
{productlist.newProduct.map(pro => (
<Link to={{
pathname: `/product/${pro._id}`,
state: {
id: pro._id,
name: pro.pro_name,
price: pro.price,
colors: pro.colors,
sizes: pro.sizes,
description: pro.description,
main_img: pro.main_imgUrl,
detail_imgs: pro.detail_imgUrls
}
}}>
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
</Link>
))}
</Row>
</div>
</Container>
)
}
......
......@@ -21,7 +21,6 @@ function Login() {
function handleChange(event) {
const { name, value } = event.target
setUser({ ...user, [name]: value })
}
async function handleSubmit(event) {
......@@ -47,8 +46,6 @@ function Login() {
window.location.href='/'
}
return (
<Container className="my-5">
<Row className="justify-content-center">
......
import React, { useState, useEffect, useRef } from 'react';
import { Redirect } from 'react-router-dom';
import { Row, Col, Button, Form, Container, Alert } from 'react-bootstrap';
import { Row, Col, Button, Form, Container, Alert, Spinner } from 'react-bootstrap';
import axios from 'axios';
import catchErrors from '../utils/catchErrors';
......@@ -23,13 +23,17 @@ function ProductsRegist() {
}
const [categories, setCategories] = useState({ 0: [], 1: [[]] })
const [product, setProduct] = useState(INIT_PRODUCT)
const [categoryNum, setCategoryNum] = useState(0)
const [categoryNum, setCategoryNum] = useState('')
const [tag, setTag] = useState(0)
const [subCate, setSubCate] = useState('')
const [color, setColor] = useState({})
const [error, setError] = useState('')
const [success, setSuccess] = useState(false)
const [checked, setChecked] = useState({ "Free": false, "XL": false, "L": false, "M": false, "S": false, "XS": false })
const [disabled, setDisabled] = useState(true)
const [loading, setLoading] = useState(false)
const selectRef = useRef(null)
const colorRef = useRef(null)
useEffect(async () => {
try {
......@@ -41,28 +45,37 @@ function ProductsRegist() {
}
}, [])
function addCategory() {
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)
console.log(list)
useEffect(() => {
const isProduct = Object.values(product).every(el => { console.log("el=", el); Boolean(el) })
isProduct ? setDisabled(false) : setDisabled(true)
}, [product])
function addCategory(e) {
if (selectRef.current.value === '') {
alert('하위 분류를 반드시 선택해 주세요.')
} else {
list.push(
<div>
<span name={subCate} >{product["main_category"]} / {subCate} </span>
<input name={subCate} type="image" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right align-middle" onClick={deleteCategory} />
</div>)
setTag(tag + 1)
selectRef.current.selectedIndex = 0
}
}
function deleteCategory(e) {
e.target.parentNode.remove()
const index = product["sub_category"].findIndex((item)=>{return item === e.target.name})
const index = product["sub_category"].findIndex((item) => { return item === e.target.name })
product["sub_category"].splice(index, 1)
setSubCate('')
console.log(product["sub_category"].length)
}
function handleCategory(e) {
const { name, value } = e.target
if (e.target.name === "main_category") {
setCategoryNum(e.target.selectedIndex - 1)
const { name, value, selectedIndex } = e.target
if (name === "main_category") {
setCategoryNum(selectedIndex - 1)
}
if (name === "sub_category") {
product[name].push(value)
......@@ -70,7 +83,6 @@ function ProductsRegist() {
} else {
setProduct({ ...product, [name]: value })
}
console.log(value)
}
function handleCheckBox(e) {
......@@ -85,15 +97,16 @@ function ProductsRegist() {
<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>
)
setColor({})
colorRef.current.value = ''
setProduct({ ...product, "colors": preColors })
}
function deleteColor(e) {
// console.log("e.name=",e.target.name)
e.target.parentNode.remove()
product["colors"].splice(e.name, 1)
setColor({})
console.log(product)
// setColor({})
// console.log(product)
}
function handleColor(e) {
......@@ -102,13 +115,11 @@ function ProductsRegist() {
function handleChange(event) {
const { name, value, files } = event.target
console.log("event.target.name=", name, "event.target.value=", value)
if (files) {
setProduct({ ...product, [name]: files })
} else {
setProduct({ ...product, [name]: value })
}
}
async function handleSubmit(e) {
......@@ -123,7 +134,7 @@ function ProductsRegist() {
console.log(product)
const formData = new FormData();
for (let key in product) {
if (key === "main_image" ||key === "detail_image") {
if (key === "main_image" || key === "detail_image") {
formData.append(key, product[key][0])
} else if(key === "sizes" || key === "colors"){
for (let i = 0; i < product[key].length ; i++){
......@@ -135,15 +146,20 @@ function ProductsRegist() {
}
}
try {
setLoading(true)
setError('')
const response = await axios.post('/api/product/regist', formData)
console.log(response)
setSuccess(true)
} catch (error) {
catchErrors(error, setError)
} finally {
setLoading(false)
}
}
if (success) {
alert('상품 등록을 완료하였습니다.')
return <Redirect to='/admin' />
}
......@@ -178,11 +194,11 @@ function ProductsRegist() {
</Form.Control>
</Col>
<Col md={6}>
<Form.Control as="select" name="sub_category" onChange={handleCategory} disabled={product["main_category"] === "TRAINING"}>
<Form.Control as="select" ref={selectRef} name="sub_category" onChange={handleCategory}>
<option value="" >하위분류</option>
{categories[1][categoryNum].map((sub) => (
{(categoryNum === '') ? '' : (categories[1][categoryNum].map((sub) => (
<option value={sub}>{sub}</option>
))}
)))}
</Form.Control>
</Col>
<Col >
......@@ -193,18 +209,37 @@ function ProductsRegist() {
</Form.Group>
<Form.Group>
<Form.Label>사이즈</Form.Label>
<Form.Check type="checkbox" name="sizes" label="Free" value="Free" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="XL" value="XL" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="L" value="L" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="M" value="M" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="S" value="S" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="XS" value="XS" onChange={handleCheckBox} />
<Row>
<Col>
<Form.Check type="checkbox" name="sizes" label="210" value="210" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="215" value="215" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="220" value="220" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="225" value="225" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="230" value="230" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="235" value="235" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="240" value="240" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="245" value="245" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="250" value="250" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="255" value="255" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="260" value="260" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="265" value="265" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="270" value="270" onChange={handleCheckBox} />
</Col>
<Col>
<Form.Check type="checkbox" name="sizes" label="FREE" value="FREE" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="XL" value="XL" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="L" value="L" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="M" value="M" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="S" value="S" onChange={handleCheckBox} />
<Form.Check type="checkbox" name="sizes" label="XS" value="XS" onChange={handleCheckBox} />
</Col>
</Row>
</Form.Group>
<Form.Group>
<Form.Label>색상</Form.Label>
<Row>
<Col md={10}>
<Form.Control as="textarea" rows={1} name="colors" placeholder="색상" onChange={handleColor} />
<Form.Control as="input" ref={colorRef} name="colors" placeholder="색상" onChange={handleColor} />
</Col>
<Col>
<Button className="float-right" style={{ background: '#91877F', borderColor: '#91877F' }} onClick={addColor}>추가</Button>
......@@ -212,7 +247,6 @@ function ProductsRegist() {
</Row>
{colorHtml.map((element) => element)}
</Form.Group>
<Form.Group controlId="productDescriptionform">
<Form.Label>상품설명</Form.Label>
<Form.Control as="textarea" name="description" rows={3} placeholder="상품을 설명해주세요" onChange={handleChange} />
......@@ -225,7 +259,9 @@ function ProductsRegist() {
<Form.Label>상세이미지</Form.Label>
<Form.File id="productImageform" name="detail_image" onChange={handleChange} />
</Form.Group>
<Button className="float-right" type="submit" style={{ background: '#91877F', borderColor: '#91877F' }}>등록</Button>
<Button type="submit" style={{ background: '#91877F', borderColor: '#91877F' }} block>
{loading && <Spinner as='span' animation='border' size='sm' role='status' aria-hidden='true' />}{' '}등록
</Button>
</Form>
</Col>
</Row>
......
import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import ListCard from '../Components/ListCard';
import Pagination from '../Components/Pagination';
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';
import catchErrors from '../utils/catchErrors';
import { Container, Row, Col, Form, FormControl, Button, Dropdown, ButtonGroup } from 'react-bootstrap';
function ProductsList({ match }) {
const [mainCategory, setMainCategory] = useState(match.params.main.toUpperCase())
const [subcategory, setSubcategory] = useState([])
const [productlist, setProductlist] = useState([])
const [sub, setSub] = useState([])
const [error, setError] = useState('')
// const user=isAuthenticated()
useEffect(() => {
setMainCategory(match.params.main.toUpperCase())
}, [match.params.main])
useEffect(() => {
getSubsCategories()
getSubsCategories([])
getProductlist()
}, [mainCategory])
useEffect(() => {
setMainCategory(match.params.main.toUpperCase())
}, [match.params.main])
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) {
// catchErrors(error, setError)
// }
// }
// function handleSubmit(e) {
// e.preventDefault()
// }
async function getSubsCategories() {
async function getSubsCategories([]) {
try {
const response = await axios.get(`/api/categories/sub/${mainCategory}`)
console.log("sub", response.data)
setSubcategory(response.data)
setSubcategory(Object.values(response.data)[0])
console.log("response data=", response.data)
console.log("object value=", Object.values(response.data));
} catch (error) {
catchError(error, setError)
catchError(error, setError)
}
}
......@@ -59,29 +43,14 @@ function ProductsList({ match }) {
const response = await axios.get(`/api/product/getproduct/${mainCategory}`)
console.log("response.data=", response.data)
setProductlist(response.data)
} catch (error) {
catchError(error, setError)
}
}
function handleClick(e){
e.preventDefault()
return getsubproductlist()
}
async function getsubproductlist(){
try {
const response = await axios.get(`/api/product/getproduct/${subcategory}`)
console.log("response.data sub=",response.data)
setProductlist(response.data)
} catch (error) {
catchErrors(error,setError)
catchError(error, setError)
}
}
return (
<div>
{console.log("main=",mainCategory)}
<style type="text/css">
{`
a, a:hover, a:active {
......@@ -101,36 +70,36 @@ function ProductsList({ match }) {
`}
</style>
<Container>
<Row className="justify-content-center" >
<Row className="justify-content-center">
<Col sm={10} xs={12} >
<h1 style={{ fontSize: "3rem" }} className="text-center">{mainCategory}</h1>
<div className="text-center">{subcategory.map((ele) => (
<Button className="m-1" onClick={(ele) => handleClick(ele)}>{ele}</Button>
))}</div>
<div className="text-center">
<ButtonGroup className="d-flex flex-wrap" variant="outline-light secondary">
{subcategory.map(el => (<Button className="m-1" variant="secondary">{el}</Button>))}
</ButtonGroup>
</div>
</Col>
</Row>
<Row className="justify-content-end mx-0 my-5">
{/* <Form as={Row} onSubmit={handleSubmit} className="justify-content-end mx-0"> */}
<Dropdown>
<Dropdown.Toggle className="mx-2">정렬</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item>인기상품</Dropdown.Item>
<Dropdown.Item>신상품</Dropdown.Item>
<Dropdown.Item>낮은가격</Dropdown.Item>
<Dropdown.Item>높은가격</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Form as={Row} onSubmit={handleSearch} className="justify-content-end mx-0">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="search px-2">
<img src="/icon/search.svg" width="20" height="20" />
</Button>
</Form>
{/* </Form> */}
<Dropdown>
<Dropdown.Toggle className="mx-2">정렬</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item>인기상품</Dropdown.Item>
<Dropdown.Item>신상품</Dropdown.Item>
<Dropdown.Item>낮은가격</Dropdown.Item>
<Dropdown.Item>높은가격</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Form as={Row} onSubmit={handleSearch} className="justify-content-end mx-0">
<FormControl type="text" placeholder="Search" style={{ width: "13rem" }} />
<Button type="submit" className="search px-2">
<img src="/icon/search.svg" width="20" height="20" />
</Button>
</Form>
</Row>
<Row md={8} sm={12} className="justify-content-start m-2">
<Row md={8} sm={12} className="justify-content-center m-2">
{productlist.map(pro => (
<Link to={{
<ListCard as={Link} id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} to={{
pathname: `/product/${pro._id}`,
state: {
id: pro._id,
......@@ -142,13 +111,10 @@ function ProductsList({ match }) {
main_img: pro.main_imgUrl,
detail_imgs: pro.detail_imgUrls
}
}}>
<ListCard id={pro._id} name={pro.pro_name} price={pro.price} main_img={pro.main_imgUrl} />
</Link>
}} />
))}
</Row>
</Container>
{/* <Pagination postsPerPage={postsPerPage} totalPosts={posts.length} paginate={paginate} /> */}
</div>
)
}
......
import axios from "axios"
import axios from "axios";
export function handleLogin({userId,role,name}){
localStorage.setItem('id',userId)
localStorage.setItem('role',role)
localStorage.setItem('name',name)
export function handleLogin({ userId, role, name, tel }) {
localStorage.setItem('id', userId)
localStorage.setItem('role', role)
localStorage.setItem('name', name)
localStorage.setItem('tel', tel)
}
export async function handleLogout(){
localStorage.removeItem('id')
localStorage.removeItem('role')
localStorage.removeItem('name')
export async function handleLogout() {
localStorage.clear()
await axios.get('/api/auth/logout')
window.location.href = '/'
}
export function isAuthenticated(){
const userId= localStorage.getItem('id')
if(userId){
export function isAuthenticated() {
const userId = localStorage.getItem('id')
if (userId) {
return userId
} else {
return false
return false
}
}
export function isAdmin() {
const role = localStorage.getItem('role')
if (role === 'admin') {
return true
} else {
return false
}
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ const login = async (req, res) => {
const { id, password } = req.body
console.log(id, password)
try {
const user = await User.findOne({ id }).select('password role name')
const user = await User.findOne({ id }).select('password role name tel')
console.log('u=', user)
if (!user) {
return res.status(404).send(`${id}가 존재하지 않습니다.`)
......@@ -23,7 +23,7 @@ const login = async (req, res) => {
httpOnly: true,
secure: config.env === 'production'
})
res.json({ userId: user._id, role: user.role, name: user.name })
res.json({ userId: user._id, role: user.role, name: user.name, tel: user.tel })
} else {
res.status(401).send('비밀번호가 일치하지 않습니다.')
......
import Category from "../schemas/Category.js";
const getCategory = async (req, res) => {
console.log("dsadd=")
try {
const category = await Category.find({}, {_id: 0})
const category = await Category.find({}, { _id: 0 })
console.log("main= ", category);
res.json(category)
} catch (error) {
console.log(error)
......@@ -11,16 +11,60 @@ const getCategory = async (req, res) => {
}
}
const getSubCategory=(req,res)=>{
const getSubCategory = async (req, res) => {
console.log("req.params=", req.params);
const { sub } = req.params
try {
const subcategory = await Category.findOne({}, { _id: 0}).select(`${sub}`)
console.log("sub= ",subcategory);
res.json(subcategory);
} catch (error) {
res.status(500).send('카테고리를 불러오지 못했습니다.')
}
}
const getsubId=(req,res,next,sub)=>{
// const subcategory = await category.find({"Dress"})
console.log('sub=',sub)
const getToHome = async (res, req) => {
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('상품을 불러오지 못했습니다.')
}
}
const getsubId = async (req, res, next, ele) => {
try {
const sub = await Category.find({ele})
if (!sub) {
res.status(404).send('카테고리가 존재하지 않습니다.')
} req.category = sub
req.subcategory = sub
next()
}
catch (error) {
console.log(error);
res.status(500).send('카테고리를 불러오지 못했습니다.')
}
next()
}
// const userById = async (req, res, next, id) => {
// try {
// const user = await User.findById(id)
// if (!user) {
// res.status(404).send('사용자를 찾을 수 없습니다')
// }
// req.account = user
// next()
// } catch (error) {
// console.log(error);
// res.status(500).send('사용자 아이디 검색 실패')
// }
// }
export default { getCategory , getsubId, getSubCategory}
\ No newline at end of file
export default { getCategory, getsubId, getSubCategory, getToHome }
\ No newline at end of file
......@@ -6,10 +6,10 @@ const upload = multer({ dest: 'uploads/' })
const imageUpload = upload.fields([
{ name: 'main_image' },
{ name: 'detail_image' }
])
])
const regist = async (req, res) => {
console.log("req.body=",req.body)
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]
......@@ -29,30 +29,38 @@ const regist = async (req, res) => {
}
}
const getToHome = async (res, req) => {
const getToHome = async (req, res) => {
try {
const bestProduct = await Product.find({}).sort({ purchase: 1 }).limit(6)
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)
console.log("best=", bestProduct)
console.log("new=", newProduct)
res.json({ bestProduct, newProduct })
} catch {
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
const getlist=(req,res)=>{
const getAll = async (req, res) => {
try {
res.json(req.productslist)
const productslist = await Product.find({}).sort({ createdAt: -1 })
res.json(productslist)
} catch (error) {
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
const getlist = (req, res) => {
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})
const productslist = await Product.find({ main_category: category })
if (!productslist) {
res.status(404).send('상품을 찾을 수 없습니다.')
}
......@@ -63,16 +71,17 @@ const categoryId = async (req, res, next, category) => {
}
}
const subgetlist=(req,res)=>{
try{
const subgetlist = (req, res) => {
try {
res.json(req.subproductslist)
}catch(error){
} catch (error) {
res.status(500).send('상품을 불러오지 못했습니다.')
}
}
const subcategoryId = async (req, res, next, subcategory) => {
try {
const subproductslist = await Product.find({sub_category:subcategory})
const subproductslist = await Product.find({ sub_category: subcategory })
if (!subproductslist) {
res.status(404).send('상품을 찾을 수 없습니다.')
}
......@@ -83,4 +92,4 @@ const subcategoryId = async (req, res, next, subcategory) => {
}
}
export default { imageUpload, regist, categoryId, getlist, subcategoryId, subgetlist, getToHome }
export default { imageUpload, regist, getToHome, getAll, categoryId, getlist, subcategoryId, subgetlist }
\ No newline at end of file
......@@ -6,15 +6,6 @@ import multer from "multer";
const uploadimg = multer({ dest: 'uploads/' });
const getUser = async (req, res) => {
try {
const user = await User.findOne({ _id: req.id })
res.json(user)
} catch (error) {
res.status(500).send('사용자 정보를 불러올 수 없습니다.')
}
}
const imgUpload = uploadimg.fields([
{ name: 'avatar', maxCount: 1 }
])
......@@ -31,7 +22,6 @@ const userById = async (req, res, next, id) => {
res.status(404).send('사용자를 찾을 수 없습니다')
}
req.account = user
req.id = id
next()
} catch (error) {
console.log(error);
......@@ -41,9 +31,7 @@ const userById = async (req, res, next, id) => {
const signup = async (req, res) => {
const { name, number1, number2, id, password, tel } = req.body
console.log(req.body)
try {
if (!isLength(password, { min: 8, max: 15 })) {
......@@ -96,4 +84,4 @@ const update = async (req, res) => {
}
}
export default { getUser, signup, username, imgUpload, userById, update }
\ No newline at end of file
export default { signup, username, imgUpload, userById, update }
\ No newline at end of file
......@@ -9,6 +9,6 @@ router.route('/main')
router.route('/sub/:sub')
.get(categoryCtrl.getSubCategory)
router.param('sub',categoryCtrl.getsubId)
// router.param('sub',categoryCtrl.getsubId)
export default router
\ No newline at end of file
......@@ -10,6 +10,9 @@ router.route('/regist')
router.route('/getproduct')
.get(productCtrl.getToHome)
router.route('/getproduct/all')
.get(productCtrl.getAll)
router.route('/getproduct/:category')
.get(productCtrl.getlist)
......
......@@ -10,10 +10,6 @@ router.route('/account/:userId')
.get(userCtrl.username)
.put(userCtrl.imgUpload, userCtrl.update)
router.route('/getuser/:userId')
.get(userCtrl.getUser)
router.param('userId', userCtrl.userById)
export default router
\ No newline at end of file
......@@ -21,11 +21,11 @@ const ProductSchema = new mongoose.Schema({
default: 0
},
sizes: {
type: Array,
type: [String],
required: true
},
colors: {
type: Array,
type: [String],
required: true
},
main_category: {
......
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