Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
students
travel
Commits
4fec5250
"node_modules/chalk/source" did not exist on "50234fbae088abd3dc4d9daa866b38de078b95b8"
Commit
4fec5250
authored
Jul 25, 2022
by
백승민
Browse files
rewrite done
parent
c1d3b019
Changes
17
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
4fec5250
...
@@ -2,4 +2,5 @@ node_modules/
...
@@ -2,4 +2,5 @@ node_modules/
.vscode/
.vscode/
package-lock.json
package-lock.json
dist/
dist/
uploads/
uploads/
\ No newline at end of file
adminpics
\ No newline at end of file
frontend/src/Pages/myslide.tsx
View file @
4fec5250
...
@@ -41,7 +41,6 @@ export function MySlide({ slides}: num) {
...
@@ -41,7 +41,6 @@ export function MySlide({ slides}: num) {
<
div
className
=
"flex flex-row justify-center items-center "
>
<
div
className
=
"flex flex-row justify-center items-center "
>
<
button
className
=
"mx-3 w-6 h-6 rounded-full hover:bg-sky-100 hover:text-gray-400"
onClick
=
{
leftClick
}
disabled
=
{
slide
===
1
}
>
<
button
className
=
"mx-3 w-6 h-6 rounded-full hover:bg-sky-100 hover:text-gray-400"
onClick
=
{
leftClick
}
disabled
=
{
slide
===
1
}
>
<
<
{
/* {slide.current} */
}
</
button
>
</
button
>
<
div
<
div
className
=
{
`m-3 md:m-5 md:basis-4/5 flex flex-row relative w-full overflow-hidden`
}
className
=
{
`m-3 md:m-5 md:basis-4/5 flex flex-row relative w-full overflow-hidden`
}
...
@@ -49,7 +48,7 @@ export function MySlide({ slides}: num) {
...
@@ -49,7 +48,7 @@ export function MySlide({ slides}: num) {
{
slides
.
slice
(
page
-
1
,
page
+
2
).
map
((
slide
)
=>
(
{
slides
.
slice
(
page
-
1
,
page
+
2
).
map
((
slide
)
=>
(
<
div
key
=
{
Math
.
random
()
}
className
=
"min-w-full"
<
div
key
=
{
Math
.
random
()
}
className
=
"min-w-full"
>
>
<
div
key
=
{
slide
}
className
=
{
`inline-grid grid-cols-
5
${
style
}
`
}
>
<
div
key
=
{
slide
}
className
=
{
`inline-grid grid-cols-
2
${
style
}
`
}
>
{
slide
}
{
slide
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
frontend/src/Pages/pic.ts
deleted
100644 → 0
View file @
c1d3b019
let
url
=
[
{
themeid
:
"
surfing
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
1.종로 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.crowdpic.net/detail-thumb/thumb_d_1F5AF0BCBB2F43EF3C5B79DA763D3CFB.jpg
"
,
name
:
"
1.해운대 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
1.대구 서핑
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/17/13/36/umbrella-4209724__340.jpg
"
,
name
:
"
1.서대문 번지점프
"
},
{
themeid
:
"
sking
"
,
cityid
:
"
Kwangjoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
1.광주 스키
"
},
{
themeid
:
"
camping
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2021/11/16/11/13/man-6800728__340.jpg
"
,
name
:
"
1.강남 캠핑
"
},
{
themeid
:
"
boat
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://cdn.pixabay.com/photo/2018/02/19/22/21/water-3166432__340.jpg
"
,
name
:
"
1.조치원 보트
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://media.istockphoto.com/photos/vertical-woman-is-wraped-in-bungee-jumping-picture-id1391927451?b=1&k=20&m=1391927451&s=170667a&w=0&h=haNtVpNjhj58PsjRi8N_RbyYfxZsFfKdb3NJi7NPdDI=
"
,
name
:
"
1.번지점프
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/04/07/07/51/railroad-tracks-710614__480.jpg
"
,
name
:
"
1.레일바이크
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2017/06/17/10/55/hot-air-balloon-2411851__340.jpg
"
,
name
:
"
1.열기구
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Jeju
"
,
url
:
"
https://cdn.pixabay.com/photo/2012/10/10/05/07/combat-diver-60545__340.jpg
"
,
name
:
"
1.스카이다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/03/11/15/19/divers-668777__480.jpg
"
,
name
:
"
1.인천 스쿠버다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://media.istockphoto.com/photos/playing-water-skiing-or-wakeboard-picture-id1021580500?b=1&k=20&m=1021580500&s=170667a&w=0&h=dL-mrlLeoQGrNBhbyAS-rN0TcpFg9s41D3WVKUoZgNo=
"
,
name
:
"
1.수상스키
"
},
{
themeid
:
"
desert
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
1.인천 사막
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Woolsan
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/11/20/44/free-climbing-4196577__480.jpg
"
,
name
:
"
1.클라이밍
"
},
{
themeid
:
"
zoo
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/06/10/18/45/africa-5283871__340.jpg
"
,
name
:
"
2.대전 동물원
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Dokdo
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/04/19/08/03/adventure-5062314__340.jpg
"
,
name
:
"
2.산
"
},
{
themeid
:
"
cave
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2016/08/23/16/34/italy-1614931__340.jpg
"
,
name
:
"
2.서울 동굴
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
2.종로 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.crowdpic.net/detail-thumb/thumb_d_1F5AF0BCBB2F43EF3C5B79DA763D3CFB.jpg
"
,
name
:
"
2.해운대 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
2.대구 서핑
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/17/13/36/umbrella-4209724__340.jpg
"
,
name
:
"
2.서대문 번지점프
"
},
{
themeid
:
"
sking
"
,
cityid
:
"
Kwangjoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
2.광주 스키
"
},
{
themeid
:
"
camping
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2021/11/16/11/13/man-6800728__340.jpg
"
,
name
:
"
2.강남 캠핑
"
},
{
themeid
:
"
boat
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://cdn.pixabay.com/photo/2018/02/19/22/21/water-3166432__340.jpg
"
,
name
:
"
2.조치원 보트
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://media.istockphoto.com/photos/vertical-woman-is-wraped-in-bungee-jumping-picture-id1391927451?b=1&k=20&m=1391927451&s=170667a&w=0&h=haNtVpNjhj58PsjRi8N_RbyYfxZsFfKdb3NJi7NPdDI=
"
,
name
:
"
2.번지점프
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/04/07/07/51/railroad-tracks-710614__480.jpg
"
,
name
:
"
2.레일바이크
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2017/06/17/10/55/hot-air-balloon-2411851__340.jpg
"
,
name
:
"
2.열기구
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Jeju
"
,
url
:
"
https://cdn.pixabay.com/photo/2012/10/10/05/07/combat-diver-60545__340.jpg
"
,
name
:
"
2.스카이다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/03/11/15/19/divers-668777__480.jpg
"
,
name
:
"
2.인천 스쿠버다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://media.istockphoto.com/photos/playing-water-skiing-or-wakeboard-picture-id1021580500?b=1&k=20&m=1021580500&s=170667a&w=0&h=dL-mrlLeoQGrNBhbyAS-rN0TcpFg9s41D3WVKUoZgNo=
"
,
name
:
"
3.수상스키
"
},
{
themeid
:
"
desert
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
3.인천 사막
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Woolsan
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/11/20/44/free-climbing-4196577__480.jpg
"
,
name
:
"
3.클라이밍
"
},
{
themeid
:
"
zoo
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/06/10/18/45/africa-5283871__340.jpg
"
,
name
:
"
3.대전 동물원
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Dokdo
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/04/19/08/03/adventure-5062314__340.jpg
"
,
name
:
"
3.산
"
},
{
themeid
:
"
cave
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2016/08/23/16/34/italy-1614931__340.jpg
"
,
name
:
"
3.서울 동굴
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
3.종로 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.crowdpic.net/detail-thumb/thumb_d_1F5AF0BCBB2F43EF3C5B79DA763D3CFB.jpg
"
,
name
:
"
3.해운대 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
3.대구 서핑
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/17/13/36/umbrella-4209724__340.jpg
"
,
name
:
"
3.서대문 번지점프
"
},
{
themeid
:
"
sking
"
,
cityid
:
"
Kwangjoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
3.광주 스키
"
},
{
themeid
:
"
camping
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2021/11/16/11/13/man-6800728__340.jpg
"
,
name
:
"
3.강남 캠핑
"
},
{
themeid
:
"
boat
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://cdn.pixabay.com/photo/2018/02/19/22/21/water-3166432__340.jpg
"
,
name
:
"
3.조치원 보트
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://media.istockphoto.com/photos/vertical-woman-is-wraped-in-bungee-jumping-picture-id1391927451?b=1&k=20&m=1391927451&s=170667a&w=0&h=haNtVpNjhj58PsjRi8N_RbyYfxZsFfKdb3NJi7NPdDI=
"
,
name
:
"
3.번지점프
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/04/07/07/51/railroad-tracks-710614__480.jpg
"
,
name
:
"
3.레일바이크
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2017/06/17/10/55/hot-air-balloon-2411851__340.jpg
"
,
name
:
"
4.열기구
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Jeju
"
,
url
:
"
https://cdn.pixabay.com/photo/2012/10/10/05/07/combat-diver-60545__340.jpg
"
,
name
:
"
4.스카이다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/03/11/15/19/divers-668777__480.jpg
"
,
name
:
"
4.인천 스쿠버다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://media.istockphoto.com/photos/playing-water-skiing-or-wakeboard-picture-id1021580500?b=1&k=20&m=1021580500&s=170667a&w=0&h=dL-mrlLeoQGrNBhbyAS-rN0TcpFg9s41D3WVKUoZgNo=
"
,
name
:
"
4.수상스키
"
},
{
themeid
:
"
desert
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
4.인천 사막
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Woolsan
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/11/20/44/free-climbing-4196577__480.jpg
"
,
name
:
"
4.클라이밍
"
},
{
themeid
:
"
zoo
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/06/10/18/45/africa-5283871__340.jpg
"
,
name
:
"
4.대전 동물원
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Dokdo
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/04/19/08/03/adventure-5062314__340.jpg
"
,
name
:
"
4.산
"
},
{
themeid
:
"
cave
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2016/08/23/16/34/italy-1614931__340.jpg
"
,
name
:
"
4.서울 동굴
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
4.종로 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.crowdpic.net/detail-thumb/thumb_d_1F5AF0BCBB2F43EF3C5B79DA763D3CFB.jpg
"
,
name
:
"
4.해운대 서핑
"
},
{
themeid
:
"
surfing
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
4.대구 서핑
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/17/13/36/umbrella-4209724__340.jpg
"
,
name
:
"
4.서대문 번지점프
"
},
{
themeid
:
"
sking
"
,
cityid
:
"
Kwangjoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
4.광주 스키
"
},
{
themeid
:
"
camping
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2021/11/16/11/13/man-6800728__340.jpg
"
,
name
:
"
4.강남 캠핑
"
},
{
themeid
:
"
boat
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://cdn.pixabay.com/photo/2018/02/19/22/21/water-3166432__340.jpg
"
,
name
:
"
5.조치원 보트
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Sejong
"
,
url
:
"
https://media.istockphoto.com/photos/vertical-woman-is-wraped-in-bungee-jumping-picture-id1391927451?b=1&k=20&m=1391927451&s=170667a&w=0&h=haNtVpNjhj58PsjRi8N_RbyYfxZsFfKdb3NJi7NPdDI=
"
,
name
:
"
5.번지점프
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Busan
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/04/07/07/51/railroad-tracks-710614__480.jpg
"
,
name
:
"
5.레일바이크
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daegoo
"
,
url
:
"
https://cdn.pixabay.com/photo/2017/06/17/10/55/hot-air-balloon-2411851__340.jpg
"
,
name
:
"
5.열기구
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Jeju
"
,
url
:
"
https://cdn.pixabay.com/photo/2012/10/10/05/07/combat-diver-60545__340.jpg
"
,
name
:
"
5.스카이다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2015/03/11/15/19/divers-668777__480.jpg
"
,
name
:
"
5.인천 스쿠버다이빙
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://media.istockphoto.com/photos/playing-water-skiing-or-wakeboard-picture-id1021580500?b=1&k=20&m=1021580500&s=170667a&w=0&h=dL-mrlLeoQGrNBhbyAS-rN0TcpFg9s41D3WVKUoZgNo=
"
,
name
:
"
5.수상스키
"
},
{
themeid
:
"
desert
"
,
cityid
:
"
Incheon
"
,
url
:
"
https://cdn.pixabay.com/photo/2022/06/15/23/08/germany-7264701__340.jpg
"
,
name
:
"
5.인천 사막
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Woolsan
"
,
url
:
"
https://cdn.pixabay.com/photo/2019/05/11/20/44/free-climbing-4196577__480.jpg
"
,
name
:
"
5.클라이밍
"
},
{
themeid
:
"
zoo
"
,
cityid
:
"
Daejeon
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/06/10/18/45/africa-5283871__340.jpg
"
,
name
:
"
5.대전 동물원
"
},
{
themeid
:
"
activity
"
,
cityid
:
"
Dokdo
"
,
url
:
"
https://cdn.pixabay.com/photo/2020/04/19/08/03/adventure-5062314__340.jpg
"
,
name
:
"
5.산
"
},
{
themeid
:
"
cave
"
,
cityid
:
"
Seoul
"
,
url
:
"
https://cdn.pixabay.com/photo/2016/08/23/16/34/italy-1614931__340.jpg
"
,
name
:
"
5.서울 동굴
"
},
];
export
function
getPicure
(){
return
url
;
};
\ No newline at end of file
frontend/src/apis/mainimg.api.ts
View file @
4fec5250
...
@@ -2,8 +2,8 @@ import axios from "axios";
...
@@ -2,8 +2,8 @@ import axios from "axios";
import
{
MainimgType
}
from
"
../types
"
;
import
{
MainimgType
}
from
"
../types
"
;
import
baseUrl
from
"
./baseUrl
"
;
import
baseUrl
from
"
./baseUrl
"
;
export
const
mainimg
=
async
(
mainimg
:
MainimgType
)
=>
{
export
const
mainimg
=
async
(
formdata
:
FormData
)
=>
{
const
{
data
}
=
await
axios
.
post
(
`
${
baseUrl
}
/mainimg`
,
mainimg
);
const
{
data
}
=
await
axios
.
post
(
`
${
baseUrl
}
/mainimg`
,
formdata
);
return
data
;
return
data
;
};
};
...
@@ -17,7 +17,7 @@ export const getmainimg = async () => {
...
@@ -17,7 +17,7 @@ export const getmainimg = async () => {
return
data
;
return
data
;
};
};
export
const
updat
in
g
=
async
(
img
:
MainimgType
)
=>
{
export
const
updat
eim
g
=
async
(
formdata
:
FormData
,
_id
:
string
)
=>
{
const
{
data
}
=
await
axios
.
put
(
`
${
baseUrl
}
/mainimg/
${
img
.
_id
}
`
,
img
);
const
{
data
}
=
await
axios
.
put
(
`
${
baseUrl
}
/mainimg/
${
_id
}
`
,
formdata
);
return
data
;
return
data
;
};
};
\ No newline at end of file
frontend/src/auth/admin.tsx
View file @
4fec5250
import
React
,
{
FormEvent
,
useEffect
,
useState
,
MouseEvent
}
from
"
react
"
;
import
React
,
{
FormEvent
,
useEffect
,
useState
,
MouseEvent
}
from
"
react
"
;
import
{
Link
}
from
"
react-router-dom
"
;
import
{
Link
}
from
"
react-router-dom
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
MainimgType
}
from
"
../types
"
;
import
{
MainimgType
}
from
"
../types
"
;
import
{
picture
}
from
"
../apis/profile.api
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
MySlide
}
from
"
./adminslide
"
;
import
{
MySlide
}
from
"
./adminslide
"
;
// export interface ImgState {
// export interface ImgState {
// state: MainimgType;
// state: MainimgType;
// }
// }
export
default
function
Admin
()
{
export
default
function
Admin
()
{
// 이미지 전체 불러오기
// 이미지 전체 불러오기
const
[
getimgs
,
setGetimgs
]
=
useState
<
MainimgType
[]
>
([]);
const
[
getimgs
,
setGetimgs
]
=
useState
<
MainimgType
[]
>
([]);
...
@@ -17,54 +19,57 @@ export default function Admin() {
...
@@ -17,54 +19,57 @@ export default function Admin() {
const
imgs
=
await
mainimgApi
.
getmainimg
();
const
imgs
=
await
mainimgApi
.
getmainimg
();
setGetimgs
(
imgs
)
setGetimgs
(
imgs
)
};
};
useEffect
(()
=>
{
useEffect
(()
=>
{
imgsData
();
imgsData
();
},
[]);
},
[]);
// 이미지 추가하기
// 이미지 추가하기
const
[
addimg
,
setAddimg
]
=
useState
<
MainimgType
>
({
const
[
addimg
,
setAddimg
]
=
useState
<
MainimgType
>
({
_id
:
""
,
_id
:
""
,
theme
:
""
,
theme
:
""
,
city
:
""
,
city
:
""
,
url
:
""
,
title
:
""
,
title
:
""
,
pic
:
{
originalfilename
:
""
,
newfilename
:
""
},
});
});
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
addSuccess
,
setAddSuccess
]
=
useState
(
false
);
const
[
addSuccess
,
setAddSuccess
]
=
useState
(
false
);
const
[
delSuccess
,
setDelSuccess
]
=
useState
(
false
);
const
[
delSuccess
,
setDelSuccess
]
=
useState
(
false
);
const
[
file
,
setFile
]
=
useState
<
File
>
();
function
handleSelectChange
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
function
handleSelectChange
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
const
{
name
,
value
}
=
event
.
currentTarget
;
console
.
log
(
value
)
setAddimg
({
...
addimg
,
[
name
]:
value
});
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
}
function
handleInputeChange
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
function
handleInputeChange
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
const
{
name
,
value
}
=
event
.
currentTarget
;
setAddimg
({
...
addimg
,
[
name
]:
value
});
setAddimg
({
...
addimg
,
[
name
]:
value
});
}
}
;
async
function
handleSubmit
(
event
:
FormEvent
)
{
function
handleFileChange
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
event
.
preventDefault
();
const
file
=
e
.
target
.
files
?.[
0
];
try
{
if
(
!
(
file
===
undefined
))
{
setError
(
""
);
setFile
(
file
);
console
.
log
(
"
img data
"
,
addimg
);
setLoading
(
true
);
const
res
=
await
mainimgApi
.
mainimg
(
addimg
);
console
.
log
(
"
서버연결됬나요
"
,
res
);
setAddSuccess
(
true
);
setError
(
""
);
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
}
}
}
if
(
addSuccess
)
{
async
function
handleSubmit
(
event
:
FormEvent
)
{
alert
(
"
img 추가되었습니다
"
);
event
.
preventDefault
();
}
const
formdata
=
new
FormData
();
console
.
log
(
addimg
);
formdata
.
append
(
"
city
"
,
addimg
.
city
);
formdata
.
append
(
"
theme
"
,
addimg
.
theme
);
formdata
.
append
(
"
title
"
,
addimg
.
title
);
if
(
!
(
file
===
undefined
))
{
formdata
.
append
(
"
mainimg
"
,
file
);
console
.
log
(
formdata
);
const
res
=
await
mainimgApi
.
mainimg
(
formdata
);
console
.
log
(
"
확인 중
"
,
res
);
alert
(
"
img 추가되었습니다
"
);
};
};
// 이미지 삭제하기
// 이미지 삭제하기
async
function
handleDeleteClick
(
event
:
MouseEvent
<
HTMLButtonElement
>
)
{
async
function
handleDeleteClick
(
event
:
MouseEvent
<
HTMLButtonElement
>
)
{
try
{
try
{
...
@@ -76,6 +81,7 @@ export default function Admin() {
...
@@ -76,6 +81,7 @@ export default function Admin() {
// setGetimgs(getimgs)
// setGetimgs(getimgs)
setDelSuccess
(
true
);
setDelSuccess
(
true
);
setError
(
""
);
setError
(
""
);
alert
(
"
img 삭제되었습니다
"
);
}
else
{
}
else
{
return
false
;
return
false
;
}
}
...
@@ -87,10 +93,7 @@ export default function Admin() {
...
@@ -87,10 +93,7 @@ export default function Admin() {
setLoading
(
false
);
setLoading
(
false
);
};
};
};
};
if
(
delSuccess
)
{
alert
(
"
img 삭제되었습니다
"
);
}
let
limit
=
15
;
let
limit
=
15
;
const
numPages
=
Math
.
ceil
(
getimgs
.
length
/
15
);
const
numPages
=
Math
.
ceil
(
getimgs
.
length
/
15
);
...
@@ -100,22 +103,22 @@ export default function Admin() {
...
@@ -100,22 +103,22 @@ export default function Admin() {
const
slides
=
[]
const
slides
=
[]
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
const
k
=
[
const
k
=
[
getimgs
.
slice
(
i
*
limit
,
i
*
limit
+
limit
).
map
((
pic
,
index
:
number
)
=>
(
getimgs
.
slice
(
i
*
limit
,
i
*
limit
+
limit
).
map
((
pic
ture
,
index
:
number
)
=>
(
<
div
key
=
{
index
}
>
<
div
key
=
{
index
}
>
<
div
className
=
{
`m-1 shrink-0 bg-gray-200 rounded shadow-md `
}
>
<
div
className
=
{
`m-1 shrink-0 bg-gray-200 rounded shadow-md `
}
>
<
img
<
img
src
=
{
pic
.
ur
l
}
src
=
{
"
http://localhost:3000/images/
"
+
pic
t
ur
e
.
pic
.
newfilename
}
className
=
"w-full h-10 md:h-20 object-center"
className
=
"w-full h-10 md:h-20 object-center"
/>
/>
<
p
className
=
"text-center text-xs"
>
{
pic
.
title
}
</
p
>
<
p
className
=
"text-center text-xs"
>
{
pic
ture
.
title
}
</
p
>
</
div
>
</
div
>
<
div
className
=
"text-end"
>
<
div
className
=
"text-end"
>
<
button
className
=
"border-r-2 border-r-indigo-500 text-xs"
>
<
button
className
=
"border-r-2 border-r-indigo-500 text-xs"
>
<
Link
to
=
{
`/admin/
${
pic
.
_id
}
`
}
state
=
{
pic
}
>
<
Link
to
=
{
`/admin/
${
pic
ture
.
_id
}
`
}
state
=
{
pic
ture
}
>
수정
수정
</
Link
>
</
Link
>
</
button
>
</
button
>
<
button
id
=
{
pic
.
_id
}
onClick
=
{
handleDeleteClick
}
className
=
"text-xs"
>
<
button
id
=
{
pic
ture
.
_id
}
onClick
=
{
handleDeleteClick
}
className
=
"text-xs"
>
삭제
삭제
</
button
>
</
button
>
</
div
>
</
div
>
...
@@ -170,10 +173,16 @@ export default function Admin() {
...
@@ -170,10 +173,16 @@ export default function Admin() {
<
option
value
=
"사이클링"
>
사이클링
</
option
>
<
option
value
=
"사이클링"
>
사이클링
</
option
>
</
select
>
</
select
>
<
div
className
=
"flex items-center justify-end gap-3"
>
<
div
className
=
"flex items-center justify-end gap-3"
>
<
p
>
url :
</
p
>
<
input
<
input
name
=
"url"
className
=
"border-2 border-sky-500"
type
=
"file"
onChange
=
{
handleInputeChange
}
/>
id
=
"files"
{
/* type="file"/> */
}
className
=
"hidden"
onChange
=
{
handleFileChange
}
></
input
>
<
label
htmlFor
=
"files"
className
=
"border-2 m-5"
>
이미지 선택
</
label
>
</
div
>
</
div
>
<
div
className
=
"flex items-center justify-end gap-3 mt-2 md:mt-0"
>
<
div
className
=
"flex items-center justify-end gap-3 mt-2 md:mt-0"
>
<
p
>
title :
</
p
>
<
p
>
title :
</
p
>
...
...
frontend/src/auth/imgrewrite.tsx
View file @
4fec5250
import
React
,
{
FormEvent
,
useState
}
from
"
react
"
;
import
React
,
{
FormEvent
,
useState
}
from
"
react
"
;
import
{
Link
,
Outlet
,
useNavigate
,
useLocation
}
from
"
react-router-dom
"
;
import
{
Link
,
Outlet
,
useNavigate
,
useLocation
}
from
"
react-router-dom
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
import
isLength
from
"
validator/lib/isLength
"
;
import
isLength
from
"
validator/lib/isLength
"
;
...
@@ -26,38 +26,82 @@ export default function ImgRewrite() {
...
@@ -26,38 +26,82 @@ export default function ImgRewrite() {
_id
:
img
.
_id
,
_id
:
img
.
_id
,
theme
:
img
.
theme
,
theme
:
img
.
theme
,
city
:
img
.
city
,
city
:
img
.
city
,
url
:
img
.
url
,
title
:
img
.
title
,
title
:
img
.
title
,
pic
:
{
originalfilename
:
""
,
newfilename
:
""
},
});
});
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
disabled
,
setDisabled
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
file
,
setFile
]
=
useState
<
File
>
();
const
[
imageSrc
,
setImageSrc
]
=
useState
(
""
);
const
PictureSrc
=
(
fileBlob
:
Blob
)
=>
{
const
reader
=
new
FileReader
();
reader
.
readAsDataURL
(
fileBlob
);
reader
.
onload
=
(
data
)
=>
{
if
(
typeof
data
.
target
?.
result
===
"
string
"
)
{
console
.
log
(
data
.
target
?.
result
);
setImageSrc
(
data
.
target
?.
result
);
}
};
};
const
onUploadFile
=
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
file
=
e
.
target
.
files
?.[
0
];
if
(
!
(
file
===
undefined
))
{
setFile
(
file
);
PictureSrc
(
file
);
}
};
async
function
reWriteSubmit
(
event
:
FormEvent
)
{
async
function
reWriteSubmit
(
event
:
FormEvent
)
{
event
.
preventDefault
();
event
.
preventDefault
();
try
{
if
(
confirm
(
"
수정하시겠습니까?
"
)
==
true
)
{
if
(
confirm
(
"
수정하시겠습니까?
"
)
==
true
)
{
// try {
setError
(
""
);
setError
(
""
);
console
.
log
(
"
user data
"
,
imgdata
);
console
.
log
(
"
user data
"
,
imgdata
);
if
(
infoFormMatch
(
imgdata
)
===
true
)
{
// if (infoFormMatch(imgdata) === true) {
setLoading
(
true
);
// setLoading(true);
const
res
=
await
mainimgApi
.
updating
(
imgdata
);
// const res = await mainimgApi.updating(imgdata);
// console.log("clear", res);
console
.
log
(
"
clear
"
,
res
);
// navigate("/admin", { replace: true });
navigate
(
"
/admin
"
,
{
replace
:
true
});
// setSuccess(true);
setSuccess
(
true
);
// setError("");
setError
(
""
);
const
formdata
=
new
FormData
();
}
formdata
.
append
(
"
id
"
,
imgdata
.
_id
)
}
else
{
console
.
log
(
imgdata
.
_id
)
return
false
;
formdata
.
append
(
"
city
"
,
imgdata
.
city
);
formdata
.
append
(
"
theme
"
,
imgdata
.
theme
);
formdata
.
append
(
"
title
"
,
imgdata
.
title
);
console
.
log
(
formdata
)
if
(
!
(
file
===
undefined
))
{
formdata
.
append
(
"
updatemainimg
"
,
file
);
console
.
log
(
"
formdata
"
,
formdata
);
const
res
=
await
mainimgApi
.
updateimg
(
formdata
,
imgdata
.
_id
);
navigate
(
"
/admin
"
,
{
replace
:
true
});
console
.
log
(
"
확인 중
"
,
res
);
}
}
}
catch
(
error
)
{
else
{
console
.
log
(
"
에러발생
"
);
console
.
log
(
"
ㅇ에러
"
)
catchErrors
(
error
,
setError
);
formdata
.
append
(
"
updatemainimg
"
,
""
);
}
finally
{
console
.
log
(
"
formdata
"
,
formdata
);
setLoading
(
false
);
const
res
=
await
mainimgApi
.
updateimg
(
formdata
,
imgdata
.
_id
);
navigate
(
"
/admin
"
,
{
replace
:
true
});
console
.
log
(
"
확인 중
"
,
res
);
}
// }
// } catch (error) {
// console.log("에러발생");
// catchErrors(error, setError);
// } finally {
// setLoading(false);
// }
}
else
{
return
false
;
}
}
}
}
// console.log(user._id)
// console.log(user._id)
...
@@ -65,8 +109,8 @@ export default function ImgRewrite() {
...
@@ -65,8 +109,8 @@ export default function ImgRewrite() {
if
(
!
isLength
(
pic
.
title
??
""
,
{
min
:
1
}))
{
if
(
!
isLength
(
pic
.
title
??
""
,
{
min
:
1
}))
{
setError
(
"
제목을 입력해 주세요.
"
);
setError
(
"
제목을 입력해 주세요.
"
);
return
false
;
return
false
;
}
else
if
(
!
isLength
(
pic
.
url
??
""
,
{
min
:
1
}))
{
}
else
if
(
!
isLength
(
pic
.
pic
.
newfilename
??
""
,
{
min
:
1
}))
{
setError
(
"
url을 입력
해 주세요.
"
);
setError
(
"
파일을 선택
해 주세요.
"
);
return
false
;
return
false
;
}
else
if
(
equals
(
pic
.
city
,
"
city
"
))
{
}
else
if
(
equals
(
pic
.
city
,
"
city
"
))
{
setError
(
"
도시를 선택해 주세요.
"
);
setError
(
"
도시를 선택해 주세요.
"
);
...
@@ -103,9 +147,9 @@ export default function ImgRewrite() {
...
@@ -103,9 +147,9 @@ export default function ImgRewrite() {
setImgData
(
newUser
);
setImgData
(
newUser
);
};
};
const
url
Change
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
file
Change
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
url
=
event
.
currentTarget
.
value
;
const
url
=
event
.
currentTarget
.
value
;
const
newUser
=
{
...
imgdata
,
url
:
url
};
const
newUser
=
{
...
imgdata
,
pic
:
{
originalfilename
:
""
,
newfilename
:
url
}
};
setUrl
(
event
.
currentTarget
.
value
);
setUrl
(
event
.
currentTarget
.
value
);
setImgData
(
newUser
);
setImgData
(
newUser
);
};
};
...
@@ -172,10 +216,26 @@ export default function ImgRewrite() {
...
@@ -172,10 +216,26 @@ export default function ImgRewrite() {
url
url
</
td
>
</
td
>
<
td
>
<
td
>
<
input
className
=
"border-2 border-sky-500 rounded w-full"
<
input
onChange
=
{
urlChange
}
type
=
"file"
defaultValue
=
{
img
.
url
}
id
=
"files"
/>
className
=
"hidden"
onChange
=
{
onUploadFile
}
></
input
>
<
label
htmlFor
=
"files"
className
=
"border-2 m-5"
>
이미지 선택
</
label
>
{
imageSrc
?
(
<
img
src
=
{
imageSrc
}
className
=
"object-cover object-center h-full"
/>
)
:
(
<
img
src
=
{
"
http://localhost:3000/images/
"
+
img
.
pic
.
newfilename
}
className
=
"object-cover object-center h-full"
/>
)
}
</
td
>
</
td
>
</
tr
>
</
tr
>
<
tr
>
<
tr
>
...
...
frontend/src/home/body.tsx
View file @
4fec5250
...
@@ -2,16 +2,24 @@ import React, { useEffect, MouseEvent, useState, useRef } from "react";
...
@@ -2,16 +2,24 @@ import React, { useEffect, MouseEvent, useState, useRef } from "react";
import
{
Outlet
,
useSearchParams
}
from
"
react-router-dom
"
;
import
{
Outlet
,
useSearchParams
}
from
"
react-router-dom
"
;
import
Theme
from
"
./theme
"
;
import
Theme
from
"
./theme
"
;
import
Citylist
from
"
../Pages/citylist
"
;
import
Citylist
from
"
../Pages/citylist
"
;
import
{
getPicure
}
from
"
../Pages/pic
"
;
import
{
MySlide
}
from
"
../Pages/myslide
"
;
import
{
MySlide
}
from
"
../Pages/myslide
"
;
import
{
mainimgApi
}
from
"
../apis
"
;
import
{
MainimgType
}
from
"
../types
"
;
const
initSearchParams
=
{
theme
:
""
,
city
:
""
};
const
initSearchParams
=
{
theme
:
""
,
city
:
""
};
export
default
function
Body
()
{
export
default
function
Body
()
{
let
limit
=
15
;
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
(
initSearchParams
);
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
(
initSearchParams
);
let
getPics
=
getPicure
();
const
[
getimgs
,
setGetimgs
]
=
useState
<
MainimgType
[]
>
([]);
async
function
imgsData
()
{
const
imgs
=
await
mainimgApi
.
getmainimg
();
setGetimgs
(
imgs
)
};
useEffect
(()
=>
{
imgsData
();
},
[]);
useEffect
(()
=>
{
useEffect
(()
=>
{
console
.
log
(
searchParams
.
get
(
"
theme
"
),
searchParams
.
get
(
"
city
"
));
console
.
log
(
searchParams
.
get
(
"
theme
"
),
searchParams
.
get
(
"
city
"
));
...
@@ -39,31 +47,34 @@ export default function Body() {
...
@@ -39,31 +47,34 @@ export default function Body() {
let
themechange
=
searchParams
.
get
(
"
theme
"
);
let
themechange
=
searchParams
.
get
(
"
theme
"
);
let
citylistchange
=
searchParams
.
get
(
"
city
"
);
let
citylistchange
=
searchParams
.
get
(
"
city
"
);
const
Idpics
=
get
Pic
s
.
filter
((
p
)
=>
{
const
Idpics
=
get
img
s
.
filter
((
p
)
=>
{
return
(
return
(
(
p
.
theme
id
==
themechange
&&
p
.
city
id
==
citylistchange
)
||
(
p
.
theme
==
themechange
&&
p
.
city
==
citylistchange
)
||
(
p
.
theme
id
==
themechange
&&
citylistchange
==
""
)
||
(
p
.
theme
==
themechange
&&
citylistchange
==
""
)
||
(
themechange
==
""
&&
p
.
city
id
==
citylistchange
)
||
(
themechange
==
""
&&
p
.
city
==
citylistchange
)
||
(
themechange
==
""
&&
citylistchange
==
""
)
(
themechange
==
""
&&
citylistchange
==
""
)
);
);
});
});
const
numPages
=
Math
.
ceil
(
Idpics
.
length
/
15
);
let
limit
=
4
;
const
numPages
=
Math
.
ceil
(
Idpics
.
length
/
limit
);
const
slides
=
[]
const
slides
=
[]
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numPages
;
i
++
)
{
const
k
=
[
const
k
=
[
Idpics
.
slice
(
i
*
limit
,
i
*
limit
+
limit
).
map
((
pic
,
index
:
number
)
=>
(
Idpics
.
slice
(
i
*
limit
,
i
*
limit
+
limit
).
map
((
picture
,
index
:
number
)
=>
(
<
div
<
div
className
=
{
`m-1 shrink-0 bg-gray-200 rounded shadow-md `
}
className
=
{
`m-1 shrink-0 rounded shadow-md h-45 relative overflow-hidden`
}
key
=
{
index
}
>
key
=
{
index
}
>
<
img
<
img
src
=
{
pic
.
url
}
src
=
{
"
http://localhost:3000/images/
"
+
picture
.
pic
.
newfilename
}
className
=
"w-full h-10 md:h-20 object-center"
className
=
"w-full h-40 object-cover hover:scale-110 transition duration-0 hover:duration-500"
/>
/>
<
p
className
=
"text-center text-xs"
>
{
pic
.
name
}
</
p
>
<
div
className
=
"bg-transparent text-neutral-50 text-xs rounded-full absolute bottom-0 ml-1 mb-1 hover:scale-110 transition duration-0 hover:duration-500"
>
</
div
>
<
span
>
{
picture
.
title
}
</
span
>
))]
</
div
>
</
div
>
))]
slides
.
push
(
k
);
slides
.
push
(
k
);
}
}
...
...
frontend/src/home/theme.tsx
View file @
4fec5250
...
@@ -7,37 +7,37 @@ type ThemeProps = {
...
@@ -7,37 +7,37 @@ type ThemeProps = {
export
default
function
Theme
({
handleClick
}:
ThemeProps
)
{
export
default
function
Theme
({
handleClick
}:
ThemeProps
)
{
return
(
return
(
<
div
className
=
"overflow-x-auto flex rounded md:justify-center"
>
<
div
className
=
"overflow-x-auto flex rounded md:justify-center"
>
<
button
id
=
{
"
surfing
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
서핑
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
서핑
서핑
</
button
>
</
button
>
<
button
id
=
{
"
activity
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
액티비티
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
액티비티
액티비티
</
button
>
</
button
>
<
button
id
=
{
"
camping
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300 "
>
<
button
id
=
{
"
캠핑
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300 "
>
캠핑
캠핑
</
button
>
</
button
>
<
button
id
=
{
"
sking
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
스키
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
스키
스키
</
button
>
</
button
>
<
button
id
=
{
"
boat
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
보트
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
보트
보트
</
button
>
</
button
>
<
button
id
=
{
"
desert
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
사막
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
사막
사막
</
button
>
</
button
>
<
button
id
=
{
"
golf
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
골프
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
골프
골프
</
button
>
</
button
>
<
button
id
=
{
"
cave
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
동굴
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
동굴
동굴
</
button
>
</
button
>
<
button
id
=
{
"
history
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
문화재
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
문화재
문화재
</
button
>
</
button
>
<
button
id
=
{
"
zoo
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
동물원
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
동물원
동물원
</
button
>
</
button
>
<
button
id
=
{
"
cycling
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
<
button
id
=
{
"
사이클링
"
}
onClick
=
{
handleClick
}
className
=
"shrink-0 px-5 hover:text-sky-300"
>
사이클링
사이클링
</
button
>
</
button
>
</
div
>
</
div
>
...
...
frontend/src/pages/citylist.tsx
View file @
4fec5250
...
@@ -9,70 +9,70 @@ export default function Citylist({ handleClick }: CityProps) {
...
@@ -9,70 +9,70 @@ export default function Citylist({ handleClick }: CityProps) {
<
div
className
=
"overflow-auto w-full flex flex-row md:flex-col md:mr-24 bg-sky-100"
>
<
div
className
=
"overflow-auto w-full flex flex-row md:flex-col md:mr-24 bg-sky-100"
>
<
div
className
=
"text-center px-5 py-2 bg-sky-300 shrink-0"
>
도시
</
div
>
<
div
className
=
"text-center px-5 py-2 bg-sky-300 shrink-0"
>
도시
</
div
>
<
button
<
button
id
=
{
"
Seoul
"
}
id
=
{
"
서울
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
서울
서울
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Busan
"
}
id
=
{
"
부산
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
부산
부산
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Incheon
"
}
id
=
{
"
인천
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
인천
인천
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Daegoo
"
}
id
=
{
"
대구
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
대구
대구
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Kwangjoo
"
}
id
=
{
"
광주
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
광주
광주
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Daejeon
"
}
id
=
{
"
대전
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
대전
대전
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Woolsan
"
}
id
=
{
"
울산
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
울산
울산
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Sejong
"
}
id
=
{
"
세종
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
세종
세종
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Dokdo
"
}
id
=
{
"
독도
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
독도
독도
</
button
>
</
button
>
<
button
<
button
id
=
{
"
Jeju
"
}
id
=
{
"
제주
"
}
onClick
=
{
handleClick
}
onClick
=
{
handleClick
}
className
=
"px-5 py-2 hover:underline shrink-0"
className
=
"px-5 py-2 hover:underline shrink-0"
>
>
...
...
frontend/src/types/index.tsx
View file @
4fec5250
...
@@ -43,6 +43,9 @@ export interface MainimgType {
...
@@ -43,6 +43,9 @@ export interface MainimgType {
_id
:
string
;
_id
:
string
;
theme
:
string
;
theme
:
string
;
city
:
string
;
city
:
string
;
url
:
string
;
title
:
string
;
title
:
string
;
pic
:
{
originalfilename
:
string
;
newfilename
:
string
;
};
}
}
src/app.ts
View file @
4fec5250
...
@@ -12,6 +12,7 @@ app.use(cookieParser());
...
@@ -12,6 +12,7 @@ app.use(cookieParser());
app
.
use
(
"
/api
"
,
router
);
app
.
use
(
"
/api
"
,
router
);
app
.
use
(
"
/images
"
,
express
.
static
(
path
.
join
(
__dirname
,
"
..
"
,
"
/uploads
"
)));
app
.
use
(
"
/images
"
,
express
.
static
(
path
.
join
(
__dirname
,
"
..
"
,
"
/uploads
"
)));
app
.
use
(
"
/images
"
,
express
.
static
(
path
.
join
(
__dirname
,
"
..
"
,
"
/adminpics
"
)));
app
.
use
((
err
:
any
,
req
:
Request
,
res
:
Response
,
next
:
NextFunction
)
=>
{
app
.
use
((
err
:
any
,
req
:
Request
,
res
:
Response
,
next
:
NextFunction
)
=>
{
console
.
log
(
"
익스프레스 에러:
"
,
err
);
console
.
log
(
"
익스프레스 에러:
"
,
err
);
...
...
src/controllers/mainimg.controller.ts
View file @
4fec5250
...
@@ -3,38 +3,77 @@ import isLength from "validator/lib/isLength";
...
@@ -3,38 +3,77 @@ import isLength from "validator/lib/isLength";
import
{
TypedRequestAuth
}
from
"
./auth.controller
"
;
import
{
TypedRequestAuth
}
from
"
./auth.controller
"
;
import
{
asyncWrap
}
from
"
../helpers
"
;
import
{
asyncWrap
}
from
"
../helpers
"
;
import
{
mainimgDb
}
from
"
../db
"
;
import
{
mainimgDb
}
from
"
../db
"
;
import
{
TypedRequest
}
from
"
../types
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
import
formidable
from
"
formidable
"
;
export
const
createMainimg
=
asyncWrap
(
async
(
reqExp
,
res
,
next
)
=>
{
export
const
createMainimg
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
string
}
>
;
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
ObjectId
}
>
;
const
{
userId
}
=
req
.
auth
const
{
theme
,
city
,
url
,
title
}
=
req
.
body
as
{
//
const { theme, city, url, title } = req.body as {
theme
:
string
;
//
theme: string;
city
:
string
;
//
city: string;
url
:
string
;
//
url: string;
title
:
string
;
//
title: string;
};
//
};
console
.
log
(
"
body
"
,
req
.
body
);
//
console.log("body", req.body);
if
(
!
isLength
(
url
??
""
,
{
min
:
1
}))
{
const
form
=
formidable
({
return
res
.
status
(
422
).
send
(
"
이미지 url을 입력해주세요
"
);
uploadDir
:
"
uploads
"
,
}
keepExtensions
:
true
,
multiples
:
false
,
if
(
!
isLength
(
title
??
""
,
{
min
:
1
}))
{
return
res
.
status
(
422
).
send
(
"
이미지 제목을 입력해주세요
"
);
}
const
newMainimg
=
await
mainimgDb
.
createMainimg
({
theme
,
city
,
url
,
title
,
});
});
return
res
.
json
(
newMainimg
);
form
.
parse
(
req
,
(
err
,
fields
,
files
)
=>
{
if
(
!
Array
.
isArray
(
files
.
mainimg
))
{
//파일 좁히기 중
if
(
!
(
Array
.
isArray
(
fields
.
city
)
||
Array
.
isArray
(
fields
.
title
)
||
Array
.
isArray
(
fields
.
theme
)
)
)
{
const
city
=
fields
.
city
;
const
title
=
fields
.
title
;
const
theme
=
fields
.
theme
;
const
originalfilename
=
files
.
mainimg
?.
originalFilename
;
const
newfilename
=
files
.
mainimg
.
newFilename
;
if
(
!
(
originalfilename
===
null
||
newfilename
===
undefined
))
{
mainimgDb
.
createMainimg
(
{
city
,
title
,
theme
},
{
originalfilename
,
newfilename
,
}
);
}
}
}
});
res
.
json
();
});
});
// if (!isLength(url ?? "", { min: 1 })) {
// return res.status(422).send("이미지 url을 입력해주세요");
// }
// if (!isLength(title ?? "", { min: 1 })) {
// return res.status(422).send("이미지 제목을 입력해주세요");
// }
// const newMainimg = await mainimgDb.createMainimg({
// theme,
// city,
// url,
// title,
// });
// return res.json(newMainimg);
// });
export
const
getMainimg
=
asyncWrap
(
async
(
req
,
res
)
=>
{
export
const
getMainimg
=
asyncWrap
(
async
(
req
,
res
)
=>
{
const
mainimgs
=
await
mainimgDb
.
getMainimg
();
const
mainimgs
=
await
mainimgDb
.
getMainimg
();
return
res
.
json
(
mainimgs
);
return
res
.
json
(
mainimgs
);
...
@@ -49,25 +88,52 @@ export const deleteMainimg = asyncWrap(async (req, res) => {
...
@@ -49,25 +88,52 @@ export const deleteMainimg = asyncWrap(async (req, res) => {
return
res
.
json
(
deleteCount
);
return
res
.
json
(
deleteCount
);
});
});
export
const
updateMainimg
=
asyncWrap
(
async
(
req
,
res
)
=>
{
export
const
updateMainimg
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
const
{
title
,
theme
,
city
,
url
}
=
req
.
body
as
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
ObjectId
}
>
;
title
:
string
;
url
:
string
;
theme
:
string
;
const
form
=
formidable
({
city
:
string
;
uploadDir
:
"
uploads
"
,
};
keepExtensions
:
true
,
const
{
imgId
}
=
req
.
params
;
multiples
:
false
,
});
const
updateImg
=
await
mainimgDb
.
updateOnePost
(
form
.
parse
(
req
,
(
err
,
fields
,
files
)
=>
{
{
if
(
!
Array
.
isArray
(
files
.
updatemainimg
))
{
title
,
//파일 좁히기 중
theme
,
if
(
city
,
!
(
Array
.
isArray
(
fields
.
id
)
||
url
,
Array
.
isArray
(
fields
.
city
)
||
},
Array
.
isArray
(
fields
.
title
)
||
imgId
Array
.
isArray
(
fields
.
theme
)
);
)
)
{
return
res
.
json
(
updateImg
);
const
id
=
fields
.
id
;
const
city
=
fields
.
city
;
const
title
=
fields
.
title
;
const
theme
=
fields
.
theme
;
console
.
log
(
"
error
"
)
if
(
!
(
files
.
updatemainimg
===
undefined
)){
const
originalfilename
=
files
.
updatemainimg
?.
originalFilename
;
const
newfilename
=
files
.
updatemainimg
.
newFilename
;
if
(
!
(
originalfilename
===
null
||
newfilename
===
undefined
))
{
mainimgDb
.
updateOneMainimg
(
id
,
theme
,
city
,
title
,
originalfilename
,
newfilename
);
}
}
else
{
mainimgDb
.
updateOneMainimg
(
id
,
theme
,
city
,
title
)}
}
}
});
res
.
json
();
});
});
src/controllers/user.controller.ts
View file @
4fec5250
import
{
userDb
}
from
"
../db
"
;
import
{
userDb
}
from
"
../db
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
import
{
Request
}
from
"
express
"
;
import
{
Request
}
from
"
express
"
;
import
formidable
,
{
Fields
,
Files
}
from
"
formidable
"
;
import
formidable
from
"
formidable
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
import
fs
from
"
fs
"
;
import
fs
from
"
fs
"
;
...
...
src/db/mainimg.db.ts
View file @
4fec5250
import
{
Mainimg
,
MainimgType
}
from
"
../models
"
;
import
{
Avatar
,
IAvatar
,
Mainimg
,
MainimgType
}
from
"
../models
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
export
const
createMainimg
=
async
(
mainimg
:
MainimgType
,
pic
:
IAvatar
)
=>
{
const
newPic
=
await
Avatar
.
create
({
originalfilename
:
pic
.
originalfilename
,
newfilename
:
pic
.
newfilename
,
pictureauth
:
pic
.
picturepath
,
});
export
const
createMainimg
=
async
(
mainimg
:
MainimgType
)
=>
{
const
newMainimg
=
await
Mainimg
.
create
({
const
newMainimg
=
await
Mainimg
.
create
({
theme
:
mainimg
.
theme
,
theme
:
mainimg
.
theme
,
city
:
mainimg
.
city
,
city
:
mainimg
.
city
,
url
:
mainimg
.
url
,
pic
:
newPic
.
_id
,
title
:
mainimg
.
title
,
title
:
mainimg
.
title
,
});
});
return
newMainimg
;
return
newMainimg
;
};
};
export
const
getMainimg
=
async
()
=>
{
export
const
getMainimg
=
async
()
=>
{
const
users
=
await
Mainimg
.
find
({});
const
img
=
await
Mainimg
.
find
({}).
populate
(
"
pic
"
);
return
users
;
};
return
img
;
};
export
const
deleteOneMainimg
=
async
(
_id
:
string
)
=>
{
export
const
deleteOneMainimg
=
async
(
_id
:
string
)
=>
{
const
res
=
await
Mainimg
.
deleteOne
({
_id
:
_id
});
const
res
=
await
Mainimg
.
deleteOne
({
_id
:
_id
});
return
res
;
return
res
;
};
};
export
const
updateOnePost
=
async
(
mainimg
:
MainimgType
,
_id
:
string
)
=>
{
export
const
updateOneMainimg
=
async
(
const
newMainimg
=
await
Mainimg
.
findOneAndUpdate
(
_Id
:
string
,
{
_id
:
_id
},
theme
:
string
,
{
city
:
string
,
theme
:
mainimg
.
theme
,
title
:
string
,
city
:
mainimg
.
city
,
originalfilename
?:
string
|
null
,
url
:
mainimg
.
url
,
newfilename
?:
string
,
title
:
mainimg
.
title
,
)
=>
{
},
const
newMainimg
=
await
Mainimg
.
findById
(
_Id
);
{
new
:
true
}
console
.
log
(
"
error2
"
,
_Id
)
);
if
(
!
(
newMainimg
?.
pic
===
undefined
))
{
return
newMainimg
;
if
(
originalfilename
===
undefined
)
{
};
await
Mainimg
.
findByIdAndUpdate
(
newMainimg
.
_id
,
{
\ No newline at end of file
theme
:
theme
,
city
:
city
,
title
:
title
,
})
console
.
log
(
"
errrror4
"
)
}
else
if
(
!
(
originalfilename
===
undefined
)
&&
(
!
(
theme
===
undefined
)
||!
(
city
===
undefined
)
||!
(
title
===
undefined
))){
await
Mainimg
.
findByIdAndUpdate
(
newMainimg
.
_id
,
{
theme
:
theme
,
city
:
city
,
title
:
title
,
})
await
Avatar
.
findByIdAndUpdate
(
newMainimg
.
pic
.
_id
,
{
originalfilename
:
originalfilename
,
newfilename
:
newfilename
,
})
console
.
log
(
"
error6
"
)
}
else
{
await
Avatar
.
findByIdAndUpdate
(
newMainimg
.
pic
.
_id
,
{
originalfilename
:
originalfilename
,
newfilename
:
newfilename
,
})
console
.
log
(
"
error5
"
,
newfilename
,
originalfilename
,
theme
,
city
,
title
)}
}
else
(
console
.
log
(
"
error3
"
,
newMainimg
))
}
\ No newline at end of file
src/db/user.db.ts
View file @
4fec5250
import
bcrypt
from
"
bcryptjs
"
;
import
bcrypt
from
"
bcryptjs
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
import
{
ObjectId
}
from
"
mongoose
"
;
import
{
IUser
,
Role
,
Post
,
User
,
Avatar
}
from
"
../models
"
;
import
{
IUser
,
Role
,
Post
,
User
,
Avatar
}
from
"
../models
"
;
import
fs
from
"
fs
"
;
import
fs
from
"
fs
/promises
"
;
export
const
createUser
=
async
(
user
:
IUser
)
=>
{
export
const
createUser
=
async
(
user
:
IUser
)
=>
{
// 비밀번호 암호화
// 비밀번호 암호화
...
@@ -106,9 +106,7 @@ export const deleteUser = async (userId: ObjectId) => {
...
@@ -106,9 +106,7 @@ export const deleteUser = async (userId: ObjectId) => {
const
user
=
await
User
.
findById
(
userId
);
const
user
=
await
User
.
findById
(
userId
);
if
(
!
(
user
?.
avatar
===
undefined
))
{
if
(
!
(
user
?.
avatar
===
undefined
))
{
const
ref
=
await
Avatar
.
findById
(
user
.
avatar
.
_id
);
const
ref
=
await
Avatar
.
findById
(
user
.
avatar
.
_id
);
fs
.
unlink
(
"
../travel/uploads/
"
+
ref
?.
newfilename
,
(
err
)
=>
{
await
fs
.
unlink
(
"
../travel/uploads/
"
+
ref
?.
newfilename
);
console
.
log
(
err
);
});
await
Avatar
.
deleteOne
({
_id
:
user
.
avatar
.
_id
});
await
Avatar
.
deleteOne
({
_id
:
user
.
avatar
.
_id
});
await
User
.
deleteOne
({
_id
:
userId
});
await
User
.
deleteOne
({
_id
:
userId
});
}
}
...
...
src/models/mainimg.model.ts
View file @
4fec5250
import
{
model
,
Schema
}
from
"
mongoose
"
;
import
{
model
,
Schema
,
Types
}
from
"
mongoose
"
;
export
interface
MainimgType
{
export
interface
MainimgType
{
theme
:
string
;
theme
:
string
;
city
:
string
;
city
:
string
;
url
:
string
;
title
:
string
;
title
:
string
;
pic
?:
Types
.
ObjectId
;
}
}
const
MainimgSchema
=
new
Schema
<
MainimgType
>
({
const
MainimgSchema
=
new
Schema
<
MainimgType
>
({
...
@@ -15,13 +15,14 @@ const MainimgSchema = new Schema<MainimgType>({
...
@@ -15,13 +15,14 @@ const MainimgSchema = new Schema<MainimgType>({
city
:
{
city
:
{
type
:
String
,
type
:
String
,
},
},
url
:
{
type
:
String
,
},
title
:
{
title
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
pic
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
"
Avatar
"
}
});
});
...
...
src/routes/mainimg.route.ts
View file @
4fec5250
...
@@ -11,7 +11,7 @@ router
...
@@ -11,7 +11,7 @@ router
router
router
.
route
(
"
/:imgId
"
)
.
route
(
"
/:imgId
"
)
.
delete
(
authCtrl
.
requireLogin
,
mainimgCtrl
.
deleteMainimg
)
.
delete
(
authCtrl
.
requireLogin
,
mainimgCtrl
.
deleteMainimg
)
.
put
(
authCtrl
.
requireLogin
,
mainimgCtrl
.
updateMainimg
);
.
put
(
authCtrl
.
requireLogin
,
authCtrl
.
hasRole
(
"
admin
"
),
mainimgCtrl
.
updateMainimg
);
export
default
router
;
export
default
router
;
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