Commit 5f0483b4 authored by kusang96's avatar kusang96
Browse files

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

parents c61f522c 0a98a6e0
...@@ -24,5 +24,6 @@ yarn-error.log* ...@@ -24,5 +24,6 @@ yarn-error.log*
package-lock.json package-lock.json
.eslintcache .eslintcache
debug.log
.yarn.lock .yarn.lock
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.11.6", "@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2", "@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.6.0", "@testing-library/user-event": "^12.6.0",
"axios": "^0.21.1",
"bootstrap": "^4.5.3", "bootstrap": "^4.5.3",
"react": "^17.0.1", "react": "^17.0.1",
"react-bootstrap": "^1.4.0", "react-bootstrap": "^1.4.0",
...@@ -39,5 +40,5 @@ ...@@ -39,5 +40,5 @@
"last 1 safari version" "last 1 safari version"
] ]
}, },
"proxy":"http://localhost:3001" "proxy": "http://localhost:3001"
} }
...@@ -22,7 +22,7 @@ function SubNav() { ...@@ -22,7 +22,7 @@ function SubNav() {
} }
return ( return (
<Navbar sticky="top" className="flex-nowrap" style={{ top: "62px", paddingTop: "0", paddingBottom: "0", backgroundColor: "#fff", overflowX: "auto" }}> <Navbar sticky="top" className="flex-nowrap" style={{ top: "62px", paddingTop: "0", paddingBottom: "0", backgroundColor: "#fff"}}>
<style type="text/css"> <style type="text/css">
{` {`
.nav-link, .nav-link:hover, .nav-link:active { .nav-link, .nav-link:hover, .nav-link:active {
......
import React from 'react'
import MainNav from '../Components/MainNav'
import SubNav from '../Components/SubNav'
function Account() {
return (
<div>
<MainNav />
<SubNav />
<h5>마이페이지</h5>
</div>
)
}
export default Account
...@@ -3,7 +3,7 @@ import MainNav from '../Components/MainNav'; ...@@ -3,7 +3,7 @@ import MainNav from '../Components/MainNav';
import SubNav from '../Components/SubNav'; import SubNav from '../Components/SubNav';
import Pagination from '../Components/Pagination'; import Pagination from '../Components/Pagination';
import search from '../search.svg'; import search from '../search.svg';
import { Row, Col, Form, FormControl, Button, Card } from 'react-bootstrap'; import { Row, Col, Form, FormControl, Button, Card, Container } from 'react-bootstrap';
function Admin() { function Admin() {
function handleClick(e) { function handleClick(e) {
...@@ -29,17 +29,16 @@ function Admin() { ...@@ -29,17 +29,16 @@ function Admin() {
</style> </style>
<MainNav /> <MainNav />
<SubNav /> <SubNav />
<Row className="justify-content-end mt-5 mr-3 mb-5"> <Container>
<Col as={Form} inline className="justify-content-end"> <Row className="justify-content-end mt-5 mb-5">
<FormControl type="text" placeholder="Search" className="mr-1" /> <FormControl type="text" placeholder="Search" style={{width:"13rem"}} />
<Button type="submit" className="px-2"> <Button type="submit" className="px-2">
<img src={search} width="20" height="20" /> <img src={search} width="20" height="20" />
</Button> </Button>
</Col> <Button sm={2} xs={6} type="button" href="/regist" className="ml-1">상품 등록</Button>
<Col sm={2} xs={3} as={Button} type="button" href="/regist">상품 등록</Col>
</Row> </Row>
<Row className="justify-content-start m-5"> <Row className="justify-content-start m-5">
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://img.sonyunara.com/files/goods/67460/1607053816_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>케이시앵글부츠(SH)</Card.Title> <Card.Title>케이시앵글부츠(SH)</Card.Title>
...@@ -50,7 +49,7 @@ function Admin() { ...@@ -50,7 +49,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://img.sonyunara.com/files/goods/48705/1552562469_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>메리제인플랫(SH)</Card.Title> <Card.Title>메리제인플랫(SH)</Card.Title>
...@@ -61,7 +60,7 @@ function Admin() { ...@@ -61,7 +60,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://img.sonyunara.com/files/goods/53386/1567390097_2.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>솔티드스니커즈(SH)</Card.Title> <Card.Title>솔티드스니커즈(SH)</Card.Title>
...@@ -72,7 +71,7 @@ function Admin() { ...@@ -72,7 +71,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://img.sonyunara.com/files/goods/61286/1587540563_0.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>버켄슬리퍼(SH)</Card.Title> <Card.Title>버켄슬리퍼(SH)</Card.Title>
...@@ -83,7 +82,7 @@ function Admin() { ...@@ -83,7 +82,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://hotping.co.kr/web/product/big/202011/b8f4c6471955b80fc3991b7d6df8926a.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>크레센도 하이힐펌프스</Card.Title> <Card.Title>크레센도 하이힐펌프스</Card.Title>
...@@ -94,7 +93,7 @@ function Admin() { ...@@ -94,7 +93,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://hotping.co.kr/web/product/big/202011/888e4e8d6a2c2e7da385b079151fcba2.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>어텀솔져1cm 스웨이드로퍼</Card.Title> <Card.Title>어텀솔져1cm 스웨이드로퍼</Card.Title>
...@@ -105,7 +104,7 @@ function Admin() { ...@@ -105,7 +104,7 @@ function Admin() {
<Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button> <Button className="float-right" onClick={(e) => handleClick(e)}>삭제</Button>
</Card.Body> </Card.Body>
</Card> </Card>
<Card className="my-5" style={{ width: "18rem", margin: "auto"}}> <Card className="my-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.Img variant="top" src="https://hotping.co.kr/web/product/big/202007/3308564012eb14e6c11ed621fa7555fb.jpg" style={{ objectFit: "contain", height: "22rem" }} />
<Card.Body> <Card.Body>
<Card.Title>포웰3.5cm 스니커즈</Card.Title> <Card.Title>포웰3.5cm 스니커즈</Card.Title>
...@@ -118,6 +117,7 @@ function Admin() { ...@@ -118,6 +117,7 @@ function Admin() {
</Card> </Card>
</Row> </Row>
<Pagination /> <Pagination />
</Container>
</div> </div>
) )
......
...@@ -2,7 +2,8 @@ import React, { useState, useEffect, useRef } from 'react'; ...@@ -2,7 +2,8 @@ import React, { useState, useEffect, useRef } from 'react';
import MainNav from '../Components/MainNav'; import MainNav from '../Components/MainNav';
import SubNav from '../Components/SubNav'; import SubNav from '../Components/SubNav';
import DaumPostcode from "react-daum-postcode"; import DaumPostcode from "react-daum-postcode";
import { Container, Card, Row, Col, Button, Form } from 'react-bootstrap'; import { Container, Card, Row, Col, Button, Form, FormGroup } from 'react-bootstrap';
import { Redirect } from 'react-router-dom';
function Payment() { function Payment() {
...@@ -11,6 +12,9 @@ function Payment() { ...@@ -11,6 +12,9 @@ function Payment() {
const [isZoneCode, setIsZoneCode] = useState(); const [isZoneCode, setIsZoneCode] = useState();
const [isPostOpen, setIsPostOpen] = useState(); const [isPostOpen, setIsPostOpen] = useState();
const [post, setPost] = useState([]) const [post, setPost] = useState([])
const [redirect, setRedirect] = useState(null)
const [address, setAddress] = useState("")
const [num, setNum] = useState(0)
function postClick() { function postClick() {
if (post.length !== 0) { if (post.length !== 0) {
...@@ -19,20 +23,20 @@ function Payment() { ...@@ -19,20 +23,20 @@ function Payment() {
else { else {
setPost( setPost(
<div> <div>
<DaumPostcode style={postCodeStyle} onComplete={handleComplete} /> <DaumPostcode style={postCodeStyle} onComplete={handleComplete} autoClose={true} />
</div> </div>
) )
} }
} }
const handleComplete = (data) => { const handleComplete = (data) => {
let fullAddress = data.address; let fullAddress = data.address;
let extraAddress = ""; let extraAddress = "";
console.log(data)
if (data.addressType === "R") { if (data.addressType === "R") {
if (data.bname !== "") { if (data.bname !== "") {
extraAddress += data.bname; extraAddress += data.bname;
console.log(extraAddress)
} }
if (data.buildingName !== "") { if (data.buildingName !== "") {
extraAddress += extraAddress +=
...@@ -40,27 +44,28 @@ function Payment() { ...@@ -40,27 +44,28 @@ function Payment() {
} }
fullAddress += extraAddress !== "" ? ` (${extraAddress})` : ""; fullAddress += extraAddress !== "" ? ` (${extraAddress})` : "";
} }
setIsZoneCode(data.zonecode); setAddress({ full: fullAddress, zone: data.zonecode });
setIsAddress(fullAddress);
setIsPostOpen(false); console.log(fullAddress);
}; }
const postCodeStyle = { const postCodeStyle = {
display: "block", // display: "block",
position: "absolute", position: "absolute",
// top: "50%",
width: "400px", width: "400px",
height: "500px", height: "500px",
padding: "7px", padding: "7px",
zIndex: "1000"
}; };
function handleClick() { function handleClick() {
if (paymentWay.length !== 0) { if (paymentWay.length !== 0) {
setPaymentWay([]) setPaymentWay([])
} }
else { else {
const a = ( const a = (
<div> <Row className="justify-content-md-center">
<Col md={6} className="border m-5 p-5">
<Form> <Form>
<Form.Group controlId="exampleForm.ControlSelect1"> <Form.Group controlId="exampleForm.ControlSelect1">
<Form.Label>입금은행</Form.Label> <Form.Label>입금은행</Form.Label>
...@@ -79,7 +84,9 @@ function Payment() { ...@@ -79,7 +84,9 @@ function Payment() {
<Form.Control type="date" /> <Form.Control type="date" />
</Form.Group> </Form.Group>
</Form> </Form>
</div>) </Col>
</Row>)
setPaymentWay(a) setPaymentWay(a)
} }
} }
...@@ -90,6 +97,54 @@ function Payment() { ...@@ -90,6 +97,54 @@ function Payment() {
} }
} }
async function kakaopay() {
const response = await fetch('/api/kakaopay/test/single', {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
cid: 'TC0ONETIME',
partner_order_id: 'partner_order_id',
partner_user_id: 'partner_user_id',
item_name: '앙고라 반목 폴라 베이직 모헤어 니트 (T)',
quantity: 1,
total_amount: 22000,
vat_amount: 200,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/kakaopay/success',
fail_url: 'http://localhost:3000/kakaopay/fail',
cancel_url: 'http://localhost:3000/kakaopay/cancel',
})
})
const data = await response.json()
console.log(data)
window.location.href = data.redirect_url
// setRedirect(data.redirect_url)
}
function plusNum() {
setNum(num + 1)
}
function minusNum() {
if (num === 0) {
setNum(0)
}
else {
setNum(num - 1)
}
}
function deleteCart() {
//장바구니 DB에서 해당 항목 삭제
console.log('카트에 담긴 항목을 삭제했습니다.')
}
if (redirect) {
console.log(redirect)
return <Redirect to={'/kakao'} />
}
return ( return (
<div> <div>
<MainNav /> <MainNav />
...@@ -98,6 +153,8 @@ function Payment() { ...@@ -98,6 +153,8 @@ function Payment() {
<h3 className="my-5 font-weight-bold text-center">주문/결제</h3> <h3 className="my-5 font-weight-bold text-center">주문/결제</h3>
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문자 정보</h5>
<Row className="justify-content-md-center">
<Col md={4}>
<Form> <Form>
<Form.Group controlId="formBasicName"> <Form.Group controlId="formBasicName">
<Form.Label>이름</Form.Label> <Form.Label>이름</Form.Label>
...@@ -112,41 +169,68 @@ function Payment() { ...@@ -112,41 +169,68 @@ function Payment() {
<Form.Control type="tel" placeholder="010-0000-0000" /> <Form.Control type="tel" placeholder="010-0000-0000" />
</Form.Group> </Form.Group>
</Form> </Form>
</Col>
</Row>
</div> </div>
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>배송지 정보</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>받는사람 정보</h5>
<Row> <Row className="justify-content-center">
<Col md={8}>
<Form>
<Form.Group>
<Form.Label>이름</Form.Label>
<Form.Control></Form.Control>
</Form.Group>
<Form.Group controlId="formBasicAdd">
<Form.Label>주소</Form.Label>
<Form.Row>
<Col xs={4} sm={4}>
<Form.Control type="text" id="add" value={address.zone} disabled={(address.zone == null) ? false : true} placeholder="우편번호" required ></Form.Control>
</Col>
<Col >
<Button style={{ background: '#91877F', borderColor: '#91877F' }} className="mx-1" onClick={postClick}>우편번호</Button>
{post}
</Col>
</Form.Row>
<Form.Row>
<Col> <Col>
<Button className="my-3" style={{ background: "#91877F", borderColor: '#91877F' }} onClick={postClick}>우편번호</Button> <Form.Control type="text" id="add1" value={address.full} disabled={(address.zone == null) ? false : true} placeholder="주소" required></Form.Control>
<Form.Control type="text" id="add2" placeholder="상세주소" required></Form.Control>
<Form.Control.Feedback type="invalid" > 상세 주소를 입력하세요. </Form.Control.Feedback>
</Col>
</Form.Row>
</Form.Group>
<Form.Group>
<Form.Label>휴대전화</Form.Label>
<Form.Control></Form.Control>
</Form.Group>
</Form>
</Col> </Col>
</Row> </Row>
{post}
</div> </div>
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>주문상품정보</h5>
<Card > <Card >
<Row> <Row className="mx-1">
<Col className="text-center align-self-center"> <Col xs={2} sm={2} className="text-center my-auto">
<input className="" type="checkbox" id="exampleCheck1"></input> <input className="" type="checkbox" id="exampleCheck1" />
</Col> </Col>
<Col> <Col className="text-center">
<Card.Img className="img-fluid" variant="top" src="img/asd.jpg" style={{ width: '20rem' }} /> <Card.Img className="img-fluid" variant="top" src="img/asd.jpg" style={{ width: '20rem' }} />
</Col> </Col>
<Col> <Col md={6} className="p-2">
<Card.Body> <Card.Body>
<img src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" /> <input type="image" 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.Title className="font-weight-bold mt-3">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
<Card.Text>옵션</Card.Text> <Card.Text>옵션</Card.Text>
<div className="align-items-center" > <Card.Text>수량</Card.Text>
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" /> <div>
<input type="text" placeholder="1" style={{ width: '30px' }} className="text-center align-middle mx-1" readOnly></input> <input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={minusNum} />
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" /> <input type="text" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder="1" value={num} readOnly></input>
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={plusNum} />
</div> </div>
</Card.Body> </Card.Body>
</Col> </Col>
...@@ -172,12 +256,14 @@ function Payment() { ...@@ -172,12 +256,14 @@ function Payment() {
<div> <div>
<h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>결제수단</h5> <h5 className="font-weight-bold py-3 border-top border-bottom text-center" style={{ background: '#F7F3F3' }}>결제수단</h5>
<div className="text-center"> <div className="text-center mt-5">
<Button variant="success" onClick={handleClick} >무통장입금</Button> <Button variant="success" className="align-top" onClick={handleClick} >무통장입금</Button>
<Button variant="warning" style={{ color: '#ffffff' }} onClick={handleClick2}>카카오페이</Button> <input type="image" src="img/payment_icon_yellow_small.png" onClick={kakaopay} />
</div> </div>
{paymentWay} {paymentWay}
</div>
<div className="text-center">
<Button className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} href="/account" block>결제완료</Button>
</div> </div>
</Container> </Container>
</div> </div>
......
...@@ -2,58 +2,81 @@ import React, { useState, useEffect, useRef } from 'react'; ...@@ -2,58 +2,81 @@ import React, { useState, useEffect, useRef } from 'react';
import Nav1 from '../Components/MainNav'; import Nav1 from '../Components/MainNav';
import Nav2 from '../Components/SubNav'; import Nav2 from '../Components/SubNav';
import { Row, Col, Button, Form, Container } from 'react-bootstrap'; import { Row, Col, Button, Form, Container } from 'react-bootstrap';
import axios from 'axios'
function ProductsRegist() { function ProductsRegist() {
const [product, setProduct] = useState()
function handleChange(event) {
const { name, value } = event.target
setProduct({ ...product, [name]: value })
}
function handleSubmit(e) {
e.preventDefault()
axios.post('/api/products/regist', {
product
}).then(function(res) {
console.log("client의 res=", res)
})
}
return ( return (
<div> <div>
{console.log(product)}
<Nav1 /> <Nav1 />
<Nav2 /> <Nav2 />
<Container> <Container>
<Row className="justify-content-md-center"> <Row className="justify-content-md-center">
<Col md={6} className="border m-5 p-3" style={{background:'#F7F3F3'}}> <Col md={6} className="border m-5 p-3" style={{ background: '#F7F3F3' }}>
<h2 className="text-center mt-5 font-weight-bold">상품등록</h2> <h2 className="text-center mt-5 font-weight-bold">상품등록</h2>
<Form className="p-5"> <Form className="p-5" onSubmit={handleSubmit}>
<Form.Group controlId="productNameform"> <Form.Group controlId="productNameform">
<Form.Label>상품명</Form.Label> <Form.Label>상품명</Form.Label>
<Form.Control type="text" placeholder="상품명" /> <Form.Control type="text" name="pro_name" placeholder="상품명" onChange={handleChange} />
</Form.Group> </Form.Group>
<Form.Group controlId="productAmountform"> <Form.Group controlId="productAmountform">
<Form.Label>수량</Form.Label> <Form.Label>재고</Form.Label>
<Form.Control type="text" placeholder="숫자만 입력해주세요" /> <Form.Control type="text" name="stock" placeholder="숫자만 입력해주세요" onChange={handleChange} />
</Form.Group> </Form.Group>
<Form.Group controlId="productPriceform"> <Form.Group controlId="productPriceform">
<Form.Label>가격</Form.Label> <Form.Label>가격</Form.Label>
<Form.Control type="text" placeholder="숫자만 입력해주세요" /> <Form.Control type="text" name="price" placeholder="숫자만 입력해주세요" onChange={handleChange} />
</Form.Group> </Form.Group>
<Form.Group> <Form.Group>
<Form.Label>분류</Form.Label> <Form.Label>분류</Form.Label>
<Row> <Row>
<Col md={6}> <Col md={6}>
<Form.Control as="select" placeholder="상위분류"> <Form.Control as="select" name="main_category" placeholder="상위분류" onChange={handleChange}>
<option>Pants</option> <option>Pants</option>
<option>Skirt</option> <option>Skirt</option>
<option>Outer</option> <option>Outer</option>
</Form.Control> </Form.Control>
</Col> </Col>
<Col md={6}> <Col md={6}>
<Form.Control as="select" placeholder="하위분류"> <Form.Control as="select" name="sub_category" placeholder="하위분류" onChange={handleChange}>
<option>긴바지</option> <option>JEANS</option>
<option>반바지</option> <option>SKINNY JEANS</option>
<option>청바지</option> <option>BANDING PANTS</option>
</Form.Control> </Form.Control>
</Col> </Col>
</Row> </Row>
</Form.Group> </Form.Group>
<Form.Group controlId="productDescriptionform"> <Form.Group controlId="productDescriptionform">
<Form.Label>상품설명</Form.Label> <Form.Label>상품설명</Form.Label>
<Form.Control as="textarea" rows={3} placeholder="상품을 설명해주세요" /> <Form.Control as="textarea" name="description" rows={3} placeholder="상품을 설명해주세요" onChange={handleChange} />
</Form.Group> </Form.Group>
<Form.Group> <Form.Group>
<Form.Label>대표이미지</Form.Label> <Form.Label>대표이미지</Form.Label>
<Form.File id="productImageform" /> <Form.File id="productImageform" name="main_image" onChange={handleChange} />
</Form.Group>
<Form.Group>
<Form.Label>상세이미지</Form.Label>
<Form.File id="productImageform" name="detail_image" onChange={handleChange} />
</Form.Group> </Form.Group>
<Button className="float-right" variant="primary" type="submit" style={{background:'#91877F', borderColor:'#91877F'}}>등록</Button> <Button className="float-right" variant="primary" type="submit" style={{ background: '#91877F', borderColor: '#91877F' }}>등록</Button>
</Form> </Form>
</Col> </Col>
</Row> </Row>
......
...@@ -6,6 +6,25 @@ import { Card, Button, Container, Row, Col } from 'react-bootstrap'; ...@@ -6,6 +6,25 @@ import { Card, Button, Container, Row, Col } from 'react-bootstrap';
function ShoppingCart() { function ShoppingCart() {
const [num, setNum] = useState(0)
function plusNum() {
setNum(num + 1)
}
function minusNum() {
if (num === 0) {
setNum(0)
}
else {
setNum(num - 1)
}
}
function deleteCart() {
//장바구니 DB에서 해당 항목 삭제
console.log('카트에 담긴 항목을 삭제했습니다.')
}
return ( return (
<div> <div>
<MainNav /> <MainNav />
...@@ -14,52 +33,32 @@ function ShoppingCart() { ...@@ -14,52 +33,32 @@ function ShoppingCart() {
<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 >
<Row>
<Col>
<input className="mx-5" type="checkbox" id="exampleCheck1"></input>
<Card.Img className="img-fluid" variant="top" src="img/asd.jpg" style={{ width: '20rem' }} />
</Col>
<Col md={6}>
<Card.Body>
<input type="image" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" />
<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" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" />
<input type="text" placeholder="1" style={{ width: '30px' }} className="text-center align-middle mx-1" readOnly></input>
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" />
</div>
</Card.Body>
</Col>
</Row>
</Card>
<Card> <Card>
<Row> <Row className="mx-1">
<Col> <Col xs={2} sm={2} className="text-center my-auto">
<input className="mx-5" type="checkbox" id="exampleCheck1"></input> <input className="" type="checkbox" id="exampleCheck1" />
</Col>
<Col className="text-center">
<Card.Img className="img-fluid" variant="top" src="img/asd.jpg" style={{ width: '20rem' }} /> <Card.Img className="img-fluid" variant="top" src="img/asd.jpg" style={{ width: '20rem' }} />
</Col> </Col>
<Col> <Col md={6} className="p-2">
<Card.Body> <Card.Body>
<input type="image" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="float-right" /> <input type="image" 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.Title className="font-weight-bold mt-3">제품명</Card.Title>
<Card.Text>가격</Card.Text> <Card.Text>가격</Card.Text>
<Card.Text>옵션</Card.Text> <Card.Text>옵션</Card.Text>
<Card.Text>수량</Card.Text> <Card.Text>수량</Card.Text>
<div className="align-items-center" > <div>
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" /> <input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/minus-math.png" className="align-middle" onClick={minusNum} />
<input type="text" placeholder="1" style={{ width: '30px' }} className="text-center align-middle mx-1" readOnly></input> <input type="text" style={{ width: '30px' }} className="text-center align-middle mx-1" placeholder="1" value={num} readOnly></input>
<input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" /> <input type="image" src="https://img.icons8.com/ios-glyphs/20/000000/plus-math.png" className="align-middle" onClick={plusNum} />
</div> </div>
</Card.Body> </Card.Body>
</Col> </Col>
</Row> </Row>
</Card> </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' }}>
<li> <li>
<span className="text-secondary"> 상품금액</span> <span className="text-secondary"> 상품금액</span>
...@@ -75,7 +74,7 @@ function ShoppingCart() { ...@@ -75,7 +74,7 @@ function ShoppingCart() {
</div> </div>
</div> </div>
<div className="text-center"> <div className="text-center">
<Button className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} href="/payment">결제하기</Button> <Button className="px-5" style={{ background: "#91877F", borderColor: '#91877F' }} href="/payment" block>결제하기</Button>
</div> </div>
</Container> </Container>
......
...@@ -11,6 +11,7 @@ import ShoppingCart from './Pages/ShoppingCart'; ...@@ -11,6 +11,7 @@ import ShoppingCart from './Pages/ShoppingCart';
import Payment from './Pages/Payment'; import Payment from './Pages/Payment';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import Account from './Pages/Account';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
...@@ -24,6 +25,8 @@ ReactDOM.render( ...@@ -24,6 +25,8 @@ ReactDOM.render(
<Route path="/regist" component={ProductsRegist} /> <Route path="/regist" component={ProductsRegist} />
<Route path="/shoppingcart" component={ShoppingCart} /> <Route path="/shoppingcart" component={ShoppingCart} />
<Route path="/payment" component={Payment} /> <Route path="/payment" component={Payment} />
<Route path="/account" component={Account}/>
<Route path='/kakao' component={() => {window.location.href='https://compmath.korea.ac.kr'; return null;}}/>
<Redirect path="/" to="/" /> <Redirect path="/" to="/" />
</Switch> </Switch>
</Router> </Router>
......
import express from 'express' import express from 'express';
// import bodyParser from "body-parser";
import connectDb from './schemas/index.js' import connectDb from './schemas/index.js'
import userRouter from "./routes/user.routes.js"; import userRouter from "./routes/user.routes.js";
import productRouter from './routes/product.routes.js';
import path from 'path'
import kakaopayRoutes from './routes/kakaopay.routes.js'
import config from './config.js'
import cors from 'cors'
connectDb() connectDb()
// const createError = require('http-errors');
// const express = require('express');
// const path = require('path');
// const cookieParser = require('cookie-parser');
// const logger = require('morgan');
// const port = 3030;
// const indexRouter = require('./routes/index');
const app = express(); const app = express();
// connect();
// view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'pug');
// app.use(logger('dev'));
app.use(express.json()); app.use(express.json());
// app.use(express.urlencoded({ extended: false })); app.use(cors())
// app.use(cookieParser(process.env.JWT_SECRET));
// app.use(express.static(path.join(__dirname, 'public')));
// app.use('/', indexRouter); app.use(express.static(path.join(process.cwd(), 'dist')))
// app.use(bodyParser.urlencoded({ extended: true }))
// app.listen(port, () => console.log(port));
app.listen(3001, () => console.log('Listenning'));
// app.use('/', indexRouter);
app.use('/', kakaopayRoutes)
app.use('/api/users',userRouter) app.use('/api/users',userRouter)
app.use('/api/products', productRouter)
// catch 404 and forward to error handler app.listen(config.port, () => {
// app.use(function(req, res, next) { console.info('Server started on port %s.', config.port)
// next(createError(404)); })
// });
// error handler
// app.use(function(err, req, res, next) {
// set locals, only providing error in development
// res.locals.message = err.message;
// res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
// res.status(err.status || 500);
// res.render('error');
// });
// module.exports = app;
\ No newline at end of file
...@@ -2,7 +2,16 @@ const config = { ...@@ -2,7 +2,16 @@ const config = {
env: process.env.NODEENV || 'development', env: process.env.NODEENV || 'development',
port: process.env.PORT || 3001, port: process.env.PORT || 3001,
jwtSecret: process.env.JWT_SECRET || 'My_Secret_Key', jwtSecret: process.env.JWT_SECRET || 'My_Secret_Key',
mongoDbUri: process.env.MONGEDB_URI || 'mongodb://localhost/shopping-mall' mongoDbUri: process.env.MONGEDB_URI || 'mongodb://localhost/shopping-mall',
kakaoAdminKey: 'b2dda7685c5b2990684d813e362cff07'
} }
export default config // const config = {
\ No newline at end of file // port: 3001,
// kakaoAdminKey: 'b2dda7685c5b2990684d813e362cff07',
// }
export default config
// export default config
\ No newline at end of file
// import { RequestHandler } from "express";
import fetch from 'node-fetch'
import config from "../config.js";
const success = (req, res) => {
console.log('kakaopay success route')
console.log('req body:', req.body)
return res.json({
message: 'Success'
})
}
const fail = (req, res) => {
console.log('kakaopay fail route')
console.log('req body:', req.body)
return res.json({
message: 'Failed'
})
}
const cancel = (req, res) => {
console.log('kakaopay cancel route')
console.log('req body:', req.body)
return res.json({
message: 'Canceled'
})
}
const singleTest = async (req, res) => {
console.log("asdaf")
console.log(req.body)
const item = req.body
// set data
const data = []
for (let property in item) {
let encodedKey = encodeURIComponent(property);
let encodedValue = encodeURIComponent(item[property]);
data.push(encodedKey + "=" + encodedValue);
}
const bodyData = data.join('&') // encode data (application/x-www-form-urlencoded)
const response = await fetch('https://kapi.kakao.com/v1/payment/ready', {
method: 'POST',
headers: {
'Authorization': `KakaoAK ${config.kakaoAdminKey}`,
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
body: bodyData,
})
// console.log(response)
const resp = await response.json()
console.log(resp)
res.json({redirect_url: resp.next_redirect_pc_url})
}
export default {
success,
fail,
cancel,
singleTest,
}
import Product from "../schemas/Product.js";
const regist = async (req, res) => {
console.log('req.body=', req.body)
const { pro_name, price, stock, main_category, sub_category, description, main_image, detail_image } = req.body.product
try {
const newProduct = await new Product ({
pro_name, price, stock, main_category, sub_category, description, main_image, detail_image
}).save()
console.log(newProduct)
res.json(newProduct)
} catch (error) {
console.log(error)
res.status(500).send('죄송합니다. 다시 입력해 주십시오.')
}
}
export default { regist }
\ No newline at end of file
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1", "express": "^4.17.1",
"mongoose": "^5.11.9", "mongoose": "^5.11.9",
"node-fetch": "^2.6.1",
"nodemon": "^2.0.6", "nodemon": "^2.0.6",
"validator": "^13.5.2", "validator": "^13.5.2",
"multer": "^1.4.2" "multer": "^1.4.2"
......
import express from 'express'
import kakaopayCtrl from '../controllers/kakaopay.controller.js'
const router = express.Router()
router.route('/kakaopay/success')
.get(kakaopayCtrl.success)
router.route('/api/kakaopay/fail')
.get(kakaopayCtrl.fail)
router.route('/api/kakaopay/cancel')
.get(kakaopayCtrl.cancel)
router.route('/api/kakaopay/test/single')
.post(kakaopayCtrl.singleTest)
export default router
import express from "express";
import productCtrl from '../controllers/product.controller.js';
const router = express.Router()
router.route('/regist')
.post(productCtrl.regist)
export default router
\ No newline at end of file
import mongoose from 'mongoose'
const { String, Number, Array } = mongoose.Schema.Types
const ProductSchema = new mongoose.Schema({
pro_name: {
type: String,
required: true,
},
price: {
type: String,
required: true,
},
stock: {
type: String,
required: true
},
purchase: {
type: String,
required: true,
default: 0
},
main_category: {
type: String,
required: true,
},
sub_category: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
main_image: {
type: String,
required: true,
},
detail_image: {
type: String,
required: true,
}
}, {
timestamps: true
})
export default mongoose.models.Product || mongoose.model('Product', ProductSchema)
\ No newline at end of file
import mongoose from 'mongoose'
const { String } = mongoose.Schema.Types
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
id: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
select: false
},
confirm_password:{
type: String,
required: true,
select: false
},
phoneNumber: {
type: String,
required: true,
},
role: {
type: String,
required: true,
default: 'user',
enum: ['user', 'admin', 'root']
},
birth: {
type: String,
required: true,
},
sex: {
type: String,
required: true,
}
}, {
timestamps: true
})
export default mongoose.models.User || mongoose.model('User', UserSchema)
\ 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