Product.js 13.4 KB
Newer Older
kusang96's avatar
kusang96 committed
1
import React, { useState, useEffect, useRef } from 'react';
Jiwon Yoon's avatar
Jiwon Yoon committed
2
import { Redirect, useHistory } from 'react-router-dom';
3
import axios from 'axios';
4
import catchErrors from '../utils/catchErrors';
5
import { Row, Col, Form, Card, Button, Modal, Image } from 'react-bootstrap';
kusang96's avatar
kusang96 committed
6
7


8
function Product({ match, location }) {
kusang96's avatar
0115    
kusang96 committed
9
    const [product, setProduct] = useState(location.state)
Jiwon Yoon's avatar
Jiwon Yoon committed
10
11
12
    const [color, setColor] = useState("")
    const [size, setSize] = useState("")
    const [cart, setCart] = useState([])
13
    const [error, setError] = useState('')
14
    const [selected, setSelected] = useState({ sizes: false, colors: false })
Jiwon Yoon's avatar
Jiwon Yoon committed
15
    const [count, setCount] = useState(1)
Jiwon Yoon's avatar
0113    
Jiwon Yoon committed
16
    const [price, setPrice] = useState(0)
Jiwon Yoon's avatar
Jiwon Yoon committed
17
18
19
20
    const [show, setShow] = useState(false);
    let history = useHistory();
    const handleClose = () => setShow(false);
    const handleShow = () => setShow(true);
Jiwon Yoon's avatar
Jiwon Yoon committed
21

22
    useEffect(() => {
Jiwon Yoon's avatar
Jiwon Yoon committed
23
        if (size && color) {
24
            pushOptions()
Jiwon Yoon's avatar
Jiwon Yoon committed
25
        }
Jiwon Yoon's avatar
Jiwon Yoon committed
26
    }, [size, color])
kusang96's avatar
kusang96 committed
27
28
29
30
31
32

    function handleClick(e) {
        const box = e.target.parentNode.parentNode
        box.style.display = "none"
    }

33
    function pushOptions() {
kusang96's avatar
kusang96 committed
34
35
36
37
38
        const cartSet = cart.map(el => {
            const newObj = {}
            newObj["color"] = el.color;
            newObj["size"] = el.size;
            return newObj
Jiwon Yoon's avatar
Jiwon Yoon committed
39
        })
kusang96's avatar
kusang96 committed
40
        const isDuplicated = cartSet.some(el => el.color === color && el.size === size)
Jiwon Yoon's avatar
Jiwon Yoon committed
41
42
43
44
45
46
47
48
49
        if (isDuplicated) {
            selected.sizes = false
            selected.colors = false
            setColor("")
            setSize("")
            alert("이미 선택한 옵션입니다.")
        } else {
            selected.sizes = false
            selected.colors = false
50
            setCart([...cart, { color, size, productId: product.id, count: 1, checked: false }])
Jiwon Yoon's avatar
Jiwon Yoon committed
51
52
53
54
            setColor("")
            setSize("")
            setPrice(product.price + price)
        }
55
    }
Jiwon Yoon's avatar
Jiwon Yoon committed
56

kusang96's avatar
kusang96 committed
57
58
    function handleChange(e) {
        const { name, value } = e.target
Jiwon Yoon's avatar
Jiwon Yoon committed
59
60
        if (name === "sizes") {
            setSize(value)
61
            selected.sizes = true
Jiwon Yoon's avatar
Jiwon Yoon committed
62
63
        } else if (name === "colors") {
            setColor(value)
64
65
            selected.colors = true
        }
kusang96's avatar
kusang96 committed
66
67
    }

Jiwon Yoon's avatar
Jiwon Yoon committed
68
    function deleteOption(e) {
kusang96's avatar
kusang96 committed
69
        e.preventDefault()
70
        let preprice = 0
kusang96's avatar
kusang96 committed
71
72
        const list = cart.filter((el) => el.color !== e.target.id || el.size !== e.target.name)
        list.map((el) => {
박상호's avatar
박상호 committed
73
            preprice = preprice + el.count * product.price
74
        })
kusang96's avatar
kusang96 committed
75
        setCart(list)
76
        setPrice(Number(preprice))
kusang96's avatar
kusang96 committed
77
78
    }

Jiwon Yoon's avatar
Jiwon Yoon committed
79
    function handleCount(e) {
80
81
82
        const addCount = cart.map((el) => {
            if (el.color !== e.target.id || el.size !== e.target.name) {
                return { ...el }
Jiwon Yoon's avatar
Jiwon Yoon committed
83
            } else {
84
                return { ...el, count: e.target.value }
Jiwon Yoon's avatar
Jiwon Yoon committed
85
86
            }
        })
87
        let preprice = 0
박상호's avatar
박상호 committed
88
89
        addCount.map((el) => {
            preprice = preprice + el.count * product.price
90
91
        })
        setPrice(Number(preprice))
Jiwon Yoon's avatar
Jiwon Yoon committed
92
        setCart(addCount)
Jiwon Yoon's avatar
Jiwon Yoon committed
93
        setCount(e.value)
kusang96's avatar
kusang96 committed
94
95
    }

Jiwon Yoon's avatar
Jiwon Yoon committed
96
    async function addCart(event) {
Jiwon Yoon's avatar
Jiwon Yoon committed
97
        console.log(cart)
Jiwon Yoon's avatar
Jiwon Yoon committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        if (cart.length < 1) {
            alert("옵션을 선택해주세요")
        }
        else if (localStorage.getItem('id')) {
            if (event.target.name === "shoppingcart") {
                // preCart(color, size, count), productId(productlist에서 props), userId(로컬) 를 보내줌
                try {
                    setError('')
                    const response = await axios.put('/api/cart/addcart', {
                        userId: localStorage.getItem('id'),
                        products: cart
                    })
                    console.log(response.data)
                    setShow(true)
                } catch (error) {
                    catchErrors(error, setError)
                }
            } else {
                try {
                    setError('')
118
                    cart.map((el) => {
119
120
                        el.checked = true
                    })
Jiwon Yoon's avatar
Jiwon Yoon committed
121
122
123
124
125
126
127
128
129
                    const response = await axios.put('/api/cart/addcart', {
                        userId: localStorage.getItem('id'),
                        products: cart
                    })
                    console.log(response.data)
                    history.push("/payment")
                } catch (error) {
                    catchErrors(error, setError)
                }
Jiwon Yoon's avatar
Jiwon Yoon committed
130
            }
Jiwon Yoon's avatar
Jiwon Yoon committed
131

Jiwon Yoon's avatar
Jiwon Yoon committed
132
133
134
        } else {
            alert("로그인을 해주세요.")
            return <Redirect to='/login' />
135
136
137
        }
    }

kusang96's avatar
kusang96 committed
138
139
140
141
142
143
144
145
146

    return (
        <div>
            <style type="text/css">
                {`
                .btn {
                    background-color: #CDC5C2;
                    border-color: #CDC5C2;
                }
kusang96's avatar
css    
kusang96 committed
147
148
149
150
151
152
153
154
155
156
                .btn:hover {
                    background-color: #91877F;
                    border-color: #91877F;
                }
                .btn-primary:focus {
                    background-color: #91877F;
                    border-color: #91877F;
                    box-shadow: 0 0 0 0;
                }
                .btn-primary:not(:disabled):not(.disabled):active, .show>.btn-primary.dropdown-toggle {
kusang96's avatar
kusang96 committed
157
158
159
160
161
                    background-color: #91877F;
                    border-color: #91877F;
                }
                `}
            </style>
162
163
164
165
166
167
168
169
170
171
            <Modal show={show} onHide={handleClose}>
                <Modal.Header closeButton>
                    <Modal.Title>장바구니에 상품담기</Modal.Title>
                </Modal.Header>
                <Modal.Body>정상적으로 장바구니에 상품을 담았습니다.</Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={handleClose}>쇼핑계속하기</Button>
                    <Button variant="primary" href='/shoppingcart'>장바구니로 이동</Button>
                </Modal.Footer>
            </Modal>
kusang96's avatar
kusang96 committed
172
173
            <Row className="justify-content-center mt-5 mx-0">
                <Col sm={11} md={4}>
Jiwon Yoon's avatar
asdf    
Jiwon Yoon committed
174
                    <img src={`/images/${product.main_img}`} style={{ objectFit: "contain", width: "100%" }} />
kusang96's avatar
kusang96 committed
175
176
                </Col>
                <Col sm={11} md={4} className="align-middle mt-4">
kusang96's avatar
0115    
kusang96 committed
177
178
                    <h3 className="mb-4">{product.name}</h3>
                    <h5 className="mb-4">가격 : {product.price}</h5>
kusang96's avatar
kusang96 committed
179
180
181
                    <Form style={{ borderBottom: "1px solid" }}>
                        <Form.Group style={{ borderBottom: "1px solid", paddingBottom: "2rem" }}>
                            <Form.Label>색상</Form.Label>
Jiwon Yoon's avatar
Jiwon Yoon committed
182
                            <Form.Control as="select" className="mb-2" name="colors" value={color} defaultValue="옵션 선택" onChange={handleChange}>
kusang96's avatar
kusang96 committed
183
                                <option>옵션선택</option>
Jiwon Yoon's avatar
qwr    
Jiwon Yoon committed
184
185
186
                                {product.colors.map((e) => (
                                    <option>{e}</option>
                                ))}
kusang96's avatar
kusang96 committed
187
188
                            </Form.Control>
                            <Form.Label>사이즈</Form.Label>
Jiwon Yoon's avatar
Jiwon Yoon committed
189
                            <Form.Control as="select" className="mb-2" name="sizes" value={size} defaultValue="옵션 선택" onChange={handleChange}>
kusang96's avatar
kusang96 committed
190
                                <option>옵션선택</option>
Jiwon Yoon's avatar
qwr    
Jiwon Yoon committed
191
192
193
                                {product.sizes.map((e) => (
                                    <option>{e}</option>
                                ))}
kusang96's avatar
kusang96 committed
194
195
                            </Form.Control>
                        </Form.Group>
Jiwon Yoon's avatar
Jiwon Yoon committed
196
                        {cart.map((e) => (
197
198
199
                            <Row className="mx-1">
                                <Col xs={6}>{e.color}/{e.size}</Col>
                                <Col xs={4} className="text-right" >
Jiwon Yoon's avatar
Jiwon Yoon committed
200
                                    <input type='number' id={e.color} name={e.size} onChange={handleCount} value={count} style={{ width: '3rem' }} className="text-center" />
201
202
203
204
205
                                </Col>
                                <Col xs={2} className="text-right">
                                    <input onClick={deleteOption} id={e.color} name={e.size} type="image" alt="삭제버튼" src="https://img.icons8.com/fluent-systems-regular/24/000000/close-window.png" className="align-middle" />
                                </Col>
                            </Row>
Jiwon Yoon's avatar
Jiwon Yoon committed
206

207
                        ))}
kusang96's avatar
kusang96 committed
208
209
                        <Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}>
                            <Col> 금액</Col>
Jiwon Yoon's avatar
0113    
Jiwon Yoon committed
210
                            <Col className="text-right">{price}</Col>
kusang96's avatar
kusang96 committed
211
212
                        </Row>
                        <Row className="justify-content-between mx-0 my-3" style={{ width: "100%" }}>
kusang96's avatar
css    
kusang96 committed
213
                            <Button type='button' name="shoppingcart" onClick={addCart} style={{ width: "49%" }} variant="primary" >장바구니</Button>
Jiwon Yoon's avatar
Jiwon Yoon committed
214
                            <Button type='button' name="payment" onClick={addCart} style={{ width: "49%" }}>구매하기</Button>
kusang96's avatar
kusang96 committed
215
216
217
218
219
220
                        </Row>
                    </Form>
                </Col>
            </Row>
            <Row className="justify-content-center mt-5 mx-0">
                <Col sm={11} md={8}>
박상호's avatar
박상호 committed
221
222
223
                    <h3 style={{ borderBottom: "1px solid #91877F", paddingBottom: "5px", marginBottom: "1em" }} className="p-3">
                        설명
                        </h3>
박상호's avatar
0126    
박상호 committed
224
225
226
227
228
                    <Col className='text-center' style={{ fontSize: '1px' }}>
                        <div className='p-2 text-center border' style={{ background: '#CDC5C2', width: '50%', margin: 'auto', fontSize: '3.5vmin' }} >
                            {product.name}
                        </div>
                        <Image src={`/images/${product.main_img}`} className='d-flex justify-content-center p-4' style={{ objectFit: "contain", maxWidth: "100%", margin: 'auto' }} />
박상호's avatar
박상호 committed
229
                        <Card style={{ width: '80%', margin: 'auto' }} className='my-4' >
박상호's avatar
0126    
박상호 committed
230
231
232
                            <Card.Header className='text-center' style={{ background: '#CDC5C2' }}>
                                <h5 className='m-0' style={{ whiteSpace: 'nowrap' }}> [ Description ]</h5>
                            </Card.Header>
박상호's avatar
박상호 committed
233
                            <Card.Body className='text-center m-2' style={{ whiteSpace: "pre-line", background: '#F7F3F3', fontSize: '1vw' }}>
박상호's avatar
good    
박상호 committed
234
                                <small>{product.description}</small>
235
236
                            </Card.Body>
                        </Card>
박상호's avatar
0126    
박상호 committed
237
238
239
240
241
                        <Col className='p-5'>
                            <div className='border p-2' style={{ width: '60%', margin: 'auto', fontSize: '3.5vmin' }}>[ Detail Images ]</div>
                            <Image src={`/images/${product.detail_imgs}`} style={{ objectFit: "contain", maxWidth: "100%", margin: 'auto' }} className='p-4 d-flex justify-content-center' />

                        </Col>
박상호's avatar
박상호 committed
242
                    </Col>
kusang96's avatar
kusang96 committed
243
244
245
246
247
                </Col>
            </Row>
            <Row className="justify-content-center mx-0 pt-3 px-2" style={{ position: "fixed", bottom: "0", width: "100%", backgroundColor: "#fff" }}>
                <Col sm={12} md={9}>
                    <h6 style={{ borderBottom: "1px solid", paddingBottom: "5px", marginBottom: "1em" }}>회원님이 선호할만한 상품 추천
박상호's avatar
0120    
박상호 committed
248
                        <a className="close float-right" onClick={(e) => handleClick(e)} style={{ fontSize: "1rem", cursor: "pointer" }}>X</a>
kusang96's avatar
kusang96 committed
249
                    </h6>
kusang96's avatar
css    
kusang96 committed
250
251
                    <Row className="justify-content-evenly mx-0" style={{ flexWrap: "nowrap", width: "100%", overflowX: "auto" }}>
                        <Col as={Card} style={{ minWidth: "8rem" }}>
kusang96's avatar
kusang96 committed
252
253
254
255
256
257
                            <Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67504/1607328307_0.jpg" style={{ objectFit: "contain" }} />
                            <Card.Body className="px-0">
                                <Card.Title>클로타탄원피스</Card.Title>
                                <Card.Text>구매자 : 30</Card.Text>
                            </Card.Body>
                        </Col>
kusang96's avatar
css    
kusang96 committed
258
                        <Col as={Card} style={{ minWidth: "8rem" }}>
kusang96's avatar
kusang96 committed
259
260
261
262
263
264
                            <Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67504/1607328307_0.jpg" style={{ objectFit: "contain" }} />
                            <Card.Body className="px-0">
                                <Card.Title>클로타탄원피스</Card.Title>
                                <Card.Text>구매자 : 30</Card.Text>
                            </Card.Body>
                        </Col>
kusang96's avatar
css    
kusang96 committed
265
                        <Col as={Card} style={{ minWidth: "8rem" }}>
kusang96's avatar
kusang96 committed
266
267
268
269
270
271
                            <Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67504/1607328307_0.jpg" style={{ objectFit: "contain" }} />
                            <Card.Body className="px-0">
                                <Card.Title>클로타탄원피스</Card.Title>
                                <Card.Text>구매자 : 30</Card.Text>
                            </Card.Body>
                        </Col>
kusang96's avatar
css    
kusang96 committed
272
                        <Col as={Card} style={{ minWidth: "8rem" }}>
kusang96's avatar
kusang96 committed
273
274
275
276
277
278
279
280
281
282
283
284
285
286
                            <Card.Img variant="top" src="https://img.sonyunara.com/files/goods/67504/1607328307_0.jpg" style={{ objectFit: "contain" }} />
                            <Card.Body className="px-0">
                                <Card.Title>클로타탄원피스</Card.Title>
                                <Card.Text>구매자 : 30</Card.Text>
                            </Card.Body>
                        </Col>
                    </Row>
                </Col>
            </Row>
        </div>
    )
}

export default Product