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
travel
Commits
1574f869
Commit
1574f869
authored
Jul 26, 2022
by
Yoon, Daeki
😅
Browse files
admin 권한 추가
parent
ed7b303c
Changes
3
Hide whitespace changes
Inline
Side-by-side
frontend/src/auth/admin.tsx
View file @
1574f869
import
{
get
}
from
"
mongoose
"
;
import
React
,
{
FormEvent
,
useEffect
,
useState
,
MouseEvent
}
from
"
react
"
;
import
{
Link
}
from
"
react-router-dom
"
;
import
{
Link
,
Navigate
}
from
"
react-router-dom
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
// import { profileUpload } from "../apis/profile.api";
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
MainimgType
}
from
"
../types
"
;
import
{
MySlide
}
from
"
./adminslide
"
;
// export interface ImgState {
// state: MainimgType;
// }
import
{
useAuth
}
from
"
./auth.context
"
;
export
default
function
Admin
()
{
// 이미지 전체 불러오기
const
[
getimgs
,
setGetimgs
]
=
useState
<
MainimgType
[]
>
([]);
// 이미지 전체 불러오기
const
[
getimgs
,
setGetimgs
]
=
useState
<
MainimgType
[]
>
([]);
// 이미지 추가하기
const
[
addimg
,
setAddimg
]
=
useState
<
MainimgType
>
({
_id
:
""
,
theme
:
""
,
city
:
""
,
title
:
""
,
fileInfo
:
{
originalfilename
:
""
,
newfilename
:
""
},
});
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
addSuccess
,
setAddSuccess
]
=
useState
(
false
);
const
[
delSuccess
,
setDelSuccess
]
=
useState
(
false
);
const
[
file
,
setFile
]
=
useState
<
File
>
();
const
{
user
}
=
useAuth
();
async
function
imgsData
()
{
const
imgs
=
await
mainimgApi
.
getmainimg
();
setGetimgs
(
imgs
);
}
useEffect
(()
=>
{
imgsData
();
},
[]);
// 이미지 추가하기
const
[
addimg
,
setAddimg
]
=
useState
<
MainimgType
>
({
_id
:
""
,
theme
:
""
,
city
:
""
,
title
:
""
,
fileInfo
:
{
originalfilename
:
""
,
newfilename
:
""
},
});
if
(
user
.
role
!==
"
admin
"
)
{
alert
(
"
이용 권한이 없습니다.
"
);
return
<
Navigate
to
=
{
"
/
"
}
replace
/>;
}
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
addSuccess
,
setAddSuccess
]
=
useState
(
false
);
const
[
delSuccess
,
setDelSuccess
]
=
useState
(
false
);
const
[
file
,
setFile
]
=
useState
<
File
>
();
async
function
imgsData
()
{
const
imgs
=
await
mainimgApi
.
getmainimg
();
setGetimgs
(
imgs
);
}
useEffect
(()
=>
{
imgsData
();
},
[]);
function
handleSelectChange
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
console
.
log
(
value
);
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
function
handleInputeChange
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
function
handleSelectChange
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
console
.
log
(
value
);
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
function
handleInputeChange
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
function
handleFileChange
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
file
=
e
.
target
.
files
?.[
0
];
if
(
!
(
file
===
undefined
))
{
setFile
(
file
);
}
function
handleFileChange
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
file
=
e
.
target
.
files
?.[
0
];
if
(
!
(
file
===
undefined
))
{
setFile
(
file
);
}
}
async
function
handleSubmit
(
event
:
FormEvent
)
{
event
.
preventDefault
();
const
formdata
=
new
FormData
();
console
.
log
(
addimg
);
formdata
.
append
(
"
city
"
,
addimg
.
city
);
formdata
.
append
(
"
theme
"
,
addimg
.
theme
);
formdata
.
append
(
"
title
"
,
addimg
.
title
);
try
{
if
(
!
(
file
===
undefined
))
{
formdata
.
append
(
"
mainimg
"
,
file
);
console
.
log
(
"
fordata
"
,
formdata
);
const
res
=
await
mainimgApi
.
mainimg
(
formdata
);
console
.
log
(
"
확인 중
"
,
res
);
alert
(
"
img 추가되었습니다
"
);
setGetimgs
([...
getimgs
,
res
])
}
else
(
console
.
log
(
"
file === undefined
"
)
)
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
async
function
handleSubmit
(
event
:
FormEvent
)
{
event
.
preventDefault
();
const
formdata
=
new
FormData
();
console
.
log
(
addimg
);
formdata
.
append
(
"
city
"
,
addimg
.
city
);
formdata
.
append
(
"
theme
"
,
addimg
.
theme
);
formdata
.
append
(
"
title
"
,
addimg
.
title
);
try
{
if
(
!
(
file
===
undefined
))
{
formdata
.
append
(
"
mainimg
"
,
file
);
console
.
log
(
"
fordata
"
,
formdata
);
const
res
=
await
mainimgApi
.
mainimg
(
formdata
);
console
.
log
(
"
확인 중
"
,
res
);
alert
(
"
img 추가되었습니다
"
);
setGetimgs
([...
getimgs
,
res
]);
}
else
console
.
log
(
"
file === undefined
"
);
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
}
// 이미지 삭제하기
async
function
handleDeleteClick
(
event
:
MouseEvent
<
HTMLButtonElement
>
)
{
try
{
if
(
confirm
(
"
삭제하시겠습니까?
"
)
==
true
)
{
const
picId
=
event
.
currentTarget
.
id
;
console
.
log
(
"
picId :
"
,
picId
);
const
res
=
await
mainimgApi
.
delmainimg
(
picId
);
console
.
log
(
"
delete img
"
,
res
);
// setGetimgs(getimgs)
setDelSuccess
(
true
);
setError
(
""
);
alert
(
"
img 삭제되었습니다
"
);
const
deleteimg
=
getimgs
.
filter
(
pic
=>
picId
!==
pic
.
_id
)
setGetimgs
(
deleteimg
)
}
else
{
return
false
;
}
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
// 이미지 삭제하기
async
function
handleDeleteClick
(
event
:
MouseEvent
<
HTMLButtonElement
>
)
{
try
{
if
(
confirm
(
"
삭제하시겠습니까?
"
)
==
true
)
{
const
picId
=
event
.
currentTarget
.
id
;
console
.
log
(
"
picId :
"
,
picId
);
const
res
=
await
mainimgApi
.
delmainimg
(
picId
);
console
.
log
(
"
delete img
"
,
res
);
// setGetimgs(getimgs)
setDelSuccess
(
true
);
setError
(
""
);
alert
(
"
img 삭제되었습니다
"
);
const
deleteimg
=
getimgs
.
filter
((
pic
)
=>
picId
!==
pic
.
_id
);
setGetimgs
(
deleteimg
);
}
else
{
return
false
;
}
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
}
let
limit
=
15
;
const
numPages
=
Math
.
ceil
(
getimgs
.
length
/
15
);
let
limit
=
15
;
const
numPages
=
Math
.
ceil
(
getimgs
.
length
/
15
);
// const location = useLocation() as ImgState;
// const img = location.state;
const
slides
=
[];
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
const
k
=
[
getimgs
.
slice
(
i
*
limit
,
i
*
limit
+
limit
)
.
map
((
picture
,
index
:
number
)
=>
(
<
div
key
=
{
index
}
>
<
div
className
=
{
`m-1 shrink-0 bg-gray-200 rounded shadow-md `
}
>
<
img
src
=
{
"
http://localhost:3000/images/
"
+
picture
.
fileInfo
.
newfilename
}
className
=
"w-full h-10 md:h-20 object-center"
/>
<
p
className
=
"text-center text-xs"
>
{
picture
.
title
}
</
p
>
</
div
>
<
div
className
=
"text-end"
>
<
button
className
=
"border-r-2 border-r-indigo-500 text-xs"
>
<
Link
to
=
{
`/admin/
${
picture
.
_id
}
`
}
state
=
{
picture
}
>
수정
</
Link
>
</
button
>
<
button
id
=
{
picture
.
_id
}
onClick
=
{
handleDeleteClick
}
className
=
"text-xs"
>
삭제
</
button
>
</
div
>
</
div
>
)),
];
slides
.
push
(
k
);
}
const
slides
=
[];
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
const
k
=
[
getimgs
.
slice
(
i
*
limit
,
i
*
limit
+
limit
)
.
map
((
picture
,
index
:
number
)
=>
(
<
div
key
=
{
index
}
>
<
div
className
=
{
`m-1 shrink-0 bg-gray-200 rounded shadow-md `
}
>
<
img
src
=
{
"
http://localhost:3000/images/
"
+
picture
.
fileInfo
.
newfilename
}
className
=
"w-full h-10 md:h-20 object-center"
/>
<
p
className
=
"text-center text-xs"
>
{
picture
.
title
}
</
p
>
</
div
>
<
div
className
=
"text-end"
>
<
button
className
=
"border-r-2 border-r-indigo-500 text-xs"
>
<
Link
to
=
{
`/admin/
${
picture
.
_id
}
`
}
state
=
{
picture
}
>
수정
</
Link
>
</
button
>
<
button
id
=
{
picture
.
_id
}
onClick
=
{
handleDeleteClick
}
className
=
"text-xs"
>
삭제
</
button
>
</
div
>
</
div
>
)),
];
slides
.
push
(
k
);
}
return
(
<
div
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"flex flex-wrap justify-center gap-3"
>
<
div
className
=
"gap-3 md:flex "
>
<
select
name
=
"city"
id
=
"Questions"
className
=
"border border-3 border-black w-20 my-5"
defaultValue
=
"질문종류"
onChange
=
{
handleSelectChange
}
>
<
option
value
=
"질문종류"
>
도시
</
option
>
<
option
value
=
"Seoul"
>
서울
</
option
>
<
option
value
=
"Busan"
>
부산
</
option
>
<
option
value
=
"Incheon"
>
인천
</
option
>
<
option
value
=
"Daegoo"
>
대구
</
option
>
<
option
value
=
"Gwangjoo"
>
광주
</
option
>
<
option
value
=
"Daejeon"
>
대전
</
option
>
<
option
value
=
"Woolsan"
>
울산
</
option
>
<
option
value
=
"Sejong"
>
세종
</
option
>
<
option
value
=
"Dokdo"
>
독도
</
option
>
<
option
value
=
"Jeju"
>
제주
</
option
>
</
select
>
<
select
name
=
"theme"
id
=
"Questions"
className
=
"border border-3 border-black w-20 my-5"
defaultValue
=
"질문종류"
onChange
=
{
handleSelectChange
}
>
<
option
value
=
"질문종류"
>
테마
</
option
>
<
option
value
=
"cycling"
>
사이클링
</
option
>
<
option
value
=
"surfing"
>
서핑
</
option
>
<
option
value
=
"activity"
>
액티비티
</
option
>
<
option
value
=
"camping"
>
캠핑
</
option
>
<
option
value
=
"skiing"
>
스키
</
option
>
<
option
value
=
"boat"
>
보트
</
option
>
<
option
value
=
"desert"
>
사막
</
option
>
<
option
value
=
"golf"
>
골프
</
option
>
<
option
value
=
"cave"
>
동굴
</
option
>
<
option
value
=
"history"
>
문화재
</
option
>
<
option
value
=
"zoo"
>
동물원
</
option
>
<
option
value
=
"cycling"
>
사이클링
</
option
>
</
select
>
<
div
className
=
"flex items-center justify-end gap-3"
>
<
input
type
=
"file"
id
=
"files"
className
=
"hidden"
onChange
=
{
handleFileChange
}
></
input
>
<
label
htmlFor
=
"files"
className
=
"border-2 m-5"
>
이미지 선택
</
label
>
</
div
>
<
div
className
=
"flex items-center justify-end gap-3 mt-2 md:mt-0"
>
<
p
>
title :
</
p
>
<
input
name
=
"title"
className
=
"border-2 border-sky-500"
onChange
=
{
handleInputeChange
}
/>
</
div
>
</
div
>
<
div
className
=
"my-5 flex items-center"
>
<
button
className
=
"border-2 border-gray-500 rounded "
>
추가
</
button
>
</
div
>
</
div
>
</
form
>
<
div
className
=
"flex justify-center"
>
<
MySlide
key
=
{
Math
.
random
()
}
slides
=
{
slides
}
/>
return
(
<
div
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"flex flex-wrap justify-center gap-3"
>
<
div
className
=
"gap-3 md:flex "
>
<
select
name
=
"city"
id
=
"Questions"
className
=
"border border-3 border-black w-20 my-5"
defaultValue
=
"질문종류"
onChange
=
{
handleSelectChange
}
>
<
option
value
=
"질문종류"
>
도시
</
option
>
<
option
value
=
"Seoul"
>
서울
</
option
>
<
option
value
=
"Busan"
>
부산
</
option
>
<
option
value
=
"Incheon"
>
인천
</
option
>
<
option
value
=
"Daegoo"
>
대구
</
option
>
<
option
value
=
"Gwangjoo"
>
광주
</
option
>
<
option
value
=
"Daejeon"
>
대전
</
option
>
<
option
value
=
"Woolsan"
>
울산
</
option
>
<
option
value
=
"Sejong"
>
세종
</
option
>
<
option
value
=
"Dokdo"
>
독도
</
option
>
<
option
value
=
"Jeju"
>
제주
</
option
>
</
select
>
<
select
name
=
"theme"
id
=
"Questions"
className
=
"border border-3 border-black w-20 my-5"
defaultValue
=
"질문종류"
onChange
=
{
handleSelectChange
}
>
<
option
value
=
"질문종류"
>
테마
</
option
>
<
option
value
=
"cycling"
>
사이클링
</
option
>
<
option
value
=
"surfing"
>
서핑
</
option
>
<
option
value
=
"activity"
>
액티비티
</
option
>
<
option
value
=
"camping"
>
캠핑
</
option
>
<
option
value
=
"skiing"
>
스키
</
option
>
<
option
value
=
"boat"
>
보트
</
option
>
<
option
value
=
"desert"
>
사막
</
option
>
<
option
value
=
"golf"
>
골프
</
option
>
<
option
value
=
"cave"
>
동굴
</
option
>
<
option
value
=
"history"
>
문화재
</
option
>
<
option
value
=
"zoo"
>
동물원
</
option
>
<
option
value
=
"cycling"
>
사이클링
</
option
>
</
select
>
<
div
className
=
"flex items-center justify-end gap-3"
>
<
input
type
=
"file"
id
=
"files"
className
=
"hidden"
onChange
=
{
handleFileChange
}
></
input
>
<
label
htmlFor
=
"files"
className
=
"border-2 m-5"
>
이미지 선택
</
label
>
</
div
>
<
div
className
=
"flex items-center justify-end gap-3 mt-2 md:mt-0"
>
<
p
>
title :
</
p
>
<
input
name
=
"title"
className
=
"border-2 border-sky-500"
onChange
=
{
handleInputeChange
}
/>
</
div
>
</
div
>
<
div
className
=
"my-5 flex items-center"
>
<
button
className
=
"border-2 border-gray-500 rounded "
>
추가
</
button
>
</
div
>
</
div
>
);
</
form
>
<
div
className
=
"flex justify-center"
>
<
MySlide
key
=
{
Math
.
random
()
}
slides
=
{
slides
}
/>
</
div
>
</
div
>
);
}
frontend/src/home/header.tsx
View file @
1574f869
...
...
@@ -39,7 +39,7 @@ export default function Header() {
프로필
</
Link
>
<
div
className
=
"border-0 border-r-2 border-black "
></
div
>
<
div
></
div
>
{
user
.
role
===
"
admin
"
?
<
Link
to
=
{
"
/admin
"
}
>
어드민
</
Link
>
:
null
}
<
button
className
=
"ml-2 text-xs"
onClick
=
{
()
=>
{
...
...
frontend/src/types/index.tsx
View file @
1574f869
...
...
@@ -4,6 +4,7 @@ export interface IUser {
email
?:
string
;
isLoggedIn
:
boolean
;
_id
?:
string
;
role
?:
string
;
}
export
interface
LoginUser
{
...
...
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