Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
students
shopping-mall
Commits
a4570666
Commit
a4570666
authored
Jan 15, 2021
by
kusang96
Browse files
Merge remote-tracking branch 'origin/sangho' into ourMaster
parents
8118cdae
1169c8dd
Changes
11
Hide whitespace changes
Inline
Side-by-side
client/src/Components/MainNav.js
View file @
a4570666
...
...
@@ -3,6 +3,7 @@ import { Navbar, Nav } from 'react-bootstrap';
import
{
handleLogout
,
isAuthenticated
}
from
'
../utils/auth
'
;
function
MainNav
()
{
const
user
=
isAuthenticated
()
return
(
...
...
@@ -11,8 +12,10 @@ function MainNav() {
<
img
alt
=
"
로고
"
src
=
"
/icon/footprint.svg
"
width
=
"
24
"
height
=
"
24
"
/>
{
'
'
}
KU
#
<
/Navbar.Brand
>
<
Nav
className
=
"
ml-auto
"
>
{
user
?
<
Nav
.
Link
className
=
"
text-light
"
onClick
=
{()
=>
handleLogout
()}
>
Logout
<
/Nav.Link
>
<
Nav
>
{
user
?
<>
<
Nav
.
Link
className
=
"
text-light
"
onClick
=
{()
=>
handleLogout
()}
>
Logout
<
/Nav.Link
>
<
Nav
.
Link
className
=
"
text-light
"
href
=
"
/account
"
>
Mypage
<
/Nav.Link
>
<
/
>
:
(
<>
<
Nav
.
Link
className
=
"
text-light
"
href
=
'
/login
'
>
Login
<
/Nav.Link
>
...
...
client/src/Components/Pagination.js
View file @
a4570666
import
React
,
{
useState
,
useEffect
,
useRef
}
from
'
react
'
;
import
React
from
'
react
'
;
import
{
Pagination
}
from
'
react-bootstrap
'
;
function
pagination
()
{
...
...
client/src/Pages/Account.js
View file @
a4570666
import
React
from
'
react
'
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
person
from
'
../person.svg
'
;
import
mypagetiger
from
'
../mypagetiger.svg
'
;
import
axios
from
'
axios
'
import
catchErrors
from
'
../utils/catchErrors
'
;
import
{
isAuthenticated
}
from
'
../utils/auth
'
;
const
INIT_ACCOUNT
=
{
name
:
""
,
avatarUrl
:
''
}
function
Account
()
{
const
[
account
,
setAccount
]
=
useState
(
INIT_ACCOUNT
)
const
[
error
,
setError
]
=
useState
(
""
)
const
userId
=
isAuthenticated
()
async
function
getUsername
(
user
)
{
// console.log("tlg")
try
{
const
response
=
await
axios
.
get
(
`/api/users/account/
${
user
}
`
)
setAccount
(
response
.
data
)
// console.log('555555555', response.data);
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
// console.log('error2222', error)
}
}
useEffect
(()
=>
{
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
)
{
for
(
const
file
of
files
)
{
// console.log("name=", name, "value=", value, 'file=', file);
}
setAccount
({
...
account
,
[
name
]:
files
})
}
else
{
console
.
log
(
"
name=
"
,
name
,
"
value=
"
,
value
);
setAccount
({
...
account
,
[
name
]:
value
})
}
}
const
handleBasic
=
async
(
event
)
=>
{
const
formData
=
new
FormData
()
formData
.
append
(
'
avatar
'
,
''
)
try
{
if
(
userId
)
{
const
response
=
await
axios
.
put
(
`/api/users/account/
${
userId
}
`
,
formData
)
console
.
log
(
response
.
data
)
window
.
location
.
reload
()
}
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
setShow
(
false
)
}
const
handleSubmit
=
async
(
event
)
=>
{
event
.
preventDefault
()
if
(
account
.
avatar
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'
avatar
'
,
account
.
avatar
[
0
])
try
{
if
(
userId
)
{
const
response
=
await
axios
.
put
(
`/api/users/account/
${
userId
}
`
,
formData
)
console
.
log
(
response
.
data
)
window
.
location
.
reload
()
}
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
else
{
alert
(
"
파일을 선택해주세요.
"
)
}
}
return
(
<
div
>
<
h5
>
마이페이지
<
/h5
>
<
/div
>
<
Container
className
=
"
px-3
"
>
<
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
}
>
{
account
.
avatarUrl
?
(
<
Image
src
=
{
account
.
avatarUrl
&&
`/image/
${
account
.
avatarUrl
}
`
}
className
=
"
img-thumbnail
"
roundedCircle
style
=
{{
objectFit
:
"
cover
"
,
width
:
"
10rem
"
,
height
:
"
10rem
"
}}
/
>
)
:
(
<
Image
src
=
{
person
}
className
=
"
img-thumbnail
"
roundedCircle
style
=
{{
objectFit
:
"
cover
"
,
width
:
"
10rem
"
,
height
:
"
10rem
"
}}
/
>
)}
<
/Button
>
<
Modal
show
=
{
show
}
onHide
=
{
handleClose
}
>
<
Modal
.
Header
closeButton
>
<
Modal
.
Title
>
이미지를
변경하시겠습니까
?
<
/Modal.Title
>
<
/Modal.Header
>
<
Form
onSubmit
=
{
handleSubmit
}
>
<
Modal
.
Body
>
<
Form
.
Control
type
=
"
file
"
name
=
"
avatar
"
onChange
=
{
handleChange
}
/
>
<
/Modal.Body
>
<
Modal
.
Footer
>
<
Col
className
=
"
px-0
"
>
<
Button
variant
=
"
outline-secondary
"
onClick
=
{
handleBasic
}
className
=
"
d-flex justify-content-start
"
><
small
>
기본이미지로
<
/small></
Button
>
{
/* 기본이미지로 보내기 */
}
<
/Col
>
<
Button
variant
=
"
secondary
"
onClick
=
{
handleClose
}
>
취소
<
/Button
>
<
Button
variant
=
"
primary
"
type
=
"
submit
"
onClick
=
{
handleClose
}
>
저장
<
/Button
>
<
/Modal.Footer
>
<
/Form
>
<
/Modal
>
<
/Col
>
<
Col
>
<
Row
className
=
"
mt-4 text-center
"
>
<
Col
>
<
h2
>
<
strong
>
{
account
.
name
}
<
/strong> <small>
(
{account.id}
)
{" "}님</
small
>
<
/h2
>
<
/Col
>
<
/Row
>
<
Row
className
=
"
px-3
"
>
<
Card
.
Body
className
=
"
p-2 text-center
"
>
<
h4
><
Link
to
=
"
/
"
class
=
"
link-warning
"
>
<
strong
title
=
"
홈으로
"
>
<
Image
src
=
{
mypagetiger
}
width
=
{
"
30rem
"
}
roundedCircle
className
=
"
img-thumbnail
"
>
<
/Image>KU
#
<
/strong
>
<
/Link
>
{
/* 홈페이지로 돌아가기 */
}
를
방문해주신
<
em
>
{
account
.
name
}
<
/em> 님,<br></
br
>
진심으로
환영합니다
!
즐거운
쇼핑
되세요
.
<
/h4
>
<
/Card.Body
>
<
/Row
>
<
Row
className
=
"
mr-1 text-muted d-flex justify-content-end
"
>
<
a
href
=
"
mailto:shoppingmall_KU@korea.ac.kr
"
>
<
small
title
=
"
메일보내기
"
>
*
문의
:
shoppingmall_KU
@
korea
.
ac
.
kr
<
/small
>
<
/a
>
{
/* 쇼핑몰 문의 메일보내기 */
}
<
/Row
>
<
/Col
>
<
/Row
>
<
/Card
>
<
Accordion
>
<
Row
className
=
"
my-3 px-3
"
>
<
Table
>
<
thead
className
=
"
text-center
"
style
=
{{
background
:
'
#F7F3F3
'
}}
>
<
tr
>
<
th
scope
=
"
col
"
>
주문현황
<
/th
>
<
th
scope
=
"
col
"
>
배송중
<
/th
>
<
th
scope
=
"
col
"
>
배송완료
<
/th
>
<
/tr
>
<
/thead
>
<
tbody
>
<
tr
>
<
th
scope
=
"
row
"
>
케이시앵글부츠
(
SH
)
<
/th
>
<
td
>
Mark
<
/td
>
<
td
>
Otto
<
/td
>
<
/tr
>
<
tr
>
<
th
scope
=
"
row
"
>
2
<
/th
>
<
td
>
Jacob
<
/td
>
<
td
>
Thornton
<
/td
>
<
/tr
>
<
tr
>
<
th
scope
=
"
row
"
>
3
<
/th
>
<
td
colspan
=
"
2
"
>
Larry
the
Bird
<
/td
>
<
/tr
>
<
/tbody
>
<
/Table
>
<
/Row
>
<
/Accordion
>
<
/Container
>
)
}
export
default
Account
}
export
default
Account
client/src/Pages/Admin.js
View file @
a4570666
import
React
,
{
useState
,
useEffect
,
useRef
}
from
'
react
'
;
import
React
from
'
react
'
;
import
Pagination
from
'
../Components/Pagination
'
;
import
{
Row
,
Form
,
FormControl
,
Button
,
Card
,
Container
}
from
'
react-bootstrap
'
;
...
...
client/src/mypagetiger.svg
0 → 100644
View file @
a4570666
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
version=
"1.0"
xmlns=
"http://www.w3.org/2000/svg"
width=
"32.000000pt"
height=
"32.000000pt"
viewBox=
"0 0 32.000000 32.000000"
preserveAspectRatio=
"xMidYMid meet"
>
<g
transform=
"translate(0.000000,32.000000) scale(0.100000,-0.100000)"
fill=
"#91877F"
stroke=
"none"
>
<path
d=
"M86 288 c-19 -27 -20 -39 -4 -73 13 -28 52 -35 62 -9 10 26 7 79 -6
92 -18 18 -35 15 -52 -10z m52 -21 c6 -30 -7 -67 -23 -67 -22 0 -38 46 -24 71
12 24 42 21 47 -4z"
/>
<path
d=
"M187 292 c-19 -21 -22 -64 -7 -93 30 -55 95 21 68 79 -16 33 -39 39
-61 14z m51 -43 c4 -47 -23 -74 -44 -44 -26 36 -14 88 20 83 16 -2 22 -11 24
-39z"
/>
<path
d=
"M8 175 c-17 -38 0 -80 32 -80 29 0 46 38 36 79 -9 36 -52 37 -68 1z
m58 -9 c6 -26 -10 -66 -27 -66 -19 0 -32 46 -20 69 16 28 39 27 47 -3z"
/>
<path
d=
"M251 174 c-25 -31 -27 -57 -6 -74 21 -17 51 -4 65 30 26 62 -18 96
-59 44z m54 5 c9 -13 -13 -66 -30 -73 -26 -10 -38 20 -20 53 16 31 38 40 50
20z"
/>
<path
d=
"M95 100 c-41 -42 -48 -53 -39 -68 9 -14 27 -17 104 -17 79 0 94 3
104 18 9 15 7 22 -12 35 -13 9 -37 32 -54 50 -17 17 -36 32 -42 32 -7 0 -34
-23 -61 -50z m119 -14 c34 -32 43 -46 34 -52 -22 -14 -177 -12 -182 1 -6 16
64 94 85 94 8 1 36 -19 63 -43z"
/>
</g>
</svg>
client/src/person.svg
0 → 100644
View file @
a4570666
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
version=
"1.0"
xmlns=
"http://www.w3.org/2000/svg"
width=
"200.000000pt"
height=
"200.000000pt"
viewBox=
"0 0 200.000000 200.000000"
preserveAspectRatio=
"xMidYMid meet"
>
<g
transform=
"translate(0.000000,200.000000) scale(0.100000,-0.100000)"
fill=
"#91877F"
stroke=
"none"
>
<path
d=
"M904 1456 c-147 -69 -174 -273 -49 -373 53 -43 47 -64 -29 -102 -124
-61 -207 -186 -210 -316 l-1 -60 385 0 385 0 -2 63 c-3 125 -90 255 -209 313
-78 39 -80 54 -20 112 84 80 94 201 26 295 -36 50 -118 92 -179 92 -27 0 -67
-10 -97 -24z"
/>
</g>
</svg>
client/src/utils/auth.js
View file @
a4570666
...
...
@@ -11,14 +11,15 @@ export async function handleLogout(){
localStorage
.
removeItem
(
'
role
'
)
localStorage
.
removeItem
(
'
name
'
)
await
axios
.
get
(
'
/api/auth/logout
'
)
window
.
location
.
href
=
'
/
'
window
.
location
.
href
=
'
/
'
}
export
function
isAuthenticated
(){
const
userId
=
localStorage
.
getItem
(
'
id
'
)
if
(
userId
){
return
userId
}
else
{
return
false
}
else
{
return
false
}
}
\ No newline at end of file
server/controllers/auth.controller.js
View file @
a4570666
...
...
@@ -3,40 +3,40 @@ import bcrypt from 'bcryptjs'
import
jwt
from
'
jsonwebtoken
'
import
config
from
'
../config.js
'
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
'
)
console
.
log
(
'
u=
'
,
user
)
if
(
!
user
){
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
'
)
console
.
log
(
'
u=
'
,
user
)
if
(
!
user
)
{
return
res
.
status
(
404
).
send
(
`
${
id
}
가 존재하지 않습니다.`
)
}
const
passwordMatch
=
await
bcrypt
.
compare
(
password
,
user
.
password
)
}
const
passwordMatch
=
await
bcrypt
.
compare
(
password
,
user
.
password
)
if
(
passwordMatch
){
const
token
=
jwt
.
sign
({
userId
:
user
.
_id
},
config
.
jwtSecret
,{
expiresIn
:
'
3d
'
if
(
passwordMatch
)
{
const
token
=
jwt
.
sign
({
userId
:
user
.
_id
},
config
.
jwtSecret
,
{
expiresIn
:
'
3d
'
})
res
.
cookie
(
'
token
'
,
token
,{
maxAge
:
config
.
cookieMaxAge
,
httpOnly
:
true
,
secure
:
config
.
env
===
'
production
'
res
.
cookie
(
'
token
'
,
token
,
{
maxAge
:
config
.
cookieMaxAge
,
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
})
}
else
{
}
else
{
res
.
status
(
401
).
send
(
'
비밀번호가 일치하지 않습니다.
'
)
}
}
catch
(
error
){
}
catch
(
error
)
{
console
.
log
(
error
)
res
.
status
(
500
).
send
(
'
로그인 실패. 다시 시도하세요.
'
)
}
}
const
logout
=
(
req
,
res
)
=>
{
res
.
clearCookie
(
'
token
'
)
res
.
send
(
'
로그아웃 되었습니다.
'
)
}
const
logout
=
(
req
,
res
)
=>
{
res
.
clearCookie
(
'
token
'
)
res
.
send
(
'
로그아웃 되었습니다.
'
)
}
export
default
{
login
,
logout
}
\ No newline at end of file
export
default
{
login
,
logout
}
\ No newline at end of file
server/controllers/user.controller.js
View file @
a4570666
...
...
@@ -2,10 +2,37 @@ import Cart from "../schemas/Cart.js";
import
User
from
"
../schemas/User.js
"
;
import
isLength
from
'
validator/lib/isLength.js
'
;
import
bcrypt
from
'
bcryptjs
'
;
import
multer
from
"
multer
"
;
const
uploadimg
=
multer
({
dest
:
'
uploads/
'
});
const
imgUpload
=
uploadimg
.
fields
([
{
name
:
'
avatar
'
,
maxCount
:
1
}
])
const
username
=
(
req
,
res
)
=>
{
res
.
json
(
req
.
account
)
console
.
log
(
req
.
account
)
}
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
(
'
사용자 아이디 검색 실패
'
)
}
}
const
signup
=
async
(
req
,
res
)
=>
{
const
{
name
,
number1
,
number2
,
id
,
password
,
tel
,
role
}
=
req
.
body
const
{
name
,
number1
,
number2
,
id
,
password
,
tel
}
=
req
.
body
console
.
log
(
req
.
body
)
try
{
...
...
@@ -37,4 +64,26 @@ const signup = async (req, res) => {
}
}
export
default
{
signup
}
\ No newline at end of file
const
update
=
async
(
req
,
res
)
=>
{
console
.
log
(
"
req
"
,
req
.
body
)
try
{
if
(
req
.
body
.
avatar
==
''
)
{
const
user
=
req
.
account
user
.
avatarUrl
=
req
.
body
.
avatar
const
updateUser
=
await
user
.
save
()
res
.
json
(
updateUser
)
}
else
{
const
avatar
=
req
.
files
[
'
avatar
'
][
0
]
const
user
=
req
.
account
user
.
avatarUrl
=
avatar
.
filename
const
updateUser
=
await
user
.
save
()
res
.
json
(
updateUser
)
}
}
catch
(
error
)
{
console
.
log
(
error
);
res
.
status
(
500
).
send
(
'
이미지 업데이트 실패
'
)
}
}
export
default
{
signup
,
username
,
imgUpload
,
userById
,
update
}
\ No newline at end of file
server/routes/user.routes.js
View file @
a4570666
...
...
@@ -6,4 +6,12 @@ const router = express.Router()
router
.
route
(
'
/signup
'
)
.
post
(
userCtrl
.
signup
)
router
.
route
(
'
/account/:userId
'
)
.
get
(
userCtrl
.
username
)
.
put
(
userCtrl
.
imgUpload
,
userCtrl
.
update
)
router
.
param
(
'
userId
'
,
userCtrl
.
userById
)
export
default
router
\ No newline at end of file
server/schemas/User.js
View file @
a4570666
...
...
@@ -33,6 +33,9 @@ const UserSchema = new mongoose.Schema({
required
:
true
,
default
:
'
user
'
,
enum
:
[
'
user
'
,
'
admin
'
,
'
root
'
]
},
avatarUrl
:
{
type
:
String
}
},
{
timestamps
:
true
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment