From 0b342e39614294ace1cbe4bb22ae12fc03f35e31 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Wed, 12 May 2021 22:57:59 +0900 Subject: [PATCH 001/176] =?UTF-8?q?chore=20:=20PlayGroundBotAPi=20-=20Play?= =?UTF-8?q?Ground=20=EC=83=9D=EC=84=B1=20=ED=9B=84=20=EB=A0=88=ED=8F=AC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EA=B4=80=EB=A0=A8=ED=95=9C=20API=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20JSON=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/playground/api_req/PlaygroundBotApi.java | 14 ++++++++++++++ Backend/src/main/resources/json/playground.json | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/dto/playground/api_req/PlaygroundBotApi.java diff --git a/Backend/src/main/java/com/pg/programmerground/dto/playground/api_req/PlaygroundBotApi.java b/Backend/src/main/java/com/pg/programmerground/dto/playground/api_req/PlaygroundBotApi.java new file mode 100644 index 0000000..933c006 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/dto/playground/api_req/PlaygroundBotApi.java @@ -0,0 +1,14 @@ +package com.pg.programmerground.dto.playground.api_req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +@Getter +public class PlaygroundBotApi { + private String name; + private String description; + @JsonProperty("homepage") + private String homePage; + @JsonProperty("private") + private boolean isPrivate; +} diff --git a/Backend/src/main/resources/json/playground.json b/Backend/src/main/resources/json/playground.json index 5922f9a..b12fa5c 100644 --- a/Backend/src/main/resources/json/playground.json +++ b/Backend/src/main/resources/json/playground.json @@ -118,5 +118,11 @@ ] } ] - } + }, + "create_org_repo": { + "name": "pg-test-repo", + "description": "test-repo", + "homepage": "https://github.com", + "private": false + } } From b9a018c1022095410e9eace9ae86c479b120df6b Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sat, 15 May 2021 13:52:23 +0900 Subject: [PATCH 002/176] test : GET Github Organization Info, Create github Organization Repository --- .../playground/PlayGroundBotTest.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java diff --git a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java new file mode 100644 index 0000000..7e05954 --- /dev/null +++ b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java @@ -0,0 +1,98 @@ +package com.pg.programmerground.playground; + +import com.pg.programmerground.TestUserManagement; +import com.pg.programmerground.model.Oauth2AuthorizedClientRepository; +import com.pg.programmerground.service.GithubRestService; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class PlayGroundBotTest { + + private static final Long GITHUB_BOT_ID = 83174448L; + private static final String PREFIX_GITHUB_API = "https://api.github.com/orgs/programmer-ground"; + private static final String PREFIX_ACCESS_TOKEN = "Bearer "; + TestJsonPackage dtoList; + + @Autowired + private GithubRestService githubRestService; + + @Autowired + TestUserManagement management; + + @Autowired + private Oauth2AuthorizedClientRepository oauth2AuthorizedClientRepository; + + + @BeforeAll + void dataSetUp() throws IOException { + dtoList = TestJsonPackage.of(); + management.saveGithubRepoBotUser(); + } + + @Test + @DisplayName("생성된 BOT 계정으로 소속 Organization의 정보를 얻을 수 있다.") + public void get_github_org_by_bot_user() { + String githubBotUserToken = oauth2AuthorizedClientRepository + .findById(GITHUB_BOT_ID) + .orElseThrow(IllegalArgumentException::new) + .getAccessTokenValue(); + + System.out.println(githubBotUserToken); + + HttpHeaders header = new HttpHeaders(); + header.set("Accept", "application/vnd.github.v3+json"); + header.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotUserToken); + + String rest = githubRestService + .rest(PREFIX_GITHUB_API, HttpMethod.GET, header, String.class); + + System.out.println(rest); + } + + @Test + @DisplayName("생성된 BOT 계정으로 Repo를 생성할 수 있다") + public void create_github_repo_by_bot_user() { + /* + * { + * "name": "", + * "description": "", + * "homepage": "https://github.com", + * "private": false, + * } + */ + String githubBotUserToken = oauth2AuthorizedClientRepository + .findById(GITHUB_BOT_ID) + .orElseThrow(IllegalArgumentException::new) + .getAccessTokenValue(); + + HttpHeaders headers = new HttpHeaders(); + headers.set("Accept", "application/vnd.github.v3+json"); + headers.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotUserToken); + + Map requestBody = new HashMap<>(); + requestBody.put("name", "test-pg-bot-repo"); + + HttpEntity> request = new HttpEntity<>(requestBody, headers); + + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity responseEntity = restTemplate + .postForEntity(PREFIX_GITHUB_API + "/repos", request, String.class); + + System.out.println(responseEntity.getBody()); + } + +} From df0543573ca48d5cfa496735d6f6c188b86ef4b4 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sat, 15 May 2021 14:34:14 +0900 Subject: [PATCH 003/176] =?UTF-8?q?refactor=20:=20header=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=20=EB=B6=80=EB=B6=84=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playground/PlayGroundBotTest.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java index 7e05954..8a064f7 100644 --- a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java +++ b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java @@ -1,5 +1,8 @@ package com.pg.programmerground.playground; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.pg.programmerground.TestUserManagement; import com.pg.programmerground.model.Oauth2AuthorizedClientRepository; import com.pg.programmerground.service.GithubRestService; @@ -15,7 +18,9 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; @SpringBootTest @@ -25,6 +30,7 @@ public class PlayGroundBotTest { private static final Long GITHUB_BOT_ID = 83174448L; private static final String PREFIX_GITHUB_API = "https://api.github.com/orgs/programmer-ground"; private static final String PREFIX_ACCESS_TOKEN = "Bearer "; + private static final RestTemplate restTemplate = new RestTemplate(); TestJsonPackage dtoList; @Autowired @@ -46,20 +52,12 @@ void dataSetUp() throws IOException { @Test @DisplayName("생성된 BOT 계정으로 소속 Organization의 정보를 얻을 수 있다.") public void get_github_org_by_bot_user() { - String githubBotUserToken = oauth2AuthorizedClientRepository - .findById(GITHUB_BOT_ID) - .orElseThrow(IllegalArgumentException::new) - .getAccessTokenValue(); - - System.out.println(githubBotUserToken); - - HttpHeaders header = new HttpHeaders(); - header.set("Accept", "application/vnd.github.v3+json"); - header.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotUserToken); - + //given + HttpHeaders headers = getHeaders(); + //when String rest = githubRestService - .rest(PREFIX_GITHUB_API, HttpMethod.GET, header, String.class); - + .rest(PREFIX_GITHUB_API, HttpMethod.GET, headers, String.class); + //then System.out.println(rest); } @@ -74,25 +72,29 @@ public void create_github_repo_by_bot_user() { * "private": false, * } */ - String githubBotUserToken = oauth2AuthorizedClientRepository + //given + Map requestBody = new HashMap<>(); + requestBody.put("name", "test-pg-bot-repo"); + HttpEntity> request = new HttpEntity<>(requestBody, getHeaders()); + //when + ResponseEntity responseEntity = restTemplate + .postForEntity(PREFIX_GITHUB_API + "/repos", request, String.class); + //then + assertEquals(responseEntity.getStatusCode(), HttpStatus.CREATED); + } + + + + private HttpHeaders getHeaders() { + String githubBotToken = oauth2AuthorizedClientRepository .findById(GITHUB_BOT_ID) .orElseThrow(IllegalArgumentException::new) .getAccessTokenValue(); HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/vnd.github.v3+json"); - headers.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotUserToken); - - Map requestBody = new HashMap<>(); - requestBody.put("name", "test-pg-bot-repo"); - - HttpEntity> request = new HttpEntity<>(requestBody, headers); - - RestTemplate restTemplate = new RestTemplate(); - ResponseEntity responseEntity = restTemplate - .postForEntity(PREFIX_GITHUB_API + "/repos", request, String.class); - - System.out.println(responseEntity.getBody()); + headers.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotToken); + return headers; } } From 5d8ddb6685970dd490a9d7136e591b709d8d1df0 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 30 Jun 2021 01:56:48 +0900 Subject: [PATCH 004/176] =?UTF-8?q?feat=20-=20playground=20get=20api=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/request.ts | 3 +- Frontend/src/pages/PlayGroundPage/index.tsx | 35 +++++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index b4d0255..5f2cf7e 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -63,7 +63,7 @@ const getReissued = async () => { }; export const getData = async (url: string) => { - const options = getOptions(); + const options = await getOptions(); try { const response = await axios.get(url, options); return response.data.data; @@ -74,7 +74,6 @@ export const getData = async (url: string) => { export const postData = async (url: string, body: string) => { const options = await getOptions(); - console.log(options); try { const response = await axios.post(url, body, options); return response.data; diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index 669fa4f..22d760e 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -1,10 +1,11 @@ +/* eslint-disable no-unused-expressions */ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable consistent-return */ /* eslint-disable no-return-await */ /* eslint-disable react/jsx-pascal-case */ /* eslint-disable array-callback-return */ // @ts-nocheck -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useLayoutEffect } from 'react'; import Header from '@src/components/header'; import SearchBar from '@src/components/searchBar'; import Bone from '@src/components/Common/bone'; @@ -12,30 +13,32 @@ import PlaygroundContent from '@src/components/playgroundContent'; import playgroundData from '@src/data/playground'; import Button from '@src/components/Common/button'; import { getAllPlaygrounds } from '@src/lib/axios/playground'; +import useShow from '@src/hooks/useShow'; import * as StyledComponent from './style'; const PlayGroundPage = () => { const groundData = playgroundData.content; - const [playground, setPlayground] = useState([]); - // const fetchData = async () => { - // try { - // const data = await getAllPlaygrounds(); - // setPlayground(data); - // } catch (e) { - // // eslint-disable-next-line no-console - // console.log(e); - // } - // }; - // useEffect(() => { - // fetchData(); - // }, []); - + const [show, dispatch] = useShow(); + const [datas, setData] = useState([]); + useEffect(() => { + const fetchData = async () => { + try { + const data = await getAllPlaygrounds(); + setData(data.playground_card); + } catch (e) { + console.log(e); + } + }; + fetchData(); + }, []); return ( <>
+ {datas.map((v) => { + return

{v.playground_id}

; + })} - {playground.playground_card} From 45b7ad4482cd20bb15da57898ff9a7057287b6e7 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 30 Jun 2021 16:49:53 +0900 Subject: [PATCH 005/176] feat - playground - get rendering --- Frontend/src/pages/PlayGroundPage/index.tsx | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index 22d760e..dca4bfc 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -10,21 +10,19 @@ import Header from '@src/components/header'; import SearchBar from '@src/components/searchBar'; import Bone from '@src/components/Common/bone'; import PlaygroundContent from '@src/components/playgroundContent'; -import playgroundData from '@src/data/playground'; import Button from '@src/components/Common/button'; import { getAllPlaygrounds } from '@src/lib/axios/playground'; import useShow from '@src/hooks/useShow'; import * as StyledComponent from './style'; const PlayGroundPage = () => { - const groundData = playgroundData.content; const [show, dispatch] = useShow(); - const [datas, setData] = useState([]); + const [playgrounds, setPlaygrounds] = useState([]); useEffect(() => { const fetchData = async () => { try { const data = await getAllPlaygrounds(); - setData(data.playground_card); + setPlaygrounds(data.playground_card); } catch (e) { console.log(e); } @@ -34,9 +32,7 @@ const PlayGroundPage = () => { return ( <>
- {datas.map((v) => { - return

{v.playground_id}

; - })} + @@ -47,16 +43,13 @@ const PlayGroundPage = () => { 방 생성 - {groundData.map((v) => { + {playgrounds.map((v) => { return ( ); })} From 19584a1c1b01c7c34e462aca93d780214c570428 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sat, 3 Jul 2021 13:17:46 +0900 Subject: [PATCH 006/176] =?UTF-8?q?refactor:=20Playground=20Apply=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/PlaygroundApply.java | 20 +++++++++---------- .../domain/enumerated/ApplyStatus.java | 2 +- .../response/UserApplyNoticeResponse.java | 6 ++++++ .../model/PlaygroundApplyRepository.java | 10 ++++++---- .../service/NoticeService.java | 6 +++--- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundApply.java b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundApply.java index 3fe2fec..b0789e4 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundApply.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundApply.java @@ -38,18 +38,18 @@ public class PlaygroundApply extends BaseTimeEntity { @Column(name = "APPLY_STATUS") @Enumerated(EnumType.STRING) - private ApplyStatus applyYn; + private ApplyStatus applyStatus; @Builder - public PlaygroundApply(OAuthUser user, Playground playground, PlaygroundPosition playgroundPosition, ApplyStatus applyYn) { + public PlaygroundApply(OAuthUser user, Playground playground, PlaygroundPosition playgroundPosition, ApplyStatus applyStatus) { Assert.notNull(user, "user must not be null"); Assert.notNull(playground, "playground must not be null"); Assert.notNull(playgroundPosition, "playgroundPosition must not be null"); - Assert.notNull(applyYn, "applyYn must not be null"); + Assert.notNull(applyStatus, "applyStatus must not be null"); this.user = user; this.playground = playground; this.playgroundPosition = playgroundPosition; - this.applyYn = applyYn; + this.applyStatus = applyStatus; } /** @@ -58,7 +58,7 @@ public PlaygroundApply(OAuthUser user, Playground playground, PlaygroundPosition */ public void acceptApply(OAuthUser user) { this.playground.isLeaderUser(user); - this.applyYn = ApplyStatus.ACCEPT; + this.applyStatus = ApplyStatus.ACCEPT; this.playgroundPosition.increaseMemberNum(); this.playground.increaseMemberNum(); } @@ -68,7 +68,7 @@ public void acceptApply(OAuthUser user) { */ public void rejectApply(OAuthUser user) { this.playground.isLeaderUser(user); - this.applyYn = ApplyStatus.REJECT; + this.applyStatus = ApplyStatus.REJECT; } /** * Playground 생성시 리더의 포지션을 넣기 위한 함수 @@ -78,7 +78,7 @@ public static void createLeaderApply(OAuthUser user, Playground playground, Play .user(user) .playground(playground) .playgroundPosition(playgroundPosition) - .applyYn(ApplyStatus.ACCEPT) //리더는 포지션에 넣음 + .applyStatus(ApplyStatus.ACCEPT) //리더는 포지션에 넣음 .build(); playgroundPosition.increaseMember(); //Position 증가 user.getApplyPlaygrounds().add(playgroundApply); @@ -106,7 +106,7 @@ public static void createUserApply(OAuthUser user, Playground playground, Playgr .user(user) .playground(playground) .playgroundPosition(playgroundPosition) - .applyYn(ApplyStatus.WAIT) + .applyStatus(ApplyStatus.WAIT) .build(); //양방향 관계 매핑 user.getApplyPlaygrounds().add(playgroundApply); @@ -118,14 +118,14 @@ public static void createUserApply(OAuthUser user, Playground playground, Playgr * 해당 Playground에 이미 참여중인지 판별 */ public boolean isAlreadyMember(OAuthUser user) { - return this.user.equals(user) && this.applyYn != ApplyStatus.REJECT; + return this.user.equals(user) && this.applyStatus != ApplyStatus.REJECT; } /** * Playground에 참가중인가 */ public boolean isAcceptApply() { - return this.applyYn == ApplyStatus.ACCEPT; + return this.applyStatus == ApplyStatus.ACCEPT; } @Override diff --git a/Backend/src/main/java/com/pg/programmerground/domain/enumerated/ApplyStatus.java b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/ApplyStatus.java index 4638e76..d8d7c81 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/enumerated/ApplyStatus.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/ApplyStatus.java @@ -4,5 +4,5 @@ public enum ApplyStatus { ACCEPT, REJECT, WAIT, - EXIT //탈퇴 + EXIT //Playground 퇴장 } diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java index f5a8bc0..7ce7dc7 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.pg.programmerground.domain.PlaygroundApply; +import com.pg.programmerground.domain.enumerated.ApplyStatus; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -15,12 +16,17 @@ public class UserApplyNoticeResponse { @JsonProperty(value = "playground_title") private final String playgroundTitle; + @JsonProperty(value = "playground_apply_id") + private final Long playgroundApplyId; private final String position; + private final ApplyStatus status; public static List ofList(List playgroundApplyList) { return playgroundApplyList.stream() .map(playgroundApply -> UserApplyNoticeResponse.builder() .playgroundTitle(playgroundApply.getPlayground().getTitle()) + .playgroundApplyId(playgroundApply.getId()) + .status(playgroundApply.getApplyStatus()) .position(playgroundApply.getPlaygroundPosition().getPosition().name()).build()) .collect(Collectors.toList()); } diff --git a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundApplyRepository.java b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundApplyRepository.java index 35911fe..cf856e2 100644 --- a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundApplyRepository.java +++ b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundApplyRepository.java @@ -1,6 +1,7 @@ package com.pg.programmerground.model; import com.pg.programmerground.domain.PlaygroundApply; +import com.pg.programmerground.domain.enumerated.ApplyStatus; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -17,7 +18,7 @@ public interface PlaygroundApplyRepository extends JpaRepository findPlaygroundApplyByLeader(@Param("leaderUserId")Long leaderUserId); /** @@ -28,7 +29,8 @@ public interface PlaygroundApplyRepository extends JpaRepository :userId") - List findPlaygroundApplyByOAuthUserAndStatus(@Param("userId")Long userId, @Param("status")List status); + "WHERE pa.applyStatus IN :status " + + "AND p.leader.id <> :userId " + + "AND pa.user.id = :userId") + List findPlaygroundApplyByOAuthUserAndStatus(@Param("userId")Long userId, @Param("status")List status); } diff --git a/Backend/src/main/java/com/pg/programmerground/service/NoticeService.java b/Backend/src/main/java/com/pg/programmerground/service/NoticeService.java index a8cfb1a..1b6add5 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/NoticeService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/NoticeService.java @@ -31,13 +31,13 @@ public UserLeaderNoticeListResponse getUserNoticeList(Long userId) { } public UserApplyNoticeListResponse getUserStatusNoticeList(Long userId, String status) { - List statusList; + List statusList; switch (status) { case "wait": - statusList = new ArrayList<>(Collections.singletonList(ApplyStatus.WAIT.name())); + statusList = new ArrayList<>(Collections.singletonList(ApplyStatus.WAIT)); break; case "result": - statusList = new ArrayList<>(Arrays.asList(ApplyStatus.ACCEPT.name(), ApplyStatus.REJECT.name())); + statusList = new ArrayList<>(Arrays.asList(ApplyStatus.ACCEPT, ApplyStatus.REJECT)); break; default: throw new IllegalStateException("Unexpected value: " + status); From 7349f8df43661589a339d2154969795c2d3b7389 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sun, 4 Jul 2021 18:07:10 +0900 Subject: [PATCH 007/176] =?UTF-8?q?feat=20:=20yml=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=ED=95=84=EB=93=9C=EB=A5=BC=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20GithubBotConfig=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/GithubBotConfig.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Backend/src/main/java/com/pg/programmerground/config/GithubBotConfig.java diff --git a/Backend/src/main/java/com/pg/programmerground/config/GithubBotConfig.java b/Backend/src/main/java/com/pg/programmerground/config/GithubBotConfig.java new file mode 100644 index 0000000..f8e79eb --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/config/GithubBotConfig.java @@ -0,0 +1,17 @@ +package com.pg.programmerground.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + + +@Getter +@Setter +@Configuration +@ConfigurationProperties(prefix = "github") +public class GithubBotConfig { + private String token; + private String orgUrl; + private String orgRepoUrl; +} From 8c9111e4f4130d2b09fa8fe3b0b82221abfcf372 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sun, 4 Jul 2021 18:07:31 +0900 Subject: [PATCH 008/176] =?UTF-8?q?feat=20:=20Github=20URL=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B4=80=EB=A0=A8=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20Util=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../programmerground/util/GithubHttpUtil.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Backend/src/main/java/com/pg/programmerground/util/GithubHttpUtil.java diff --git a/Backend/src/main/java/com/pg/programmerground/util/GithubHttpUtil.java b/Backend/src/main/java/com/pg/programmerground/util/GithubHttpUtil.java new file mode 100644 index 0000000..a18b8a9 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/util/GithubHttpUtil.java @@ -0,0 +1,20 @@ +package com.pg.programmerground.util; + +import org.springframework.http.HttpHeaders; + +public class GithubHttpUtil { + private final static String AUTH_PREFIX = "Authorization"; + private final static String ACCEPT_PREFIX = "Accept"; + private final static String ACCEPT_GITHUB_HEADER = "application/vnd.github.v3+json"; + + public static HttpHeaders generateGithubApiHeader(String token) { + HttpHeaders headers = new HttpHeaders(); + headers.set(ACCEPT_PREFIX, ACCEPT_GITHUB_HEADER); + headers.set(AUTH_PREFIX, token); + return headers; + } + + public static String generateCollaboratorUrl(String repoTitle, String userName) { + return "/" + repoTitle + "/collaborator/" + userName; + } +} From 5eff740f1e1b46bca7f9a37a2d4f569a01a62a0a Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sun, 4 Jul 2021 18:10:11 +0900 Subject: [PATCH 009/176] =?UTF-8?q?test=20:=20github=20Bot=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=20-=20TestUserManagerment.saveGithubRepoBotUser()=20:=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=A0=84=EC=97=AD=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=82=AC=EC=9A=A9=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EA=B9=83=ED=97=88=EB=B8=8C=20=EB=B4=87=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=20-=20PlaygroundBotTest=20:=20=EC=8B=A4=EC=A0=9C?= =?UTF-8?q?=20=EB=B4=87=20=EC=9C=A0=EC=A0=80=EB=A5=BC=20=ED=99=9C=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=ED=96=89=20=20-=20GithubBotConfigTest=20:=20yml=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=9D=84=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=EC=A7=80=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../programmerground/TestUserManagement.java | 32 ++++++ .../config/GithubBotConfigTest.java | 30 +++++ .../playground/PlayGroundBotTest.java | 106 +++++++++++++++--- 3 files changed, 155 insertions(+), 13 deletions(-) create mode 100644 Backend/src/test/java/com/pg/programmerground/config/GithubBotConfigTest.java diff --git a/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java b/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java index 4dae815..f0f1513 100644 --- a/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java +++ b/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java @@ -1,5 +1,6 @@ package com.pg.programmerground; +import com.pg.programmerground.config.GithubBotConfig; import com.pg.programmerground.domain.OAuthUser; import com.pg.programmerground.domain.github.Oauth2AuthorizedClient; import com.pg.programmerground.domain.github.UserGithubInfo; @@ -15,6 +16,10 @@ public class TestUserManagement { private static final Long GITHUB_ID = 1234L; private static final Long GITHUB_ID2 = 12345L; + private static final Long GITHUB_BOT_ID = 83174448L; + + @Autowired + private GithubBotConfig githubBotConfig; @Autowired private OAuthUserRepository oAuthUserRepository; @Autowired @@ -71,6 +76,33 @@ public void saveTestUser() { oAuthUserRepository.save(oAuthUser2); } + @Transactional + public void saveGithubRepoBotUser() { + Oauth2AuthorizedClient oauth2AuthorizedClient = Oauth2AuthorizedClient.builder() + .id(GITHUB_BOT_ID) + .clientRegistrationId("github") + .accessTokenScopes("read:user") + .accessTokenType("Bearer") + .accessTokenValue(githubBotConfig.getToken()) + .build(); + UserGithubInfo userGithubInfo = UserGithubInfo.builder() + .commitCnt(0) + .pullRequestCnt(0) + .repositoryCnt(0) + .build(); + OAuthUser oAuthUser = OAuthUser.builder() + .userName("test") + .OAuthName("test") + .Role("ROLE_USER,SCOPE_read:user") + .oauth2AuthorizedClient(oauth2AuthorizedClient) + .userGithubInfo(userGithubInfo) + .build(); + + userGithubInfoRepository.save(userGithubInfo); + oauth2AuthorizedClientRepository.save(oauth2AuthorizedClient); + oAuthUserRepository.save(oAuthUser); + } + @Transactional public void deleteTestUser() { oAuthUserRepository.delete(oauth2AuthorizedClientRepository.findById(1234L).orElseThrow().getUser()); diff --git a/Backend/src/test/java/com/pg/programmerground/config/GithubBotConfigTest.java b/Backend/src/test/java/com/pg/programmerground/config/GithubBotConfigTest.java new file mode 100644 index 0000000..85930a3 --- /dev/null +++ b/Backend/src/test/java/com/pg/programmerground/config/GithubBotConfigTest.java @@ -0,0 +1,30 @@ +package com.pg.programmerground.config; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class GithubBotConfigTest { + @Autowired + private GithubBotConfig githubBotConfig; + + @Test + void yamlFileTest() { + String token = githubBotConfig.getToken(); + String orgUrl = githubBotConfig.getOrgUrl(); + String orgRepoUrl = githubBotConfig.getOrgRepoUrl(); + + System.out.println("Bot Token : " + token); + System.out.println("Github Org URL : " + orgUrl); + System.out.println("Github Org Repo URL " + orgRepoUrl); + + assertAll( + () -> assertTrue(token.contains("bearer ")), + () -> assertEquals(orgUrl, "https://api.github.com/orgs/programmer-ground"), + () -> assertEquals(orgRepoUrl, "https://api.github.com/repos/programmer-ground") + ); + } +} \ No newline at end of file diff --git a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java index 8a064f7..ff4e26c 100644 --- a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java +++ b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java @@ -4,12 +4,19 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import com.pg.programmerground.TestUserManagement; -import com.pg.programmerground.model.Oauth2AuthorizedClientRepository; +import com.pg.programmerground.auth.jwt.JwtAuthenticationToken; +import com.pg.programmerground.config.GithubBotConfig; +import com.pg.programmerground.domain.Playground; +import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; +import com.pg.programmerground.model.PlaygroundRepository; import com.pg.programmerground.service.GithubRestService; +import com.pg.programmerground.service.OAuthUserService; +import com.pg.programmerground.service.PlaygroundService; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -20,6 +27,9 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; @@ -27,12 +37,13 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class PlayGroundBotTest { - private static final Long GITHUB_BOT_ID = 83174448L; - private static final String PREFIX_GITHUB_API = "https://api.github.com/orgs/programmer-ground"; - private static final String PREFIX_ACCESS_TOKEN = "Bearer "; + private static final Long GITHUB_ID = 1234L; private static final RestTemplate restTemplate = new RestTemplate(); TestJsonPackage dtoList; + @Autowired + private GithubBotConfig githubBotConfig; + @Autowired private GithubRestService githubRestService; @@ -40,15 +51,30 @@ public class PlayGroundBotTest { TestUserManagement management; @Autowired - private Oauth2AuthorizedClientRepository oauth2AuthorizedClientRepository; + private OAuthUserService oAuthUserService; + + @Autowired + private PlaygroundService playgroundService; + + @Autowired + private PlaygroundRepository playgroundRepository; @BeforeAll void dataSetUp() throws IOException { dtoList = TestJsonPackage.of(); + management.saveTestUser(); management.saveGithubRepoBotUser(); } + @BeforeEach + void authenticationSetUp() { + //Github 로그인을 한번 시도하고 + UserDetails userDetails = oAuthUserService.loadUserByOAuthId(GITHUB_ID); + Authentication authentication = new JwtAuthenticationToken(userDetails, "토큰 값 필요없음", userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + @Test @DisplayName("생성된 BOT 계정으로 소속 Organization의 정보를 얻을 수 있다.") public void get_github_org_by_bot_user() { @@ -56,11 +82,25 @@ public void get_github_org_by_bot_user() { HttpHeaders headers = getHeaders(); //when String rest = githubRestService - .rest(PREFIX_GITHUB_API, HttpMethod.GET, headers, String.class); + .rest(githubBotConfig.getOrgUrl(), HttpMethod.GET, headers, String.class); //then System.out.println(rest); } + @Test + @DisplayName("PlayGround의 Leader가 Github Repository 생성 요청을 할 수 있다") + public void playground_leader_request_create_github_repo() throws Exception { + //given + PlaygroundApi playgroundApi = dtoList.createPlayground; + Long playgroundId = playgroundService.createPlayground(playgroundApi); + Playground playground = playgroundRepository.findById(playgroundId).orElseThrow(); + + //when + playgroundService.getPlaygroundDetailInfo(playgroundId); + + //then + } + @Test @DisplayName("생성된 BOT 계정으로 Repo를 생성할 수 있다") public void create_github_repo_by_bot_user() { @@ -78,22 +118,62 @@ public void create_github_repo_by_bot_user() { HttpEntity> request = new HttpEntity<>(requestBody, getHeaders()); //when ResponseEntity responseEntity = restTemplate - .postForEntity(PREFIX_GITHUB_API + "/repos", request, String.class); + .postForEntity(githubBotConfig.getOrgUrl() + "/repos", request, String.class); //then assertEquals(responseEntity.getStatusCode(), HttpStatus.CREATED); } + @Test + @DisplayName("해당 Repository에 유저를 Collaborator로 추가할 수 있다") + public void add_collaborator_github_repo() { + //given + String targetUrl = githubBotConfig.getOrgRepoUrl() + "/test-repo/collaborators/pg-test-user-1"; + HttpEntity entity = new HttpEntity<>(getHeaders()); + //when + ResponseEntity exchange = restTemplate + .exchange(targetUrl, HttpMethod.PUT, entity, String.class); - private HttpHeaders getHeaders() { - String githubBotToken = oauth2AuthorizedClientRepository - .findById(GITHUB_BOT_ID) - .orElseThrow(IllegalArgumentException::new) - .getAccessTokenValue(); + //then + assertEquals(exchange.getStatusCode(), HttpStatus.CREATED); + } + + @Test + @DisplayName("해당 Repository에 추가할 유저가 Collabrator로 등록이 안되어있을 시 404 익셉션이 발생한다") + public void if_not_exist_collaborator_github_repo() { + //given + String targetUrl = githubBotConfig.getOrgRepoUrl() +"/test-repo/collaborators/pg-test-user-1"; + HttpEntity entity = new HttpEntity<>(getHeaders()); + + //when + HttpClientErrorException thrown = assertThrows(HttpClientErrorException.class, + () -> restTemplate + .exchange(targetUrl, HttpMethod.GET, entity, String.class) + ); + + //then + assertEquals(thrown.getStatusCode(), HttpStatus.NOT_FOUND); + } + @Test + @DisplayName("해당 Repository에 추가할 유저가 Collabrator로 등록이 되어있을 시 204 No Content 리스폰스가 발생한다") + public void if_exist_collaborator_github_repo() { + //given + String targetUrl = githubBotConfig.getOrgRepoUrl() + "/test-repo/collaborators/pg-test-user-2"; + HttpEntity entity = new HttpEntity<>(getHeaders()); + + //when + ResponseEntity exchange = restTemplate + .exchange(targetUrl, HttpMethod.GET, entity, String.class); + + //then + assertEquals(exchange.getStatusCode(), HttpStatus.NO_CONTENT); + } + + private HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/vnd.github.v3+json"); - headers.set("Authorization", PREFIX_ACCESS_TOKEN + githubBotToken); + headers.set("Authorization", githubBotConfig.getToken()); return headers; } From 50c9172b01210001bd10dddc27998fe9ffa31b68 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sun, 4 Jul 2021 18:13:48 +0900 Subject: [PATCH 010/176] =?UTF-8?q?feat=20:=20GithubBot=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=B0=8F=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PlaygroundController.java | 25 +++++++ .../service/PlaygroundService.java | 65 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java index 1a7cc29..7149ccf 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java @@ -85,4 +85,29 @@ public ResponseEntity> revisePlayground(@Valid RevisePlaygr public ResponseEntity> deletePlayground(@PathVariable Long playgroundId) { return ResponseEntity.ok().body(new ApiResponse<>(null)); } + + /** + * Playground 레포 생성 요청 + * TODO : 응답 값 객체 만들 예정 + */ + @PostMapping("/{playgroundId}/repo") + public ResponseEntity createPlaygroundGithubRepo( + @PathVariable Long playgroundId, + @Valid @RequestBody String repoTitle) { + +// return ResponseEntity.ok() +// .body(new ApiResponse<>(playgroundService.createPlaygroundGithubRepo(playgroundId, repoTitle))); + return ResponseEntity.ok().body(playgroundService.createPlaygroundGithubRepo(playgroundId, repoTitle)); + } + + /** + * 생성된 Github Repo에 Playground Member를 Collaborator로 등록 + * TODO : 응답 값 및 에러 수정 필요 + */ + @PutMapping("/{playgroundId}/collaborators") + public ResponseEntity applyCollaborators( + @PathVariable Long playgroundId, + @Valid @RequestBody String repoTitle) { + return ResponseEntity.ok().body(playgroundService.applyCollaboratorPlaygroundGithubRepo(playgroundId, repoTitle)); + } } diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 17ab430..0653f28 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -11,22 +11,36 @@ import com.pg.programmerground.model.OAuthUserRepository; import com.pg.programmerground.model.PlaygroundApplyRepository; import com.pg.programmerground.model.PlaygroundRepository; +import com.pg.programmerground.config.GithubBotConfig; +import com.pg.programmerground.util.GithubHttpUtil; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.modelmapper.ModelMapper; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.NoSuchElementException; +import org.springframework.web.client.RestTemplate; @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class PlaygroundService { + private static final String PREFIX_GITHUB_ORG_REPO_API = "https://api.github.com/repos/programmer-ground"; + private final PlaygroundRepository playgroundRepository; private final PlaygroundApplyRepository playgroundApplyRepository; private final OAuthUserRepository oAuthUserRepository; private final ModelMapper modelMapper; + private final GithubBotConfig botConfig; /** * 메인 페이지 playground card 목록 가져오기 @@ -92,4 +106,55 @@ public PlaygroundResponse getPlaygroundDetailInfo(Long playgroundId) { return PlaygroundResponse.of( playgroundRepository.findById(playgroundId).orElseThrow(() -> new NoSuchElementException("playground 존재 안함"))); } + + // TODO : Playground 도메인 단에서 githubRepo 이름을 업데이트하게끔 처리할 예정 + public ResponseEntity createPlaygroundGithubRepo(Long playgroundId, String repoTitle) { + RestTemplate restTemplate = new RestTemplate(); + + Playground playground = playgroundRepository.findById(playgroundId) + .orElseThrow(() -> new NoSuchElementException("존재하지 않는 Playground 입니다.")); + + String apiUrl = botConfig.getOrgUrl(); + HttpHeaders headers = GithubHttpUtil.generateGithubApiHeader(botConfig.getToken()); + + Map requestBody = new HashMap<>(); + requestBody.put("name", repoTitle); + + HttpEntity> request = new HttpEntity<>(requestBody, headers); + + return restTemplate.postForEntity(apiUrl + "/repos", request, String.class); + } + + // TODO : 각 유저별 레포지트리 권한 관련 추가 예정 + public ResponseEntity applyCollaboratorPlaygroundGithubRepo(Long playgroundId, String repoTitle) { + RestTemplate restTemplate = new RestTemplate(); + String apiUrl = botConfig.getOrgRepoUrl(); + Playground playground = playgroundRepository.findById(playgroundId) + .orElseThrow(() -> new NoSuchElementException("존재하지 않는 Playground 입니다.")); + + List applyPlaygrounds = playground.getApplyPlaygrounds(); + List temp = new ArrayList<>(); + + for(PlaygroundApply apply : applyPlaygrounds) { + if(apply.isAcceptApply()) { + temp.add(apply); + } + } + + HttpEntity entity = new HttpEntity<>(GithubHttpUtil.generateGithubApiHeader(botConfig.getToken())); + + for(PlaygroundApply user : temp) { + String collaboratorUrl = GithubHttpUtil + .generateCollaboratorUrl(repoTitle, user.getUser().getUserName()); + + ResponseEntity exchange = restTemplate + .exchange(apiUrl + collaboratorUrl, HttpMethod.PUT, entity, String.class); + + if(exchange.getStatusCode() != HttpStatus.CREATED || exchange.getStatusCode() != HttpStatus.NO_CONTENT) { + throw new IllegalArgumentException("알수 없는 오류가 발생하였습니다."); + } + } + + return (ResponseEntity) ResponseEntity.accepted(); + } } From 1c78d020c3d4b577cf33d0ba82817e71848f08c1 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sun, 4 Jul 2021 18:14:09 +0900 Subject: [PATCH 011/176] =?UTF-8?q?chore=20:=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EA=B0=92=20=EC=B6=94=EA=B0=80=20(=EA=B9=83=ED=97=88=EB=B8=8C?= =?UTF-8?q?=20=EB=B4=87=20=ED=86=A0=ED=81=B0=20=EB=B0=8F=20url=20=EB=93=B1?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backend/src/main/resources/application.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Backend/src/main/resources/application.yml b/Backend/src/main/resources/application.yml index 4957bd1..466aac3 100644 --- a/Backend/src/main/resources/application.yml +++ b/Backend/src/main/resources/application.yml @@ -1,7 +1,8 @@ --- # Suung Profile YAML spring: - profiles: seansin-local + profiles: + active: seansin-local # 자신의 환경에 맞게 active 하면됌. datasource: @@ -33,11 +34,15 @@ spring: jwt-token: secret-key: awdsd +github: + token: "bearer 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" + org-url : "https://api.github.com/orgs/programmer-ground" + org-repo-url : "https://api.github.com/repos/programmer-ground" + #logging: # level # org.hibernate.SQL: debug # org.hibernate.type: trace - server: port: 8080 --- @@ -45,8 +50,7 @@ server: --- # Jeawoo Profile YAML spring: - profiles: - active: jeawoo-local + profiles: jeawoo-local datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/auth?serverTimezone=UTC&characterEncoding=UTF-8 From 56f460c391a92a455bee1a653a8c8a9c91190502 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sun, 4 Jul 2021 21:25:54 +0900 Subject: [PATCH 012/176] =?UTF-8?q?feat:=20=ED=8C=8C=EC=9D=BC=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=B6=94=EC=83=81=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84,=20Playground=20Main=20Img=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pg/auth/controller/AuthController.java | 8 +-- .../auth/config/Oauth2WebSecurityConfig.java | 1 + .../controller/ImageController.java | 34 +++++++++++ .../controller/PlaygroundController.java | 12 +--- .../programmerground/domain/Playground.java | 16 +++++- .../pg/programmerground/dto/UploadImg.java | 13 +++++ .../service/PlaygroundService.java | 12 ++-- .../service/upload/FileStore.java | 57 +++++++++++++++++++ .../upload/PlaygroundMainImgStore.java | 24 ++++++++ Backend/src/main/resources/application.yml | 23 +++++++- 10 files changed, 179 insertions(+), 21 deletions(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/controller/ImageController.java create mode 100644 Backend/src/main/java/com/pg/programmerground/dto/UploadImg.java create mode 100644 Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java create mode 100644 Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java diff --git a/Authentication/src/main/java/com/pg/auth/controller/AuthController.java b/Authentication/src/main/java/com/pg/auth/controller/AuthController.java index 3f54c64..bfc301e 100644 --- a/Authentication/src/main/java/com/pg/auth/controller/AuthController.java +++ b/Authentication/src/main/java/com/pg/auth/controller/AuthController.java @@ -36,10 +36,10 @@ public ResponseEntity code(@RequestParam(name = "code") String code, * Test Access Token 발급 * 만료시간 무제한 */ - // @GetMapping("/test-token") - // public String testToken(@RequestParam Long oauthId) throws InvalidCodeException { - // return oAuthUserService.testAccessToken(oauthId).getAccessToken(); - // } + @GetMapping("/test-token") + public String testToken(@RequestParam Long oauthId) throws InvalidCodeException { + return oAuthUserService.testAccessToken(oauthId); + } /** * 프론트에서 호출하여 code, oauthId를 통해 유저 인증을 하고 JWT 발급 diff --git a/Backend/src/main/java/com/pg/programmerground/auth/config/Oauth2WebSecurityConfig.java b/Backend/src/main/java/com/pg/programmerground/auth/config/Oauth2WebSecurityConfig.java index 04188c2..9c69fd4 100644 --- a/Backend/src/main/java/com/pg/programmerground/auth/config/Oauth2WebSecurityConfig.java +++ b/Backend/src/main/java/com/pg/programmerground/auth/config/Oauth2WebSecurityConfig.java @@ -29,6 +29,7 @@ public class Oauth2WebSecurityConfig extends WebSecurityConfigurerAdapter { new AntPathRequestMatcher("/configuration/**"), new AntPathRequestMatcher("/swagger-resources/**"), new AntPathRequestMatcher("/v2/api-docs"), + new AntPathRequestMatcher("/images/**"), new AntPathRequestMatcher("/webjars/**"), new AntPathRequestMatcher("/webjars/springfox-swagger-ui/*.{js,css}")); //인증안할 것들 넣기 diff --git a/Backend/src/main/java/com/pg/programmerground/controller/ImageController.java b/Backend/src/main/java/com/pg/programmerground/controller/ImageController.java new file mode 100644 index 0000000..c770714 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/controller/ImageController.java @@ -0,0 +1,34 @@ +package com.pg.programmerground.controller; + +import com.pg.programmerground.service.upload.PlaygroundMainImgStore; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.net.MalformedURLException; + +@RestController +@RequestMapping("/images") +@RequiredArgsConstructor +public class ImageController { + private final PlaygroundMainImgStore playgroundMainImgStore; + + @ApiOperation(value = "Playground Main Img File", notes = "Playground Main Img File 요청") + @ResponseBody + @GetMapping(value="/pgmainimg/{fileName}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE}) + public Resource getMainImg(@PathVariable String fileName) throws MalformedURLException { + return new UrlResource("file:" + playgroundMainImgStore.getFullPath(fileName)); + } + + /** + * 추후 상세 설명에 이미지로드 + */ + @ResponseBody + @GetMapping(value="/pgdesimg/{fileName}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE}) + public Resource getDesImg(@PathVariable String fileName) { + return null; + } +} diff --git a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java index 110463d..9455689 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java @@ -11,15 +11,11 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.io.ClassPathResource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.validation.Valid; -import java.io.File; -import java.io.IOException; -import java.util.List; @Slf4j @RestController @@ -37,12 +33,10 @@ public ResponseEntity> playgroundList() return ResponseEntity.ok().body(new ApiResponse<>(new PlaygroundCardListResponse(playgroundService.getPlaygroundCardList()))); } - /** - * playground 생성 - */ + @ApiOperation(value = "Playground 생성", notes = "Playground 생성 요청") @PostMapping("") - public ResponseEntity> createPlayground(@Valid @RequestBody PlaygroundApi info) throws Exception { - return ResponseEntity.ok().body(new ApiResponse<>(playgroundService.createPlayground(info))); + public ResponseEntity> createPlayground(@RequestPart(required = false) MultipartFile mainImg, @Valid @RequestPart PlaygroundApi info) throws Exception { + return ResponseEntity.ok().body(new ApiResponse<>(playgroundService.createPlayground(mainImg, info))); } @ApiOperation(value = "Playground 참가 신청", notes = "Playground 참가 신청 요청") diff --git a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java index 50b6879..f26f210 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java @@ -1,7 +1,7 @@ package com.pg.programmerground.domain; import com.pg.programmerground.domain.common.BaseTimeEntity; -import com.pg.programmerground.domain.enumerated.ApplyStatus; +import com.pg.programmerground.dto.UploadImg; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.exception.FullMemberException; import com.pg.programmerground.exception.IncorrectUserException; @@ -36,6 +36,12 @@ public class Playground extends BaseTimeEntity { @Column(name = "DESCRIPTION") private String description; + @Column(name = "MAIN_IMG_NAME") + private String mainImgName; + + @Column(name = "MAIN_IMG_UPLOAD_NAME") + private String mainImgUploadName; + @OneToMany(mappedBy = "playground", cascade = CascadeType.ALL, orphanRemoval = true) private final List applyPlaygrounds = new ArrayList<>(); @@ -47,10 +53,12 @@ public class Playground extends BaseTimeEntity { private List playgroundPositionList = new ArrayList<>(); @Builder - private Playground(int maxMemberCount, String title, String description) { + private Playground(int maxMemberCount, String title, String description, String mainImgName, String mainImgUploadName) { this.maxMemberCount = maxMemberCount; this.title = title; this.description = description; + this.mainImgName = mainImgName; + this.mainImgUploadName = mainImgUploadName; } /** @@ -58,12 +66,14 @@ private Playground(int maxMemberCount, String title, String description) { * playground 정보 builer로 생성 * playground 객체에 oAuthUser가 등록된 연관 객체(oAuthUserPlayground) 등록 */ - public static Playground createPlayground(PlaygroundApi playgroundApi, OAuthUser leader, List playgroundPositionList) { + public static Playground createPlayground(PlaygroundApi playgroundApi, UploadImg uploadMainImg, OAuthUser leader, List playgroundPositionList) { Playground.checkMaxMemberNumWithPosition(playgroundApi, playgroundPositionList); Playground playground = Playground.builder() .title(playgroundApi.getTitle()) .description(playgroundApi.getDescription()) .maxMemberCount(playgroundApi.getMaxUserNum()) + .mainImgName(uploadMainImg.getOriginalFileName()) + .mainImgUploadName(uploadMainImg.getStoreFileName()) .build(); playgroundPositionList.forEach(playground::addPosition); playground.addLeader(leader); diff --git a/Backend/src/main/java/com/pg/programmerground/dto/UploadImg.java b/Backend/src/main/java/com/pg/programmerground/dto/UploadImg.java new file mode 100644 index 0000000..413dd62 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/dto/UploadImg.java @@ -0,0 +1,13 @@ +package com.pg.programmerground.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class UploadImg { + //업로드한 이미지 원본명 + private final String originalFileName; + //서버에 저장될 이미지명 + private final String storeFileName; +} diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 17ab430..7b58f35 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -4,6 +4,7 @@ import com.pg.programmerground.domain.Playground; import com.pg.programmerground.domain.PlaygroundApply; import com.pg.programmerground.domain.PlaygroundPosition; +import com.pg.programmerground.dto.UploadImg; import com.pg.programmerground.dto.playground.api_req.ApplyPlaygroundApi; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.dto.playground.response.PlaygroundCardResponse; @@ -11,10 +12,11 @@ import com.pg.programmerground.model.OAuthUserRepository; import com.pg.programmerground.model.PlaygroundApplyRepository; import com.pg.programmerground.model.PlaygroundRepository; +import com.pg.programmerground.service.upload.PlaygroundMainImgStore; import lombok.RequiredArgsConstructor; -import org.modelmapper.ModelMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.NoSuchElementException; @@ -26,7 +28,7 @@ public class PlaygroundService { private final PlaygroundRepository playgroundRepository; private final PlaygroundApplyRepository playgroundApplyRepository; private final OAuthUserRepository oAuthUserRepository; - private final ModelMapper modelMapper; + private final PlaygroundMainImgStore playgroundMainImgStore; /** * 메인 페이지 playground card 목록 가져오기 @@ -39,13 +41,15 @@ public List getPlaygroundCardList() { * Playground 생성 */ @Transactional - public Long createPlayground(PlaygroundApi playgroundInfo) throws Exception { + public Long createPlayground(MultipartFile mainImg, PlaygroundApi playgroundInfo) throws Exception { //로그인 유저 가져오기 OAuthUser leaderUser = oAuthUserRepository.findById(UserAuthenticationService.getUserId()).orElseThrow(); + //Playground 메인 이미지 업로드 + UploadImg uploadMainImg = playgroundMainImgStore.storeFile(mainImg); //Playground Position 객체 리스트 만들기 List playgroundPositionList = PlaygroundPosition.createPosition(playgroundInfo); //Playground 생성 - Playground playground = Playground.createPlayground(playgroundInfo, leaderUser, playgroundPositionList); + Playground playground = Playground.createPlayground(playgroundInfo, uploadMainImg, leaderUser, playgroundPositionList); //리더 포지션 검색 PlaygroundPosition leaderPosition = PlaygroundPosition.searchLeaderPosition(playgroundPositionList, playgroundInfo.getLeaderPosition()); //리더도 Position에 포함되야하므로 PlaygroundApply 객체를 만든다. diff --git a/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java b/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java new file mode 100644 index 0000000..d9065b0 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java @@ -0,0 +1,57 @@ +package com.pg.programmerground.service.upload; + +import com.pg.programmerground.dto.UploadImg; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +/** + * File Upload 구현체지만 각 이미지마다 저장 경로가 다르기 떄문에 상속받아 경로를 설정 + */ +public abstract class FileStore { + @Value("${file.dir}") + public String fileDir; + + /** + * 이미지 업로드 안했을 경우 default 이미지 설정 + */ + public abstract UploadImg defaultStoreFile(); + + /** + * 저장할 파일 경로 + */ + public abstract String getFullPath(String fileName); + + /** + * 파일 저장 + */ + public UploadImg storeFile(MultipartFile imgFile) throws IOException { + if(imgFile == null || imgFile.isEmpty()) { + return this.defaultStoreFile(); + } + String fileName = imgFile.getOriginalFilename(); + String storeFileName = this.createStoreFileName(fileName); + imgFile.transferTo(new File(this.getFullPath(storeFileName))); + return new UploadImg(fileName, storeFileName); + } + + /** + * 서버에 저장될 이미지 이름 + */ + public String createStoreFileName(String originalFileName) { + String uuid = UUID.randomUUID().toString(); + String ext = this.extractExt(originalFileName); + return uuid + "." + ext; + } + + /** + * 확장자 추출 + */ + public String extractExt(String originalName) { + int pos = originalName.lastIndexOf("."); + return originalName.substring(pos + 1); + } +} diff --git a/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java b/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java new file mode 100644 index 0000000..ae9d2cc --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java @@ -0,0 +1,24 @@ +package com.pg.programmerground.service.upload; + +import com.pg.programmerground.dto.UploadImg; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class PlaygroundMainImgStore extends FileStore{ + @Value("${file.playground-main-img}") + private String playgroundImgDir; + + @Override + public UploadImg defaultStoreFile() { + return new UploadImg("playground-default.png", "playground-default.png"); + } + + /** + * 이미지 절대 경로 + */ + @Override + public String getFullPath(String fileName) { + return this.fileDir + playgroundImgDir + fileName; + } +} diff --git a/Backend/src/main/resources/application.yml b/Backend/src/main/resources/application.yml index 4957bd1..50d07e5 100644 --- a/Backend/src/main/resources/application.yml +++ b/Backend/src/main/resources/application.yml @@ -33,6 +33,10 @@ spring: jwt-token: secret-key: awdsd + servlet: + multipart: + max-file-size: 1MB + max-request-size: 10MB #logging: # level # org.hibernate.SQL: debug @@ -40,6 +44,12 @@ spring: server: port: 8080 + +#이미지 파일 저장 경로 설정 각자 컴퓨터에 맞게 설정 +file: + dir: /Users/jaewoochoi/Desktop/image + playground-main-img: /pgmainimg/ #image/pgmainimg 만들 것 + playground-description-img: /pgdesimg/ #image/pgdesimg 만들 것 --- --- @@ -55,12 +65,17 @@ spring: jpa: hibernate: #옵션 create, update, none, create-drop, validate 있음 - ddl-auto: create-drop + ddl-auto: update naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl properties: hibernate: format_sql: true + show-sql: true + servlet: + multipart: + max-file-size: 1MB + max-request-size: 10MB security: jwt-token: @@ -68,4 +83,10 @@ spring: server: port: 9000 + +file: + dir: /Users/jaewoochoi/Desktop/image + playground-main-img: /pgmainimg/ + playground-description-img: /pgdesimg/ + --- \ No newline at end of file From 5bb2e86c474ea27acb256a2109b4f7e0dda5ec6b Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sun, 4 Jul 2021 21:29:48 +0900 Subject: [PATCH 013/176] =?UTF-8?q?refactor:=20import=20=EB=88=84=EB=9D=BD?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/PlaygroundService.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 217e9b3..a5c9040 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -1,9 +1,11 @@ package com.pg.programmerground.service; +import com.pg.programmerground.config.GithubBotConfig; import com.pg.programmerground.domain.OAuthUser; import com.pg.programmerground.domain.Playground; import com.pg.programmerground.domain.PlaygroundApply; import com.pg.programmerground.domain.PlaygroundPosition; +import com.pg.programmerground.dto.UploadImg; import com.pg.programmerground.dto.playground.api_req.ApplyPlaygroundApi; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.dto.playground.response.PlaygroundCardResponse; @@ -11,24 +13,17 @@ import com.pg.programmerground.model.OAuthUserRepository; import com.pg.programmerground.model.PlaygroundApplyRepository; import com.pg.programmerground.model.PlaygroundRepository; -import com.pg.programmerground.config.GithubBotConfig; +import com.pg.programmerground.service.upload.PlaygroundMainImgStore; import com.pg.programmerground.util.GithubHttpUtil; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import lombok.RequiredArgsConstructor; import org.modelmapper.ModelMapper; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.NoSuchElementException; import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; @Service @Transactional(readOnly = true) From 1a205128255e6e06fce8cb7ead54cbe3b99e10e9 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Mon, 12 Jul 2021 00:01:25 +0900 Subject: [PATCH 014/176] =?UTF-8?q?feat:=20=ED=8C=8C=EC=9D=BC=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20=ED=99=95=EC=9E=A5?= =?UTF-8?q?=EC=9E=90=20=ED=95=84=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backend/build.gradle | 4 +-- .../pg/programmerground/domain/OAuthUser.java | 2 +- .../exception/ControllerExceptionHandler.java | 12 +++++++-- .../exception/FileExtractException.java | 11 ++++++++ .../service/upload/FileStore.java | 15 +++++++++++ .../upload/PlaygroundMainImgStore.java | 2 +- .../programmerground/TestUserManagement.java | 6 ++--- .../playground/PlayGroundBotTest.java | 27 +++++++------------ .../playground/TestJsonPackage.java | 4 +++ 9 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/exception/FileExtractException.java diff --git a/Backend/build.gradle b/Backend/build.gradle index 335f671..e4147e3 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -49,8 +49,8 @@ dependencies { compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2' compile group: 'io.swagger', name: 'swagger-annotations', version: '1.5.21' compile group: 'io.swagger', name: 'swagger-models', version: '1.5.21' - testCompile "org.powermock:powermock-module-junit4:1.6.6" - testCompile "org.powermock:powermock-api-mockito2:1.6.6" + testCompile "org.powermock:powermock-module-junit4:2.0.0-beta.5" + testCompile "org.powermock:powermock-api-mockito2:2.0.0-beta.5" } dependencyManagement { diff --git a/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java b/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java index 40333ef..bd5a0ef 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java @@ -35,7 +35,7 @@ public class OAuthUser extends BaseTimeEntity { @Column(name = "CODE") private String code; - @OneToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "OAUTH_ID") private Oauth2AuthorizedClient oauth2AuthorizedClient; diff --git a/Backend/src/main/java/com/pg/programmerground/exception/ControllerExceptionHandler.java b/Backend/src/main/java/com/pg/programmerground/exception/ControllerExceptionHandler.java index 7527457..5266f39 100644 --- a/Backend/src/main/java/com/pg/programmerground/exception/ControllerExceptionHandler.java +++ b/Backend/src/main/java/com/pg/programmerground/exception/ControllerExceptionHandler.java @@ -20,7 +20,7 @@ public ResponseEntity> expiredJwtExceptionHandler(NoSuchElem Map map = new HashMap<>(); map.put("msg", e.getMessage()); map.put("code", 10); - return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST); } /** @@ -31,6 +31,14 @@ public ResponseEntity> WrongRequestExceptionHandler(WrongReq Map map = new HashMap<>(); map.put("msg", e.getMessage()); map.put("code", 11); - return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(FileExtractException.class) + public ResponseEntity> FileExtractExceptionHandler(FileExtractException e) { + Map map = new HashMap<>(); + map.put("msg", e.getMessage()); + map.put("code", 12); + return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST); } } \ No newline at end of file diff --git a/Backend/src/main/java/com/pg/programmerground/exception/FileExtractException.java b/Backend/src/main/java/com/pg/programmerground/exception/FileExtractException.java new file mode 100644 index 0000000..9eaee4a --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/exception/FileExtractException.java @@ -0,0 +1,11 @@ +package com.pg.programmerground.exception; + +public class FileExtractException extends RuntimeException{ + public FileExtractException() { + super(); + } + + public FileExtractException(String message) { + super(message); + } +} diff --git a/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java b/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java index d9065b0..3151dd6 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java +++ b/Backend/src/main/java/com/pg/programmerground/service/upload/FileStore.java @@ -1,17 +1,21 @@ package com.pg.programmerground.service.upload; import com.pg.programmerground.dto.UploadImg; +import com.pg.programmerground.exception.FileExtractException; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.UUID; /** * File Upload 구현체지만 각 이미지마다 저장 경로가 다르기 떄문에 상속받아 경로를 설정 */ public abstract class FileStore { + private static final String[] IMG_CONTENT_TYPE_LIST = {"image/png", "image/jpeg"}; + @Value("${file.dir}") public String fileDir; @@ -32,6 +36,7 @@ public UploadImg storeFile(MultipartFile imgFile) throws IOException { if(imgFile == null || imgFile.isEmpty()) { return this.defaultStoreFile(); } + this.checkExtract(imgFile.getContentType()); String fileName = imgFile.getOriginalFilename(); String storeFileName = this.createStoreFileName(fileName); imgFile.transferTo(new File(this.getFullPath(storeFileName))); @@ -44,6 +49,7 @@ public UploadImg storeFile(MultipartFile imgFile) throws IOException { public String createStoreFileName(String originalFileName) { String uuid = UUID.randomUUID().toString(); String ext = this.extractExt(originalFileName); + return uuid + "." + ext; } @@ -54,4 +60,13 @@ public String extractExt(String originalName) { int pos = originalName.lastIndexOf("."); return originalName.substring(pos + 1); } + + /** + * 확장자 체크 + */ + private void checkExtract(String contentType) { + if(!Arrays.asList(IMG_CONTENT_TYPE_LIST).contains(contentType)) { + throw new FileExtractException("파일 확장자는 jpeg, png만 업로드 가능"); + } + } } diff --git a/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java b/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java index ae9d2cc..a2545d3 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java +++ b/Backend/src/main/java/com/pg/programmerground/service/upload/PlaygroundMainImgStore.java @@ -15,7 +15,7 @@ public UploadImg defaultStoreFile() { } /** - * 이미지 절대 경로 + * 이미지 */ @Override public String getFullPath(String fileName) { diff --git a/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java b/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java index f0f1513..d9cf66d 100644 --- a/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java +++ b/Backend/src/test/java/com/pg/programmerground/TestUserManagement.java @@ -48,8 +48,6 @@ public void saveTestUser() { .userGithubInfo(userGithubInfo) .build(); - userGithubInfoRepository.save(userGithubInfo); - oauth2AuthorizedClientRepository.save(oauth2AuthorizedClient); oAuthUserRepository.save(oAuthUser); Oauth2AuthorizedClient oauth2AuthorizedClient2 = Oauth2AuthorizedClient.builder() @@ -71,9 +69,8 @@ public void saveTestUser() { .userGithubInfo(userGithubInfo2) .build(); - userGithubInfoRepository.save(userGithubInfo2); - oauth2AuthorizedClientRepository.save(oauth2AuthorizedClient2); oAuthUserRepository.save(oAuthUser2); + } @Transactional @@ -106,6 +103,7 @@ public void saveGithubRepoBotUser() { @Transactional public void deleteTestUser() { oAuthUserRepository.delete(oauth2AuthorizedClientRepository.findById(1234L).orElseThrow().getUser()); + oAuthUserRepository.delete(oauth2AuthorizedClientRepository.findById(12345L).orElseThrow().getUser()); } } diff --git a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java index ff4e26c..3471309 100644 --- a/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java +++ b/Backend/src/test/java/com/pg/programmerground/playground/PlayGroundBotTest.java @@ -1,8 +1,5 @@ package com.pg.programmerground.playground; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import com.pg.programmerground.TestUserManagement; import com.pg.programmerground.auth.jwt.JwtAuthenticationToken; import com.pg.programmerground.config.GithubBotConfig; @@ -12,27 +9,23 @@ import com.pg.programmerground.service.GithubRestService; import com.pg.programmerground.service.OAuthUserService; import com.pg.programmerground.service.PlaygroundService; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + @SpringBootTest @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class PlayGroundBotTest { @@ -92,7 +85,7 @@ public void get_github_org_by_bot_user() { public void playground_leader_request_create_github_repo() throws Exception { //given PlaygroundApi playgroundApi = dtoList.createPlayground; - Long playgroundId = playgroundService.createPlayground(playgroundApi); + Long playgroundId = playgroundService.createPlayground(null, playgroundApi); Playground playground = playgroundRepository.findById(playgroundId).orElseThrow(); //when diff --git a/Backend/src/test/java/com/pg/programmerground/playground/TestJsonPackage.java b/Backend/src/test/java/com/pg/programmerground/playground/TestJsonPackage.java index 06add9b..71552ef 100644 --- a/Backend/src/test/java/com/pg/programmerground/playground/TestJsonPackage.java +++ b/Backend/src/test/java/com/pg/programmerground/playground/TestJsonPackage.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; +import com.pg.programmerground.dto.playground.api_req.PlaygroundBotApi; import org.springframework.core.io.ClassPathResource; import java.io.IOException; @@ -27,6 +28,9 @@ public class TestJsonPackage { PlaygroundApi leaderPosition; @JsonProperty("apply_position") PlaygroundApi applyPosition; + @JsonProperty("create_org_repo") + PlaygroundBotApi createOrgRepo; + /** * Json To DTO */ From 817a5d0eb3a8f0d783b5dd67a273e1a281c3504a Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 1 Jul 2021 18:24:29 +0900 Subject: [PATCH 015/176] =?UTF-8?q?style=20-=20playground=20=EC=9A=94?= =?UTF-8?q?=EC=86=8C=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EB=AA=A8=EB=8B=AC?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/modal/onePlaygroundModal/index.tsx | 14 ++++++ .../Common/modal/onePlaygroundModal/style.ts | 29 ++++++++++++ .../components/playgroundContent/index.tsx | 14 +++++- Frontend/src/data/playground.ts | 46 ------------------- Frontend/src/pages/PlayGroundPage/index.tsx | 1 + 5 files changed, 56 insertions(+), 48 deletions(-) create mode 100644 Frontend/src/components/Common/modal/onePlaygroundModal/index.tsx create mode 100644 Frontend/src/components/Common/modal/onePlaygroundModal/style.ts delete mode 100644 Frontend/src/data/playground.ts diff --git a/Frontend/src/components/Common/modal/onePlaygroundModal/index.tsx b/Frontend/src/components/Common/modal/onePlaygroundModal/index.tsx new file mode 100644 index 0000000..f2b3dda --- /dev/null +++ b/Frontend/src/components/Common/modal/onePlaygroundModal/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import * as StyledComponent from './style'; + +const OnePlaygroundModal = () => { + return ( + <> + + ddd + + + ); +}; + +export default OnePlaygroundModal; diff --git a/Frontend/src/components/Common/modal/onePlaygroundModal/style.ts b/Frontend/src/components/Common/modal/onePlaygroundModal/style.ts new file mode 100644 index 0000000..75a98b2 --- /dev/null +++ b/Frontend/src/components/Common/modal/onePlaygroundModal/style.ts @@ -0,0 +1,29 @@ +/* eslint-disable import/prefer-default-export */ +import styled from 'styled-components'; + +export const ModalContainer = styled.div` + position: fixed; + width: 100%; + height: 100%; + left: 0; + top: 0; + z-index: 100; + background-color: rgba(0, 0, 0, 0.4); +`; + +export const ModalContent = styled.div` + background-color: #fefefe; + border: 1px solid #888; + border-radius: 10px; +`; + +export const ModalClose = styled.div` + font-size: 28px; + line-height: 36px; + height: 10px; + color: #aaa; + font-weight: bold; + cursor: pointer; + border-radius: 10px; + margin: 20px 10px 0 0; +`; diff --git a/Frontend/src/components/playgroundContent/index.tsx b/Frontend/src/components/playgroundContent/index.tsx index f6b18c7..3c49a3c 100644 --- a/Frontend/src/components/playgroundContent/index.tsx +++ b/Frontend/src/components/playgroundContent/index.tsx @@ -2,10 +2,12 @@ /* eslint-disable react/jsx-key */ /* eslint-disable react/require-default-props */ /* eslint-disable react/prop-types */ -import React from 'react'; +import React, { useState } from 'react'; +import OnePlaygroundModal from '@src/components/Common/modal/onePlaygroundModal'; import * as StyledComponent from './style'; interface Playground { + id: number; title: string; date: string; src?: string; @@ -15,6 +17,7 @@ interface Playground { } const PlaygroundContent = ({ + id, title, date, src, @@ -22,9 +25,15 @@ const PlaygroundContent = ({ personnel, language, }: Playground) => { + const [openState, setOpenState] = useState(false); + const createModalFunc = (playgroundId: number, event: any) => { + setOpenState(true); + }; return ( <> - + createModalFunc(id, e)} + > {title} @@ -48,6 +57,7 @@ const PlaygroundContent = ({ })} + {openState ? : ''} ); }; diff --git a/Frontend/src/data/playground.ts b/Frontend/src/data/playground.ts deleted file mode 100644 index cdc1591..0000000 --- a/Frontend/src/data/playground.ts +++ /dev/null @@ -1,46 +0,0 @@ -import typescript from '@src/assets/typescript.png'; -import svg from '@src/assets/svg.png'; -import spring from '@src/assets/spring.png'; -import react from '@src/assets/react-logo.png'; - -const playgroundData = { - content: [ - { - id: '1', - title: 'TypeScript Making', - date: '2021.01.09', - src: typescript, - position: '주니어', - personnel: '1/4', - language: ['React', 'TypeScript', 'Redux'], - }, - { - id: '2', - title: 'SVG Making', - date: '2021.01.17', - src: svg, - position: '시니어', - personnel: '1/4', - language: ['SVG'], - }, - { - id: '3', - title: 'Spring Core', - date: '2021.01.27', - src: spring, - position: '주니어', - personnel: '1/4', - language: ['Spring', 'Mysql'], - }, - { - id: '4', - title: 'React', - date: '2021.02.28', - src: react, - position: '주니어', - personnel: '2/3', - language: ['React'], - }, - ], -}; -export default playgroundData; diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index dca4bfc..d3ec484 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -50,6 +50,7 @@ const PlayGroundPage = () => { title={v.title} position={v.position_list[0].position_name} language={v.position_list[0].language} + id={v.playground_id} /> ); })} From dec01acaed5539f096178d3dcc2bacb48a05d57a Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 1 Jul 2021 18:35:50 +0900 Subject: [PATCH 016/176] =?UTF-8?q?feat=20-=20playgroundId=20api=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/playgroundContent/index.tsx | 5 ++++- Frontend/src/lib/axios/playground.ts | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Frontend/src/components/playgroundContent/index.tsx b/Frontend/src/components/playgroundContent/index.tsx index 3c49a3c..913c32e 100644 --- a/Frontend/src/components/playgroundContent/index.tsx +++ b/Frontend/src/components/playgroundContent/index.tsx @@ -4,6 +4,7 @@ /* eslint-disable react/prop-types */ import React, { useState } from 'react'; import OnePlaygroundModal from '@src/components/Common/modal/onePlaygroundModal'; +import { getOnePlayground } from '@src/lib/axios/playground'; import * as StyledComponent from './style'; interface Playground { @@ -26,8 +27,10 @@ const PlaygroundContent = ({ language, }: Playground) => { const [openState, setOpenState] = useState(false); - const createModalFunc = (playgroundId: number, event: any) => { + const createModalFunc = async (playgroundId: number, event: any) => { setOpenState(true); + const onePlayground = await getOnePlayground(playgroundId); + console.log(onePlayground); }; return ( <> diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 2686130..7aa9d8c 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -5,6 +5,7 @@ import { getData, patchData, postData, putData, deleteData } from './request'; const url = { GET_ALL_PLAYGROUND: 'http://localhost:9000/playground', CREATE_PLAYGROUND: 'http://localhost:9000/playground', + GET_ONE_PLAYGROUND: 'http://localhost:9000/playground/', }; // eslint-disable-next-line import/prefer-default-export @@ -17,3 +18,8 @@ export const createPlayground = async (playgroundData: any) => { const playground = await postData(url.CREATE_PLAYGROUND, playgroundData); return playground; }; + +export const getOnePlayground = async (playgroundId: number) => { + const playground = await getData(`${url.GET_ONE_PLAYGROUND}${playgroundId}`); + return playground; +}; From f17d913e5c639abf30b56794d741d274bcae8d98 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 1 Jul 2021 18:41:05 +0900 Subject: [PATCH 017/176] =?UTF-8?q?style=20-=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=B0=A9=20=EC=83=9D=EC=84=B1=20=EB=B2=84=ED=8A=BC=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/pages/PlayGroundPage/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index d3ec484..cc2be08 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -10,7 +10,6 @@ import Header from '@src/components/header'; import SearchBar from '@src/components/searchBar'; import Bone from '@src/components/Common/bone'; import PlaygroundContent from '@src/components/playgroundContent'; -import Button from '@src/components/Common/button'; import { getAllPlaygrounds } from '@src/lib/axios/playground'; import useShow from '@src/hooks/useShow'; import * as StyledComponent from './style'; @@ -39,7 +38,6 @@ const PlayGroundPage = () => { - + + )} diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index bcb2d19..3e32fef 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -94,6 +94,22 @@ export const UserMenu = styled.div` color: #000; text-decoration: none; } + + & > button { + &:not(:first-child) { + border-top: 1px solid rgba(0, 0, 0, 0.1); + } + padding: 16px 10px; + font-size: 18px; + font-family: Roboto, sans-serif; + min-width: 120px; + min-height: 28px; + cursor: pointer; + color: #000; + background-color: #fff; + text-decoration: none; + border: 0; + } `; export const UserProfileLink = styled.a``; From f84ab8abdda440a55264e7be1342da8435a781a3 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 28 Aug 2021 00:05:17 +0900 Subject: [PATCH 078/176] =?UTF-8?q?#125=20=EB=82=B4=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EB=AA=A8=EB=8B=AC=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EB=B0=8F=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 24 ++++++++++++-- Frontend/src/components/header/style.ts | 40 +++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index e1645dc..b490d60 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -10,7 +10,7 @@ import { getOneUser } from '@src/lib/axios/playground'; const Header = () => { const [isAlarm, setAlarm] = useState(false); const [isUser, setUser] = useState(false); - + const [info, setInfo] = useState(false); const history = useHistory(); const userClickHandler = (e: any) => { @@ -22,6 +22,14 @@ const Header = () => { if (isUser) setUser(!isUser); }; + const onClickInfoHandler = (e: any) => { + setInfo(!info); + }; + + const onClickCloseHandler = (e: any) => { + setInfo(!info); + }; + const onLogout = (e) => { document.cookie = `access_token=; Max-Age=0`; document.cookie = `refresh_token=; Max-Age=0`; @@ -75,7 +83,7 @@ const Header = () => { 레포 생성 - @@ -83,6 +91,18 @@ const Header = () => { )} + {info && ( + + + + My Alarm Info + + + 닫기 + + + + )} ); }; diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index 3e32fef..3e49d84 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -1,5 +1,5 @@ /* eslint-disable import/prefer-default-export */ -import styled, { createGlobalStyle } from 'styled-components'; +import styled, { createGlobalStyle, keyframes } from 'styled-components'; import { lightTheme, darkTheme } from '@src/utils/theme'; import logo from '../../assets/programmerground.png'; import projectIcon from '../../assets/projectIcon.png'; @@ -112,4 +112,42 @@ export const UserMenu = styled.div` } `; +const infoKeyframes = keyframes` + 0% { + transform: translateX(390px); + } + + 100% { + transform: translateX(0); + } +`; + +export const InfoMenu = styled.div` + z-index: 1000; + background-color: #f6f8fa; + border: 1px solid #e9e9e9; + position: absolute; + right: 0; + width: 360px; + top: 80px; + animation: ${infoKeyframes} 1s forwards; +`; + +export const InfoTitleContainer = styled.div` + display: flex; + padding: 8px 16px; +`; + +export const InfoTitleCloseButton = styled.button` + padding: 5px; + background-color: #fff; + border: 1px solid #e9e9e9; +`; + +export const InfoTitleName = styled.span` + flex: 1 1 auto; + &:not(:last-child) { + margin-top: 4px; + } +`; export const UserProfileLink = styled.a``; From 46706e2e1c6a4236e3ef3706ad4f21fcc567f919 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sat, 28 Aug 2021 20:49:26 +0900 Subject: [PATCH 079/176] =?UTF-8?q?feat:=20playground=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PlaygroundController.java | 6 +- .../programmerground/domain/Playground.java | 79 +++++++++++-------- .../domain/PlaygroundPosition.java | 5 +- .../domain/enumerated/PlaygroundStatus.java | 5 ++ .../model/PlaygroundRepository.java | 5 +- .../service/PlaygroundService.java | 20 ++++- .../playground/PlaygroundServiceTest.java | 19 +++++ 7 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/domain/enumerated/PlaygroundStatus.java diff --git a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java index 47223c8..b559520 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java @@ -44,7 +44,7 @@ public ResponseEntity> createPlayground(@RequestPart(required @ApiOperation(value = "Playground 참가 신청", notes = "Playground 참가 신청 요청") @PostMapping("/{playgroundId}/apply") - public ResponseEntity> applyPlayground(@PathVariable Long playgroundId, @RequestBody @Validated ApplyPlaygroundApi applyPlayground) throws Exception { + public ResponseEntity> applyPlayground(@PathVariable Long playgroundId, @RequestBody @Validated ApplyPlaygroundApi applyPlayground) { return ResponseEntity.ok().body(new ApiResponse<>(playgroundService.applyPlayground(playgroundId, applyPlayground))); } @@ -80,8 +80,8 @@ public ResponseEntity> revisePlayground(@Validated RevisePl @ApiOperation(value = "Playground 삭제", notes = "Playground 삭제 요청") @DeleteMapping("/{playgroundId}") - public ResponseEntity> deletePlayground(@PathVariable Long playgroundId) { - return ResponseEntity.ok().body(new ApiResponse<>(null)); + public ResponseEntity> deletePlayground(@PathVariable Long playgroundId) { + return ResponseEntity.ok().body(new ApiResponse<>(playgroundService.removePlayground(playgroundId))); } /** diff --git a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java index f26f210..f1f748b 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java @@ -1,12 +1,14 @@ package com.pg.programmerground.domain; import com.pg.programmerground.domain.common.BaseTimeEntity; +import com.pg.programmerground.domain.enumerated.PlaygroundStatus; import com.pg.programmerground.dto.UploadImg; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.exception.FullMemberException; import com.pg.programmerground.exception.IncorrectUserException; import com.pg.programmerground.exception.WrongRequestException; import lombok.*; +import org.hibernate.annotations.Where; import javax.persistence.*; import java.util.ArrayList; @@ -17,6 +19,7 @@ @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Where(clause = "STATUS_FLAG='ACTIVE'") public class Playground extends BaseTimeEntity { @Id @@ -52,6 +55,10 @@ public class Playground extends BaseTimeEntity { @OneToMany(mappedBy = "playground", cascade = CascadeType.ALL, orphanRemoval = true) private List playgroundPositionList = new ArrayList<>(); + @Enumerated(value = EnumType.STRING) + @Column(name = "STATUS_FLAG") + private PlaygroundStatus statusFlag = PlaygroundStatus.ACTIVE; + @Builder private Playground(int maxMemberCount, String title, String description, String mainImgName, String mainImgUploadName) { this.maxMemberCount = maxMemberCount; @@ -80,31 +87,6 @@ public static Playground createPlayground(PlaygroundApi playgroundApi, UploadImg return playground; } - /** - * playground의 전체 인원수와 각 position의 인원수의 합이 같은지 체크 - */ - private static void checkMaxMemberNumWithPosition(PlaygroundApi playgroundApi, List playgroundPositionList) { - if(playgroundPositionList.stream().mapToInt(PlaygroundPosition::getMaxPositionNum).sum() != playgroundApi.getMaxUserNum()) { - throw new WrongRequestException("playground 인원과 position 합산 인원이 다름"); - } - } - - /** - * Playground의 Position 등록 - */ - private void addPosition(PlaygroundPosition position) { - this.playgroundPositionList.add(position); - position.setPlayground(this); - } - - /** - * Playground의 Leader 설정 - */ - private void addLeader(OAuthUser leader) { - this.leader = leader; - leader.getLeaderPlaygrounds().add(this); - } - /** * Position ID로 탐색 */ @@ -123,13 +105,6 @@ public boolean checkAlreadyMember(OAuthUser user) { return applyPlaygrounds.stream().anyMatch(playgroundApply -> playgroundApply.isAlreadyMember(user)); } - /** - * Playground 멤버 가득찼는지 확인 - */ - private boolean isFullMember() { - return maxMemberCount <= currentMemberCount; - } - /** * Playground Member수 증가 */ @@ -148,4 +123,44 @@ public void isLeaderUser(OAuthUser user) { throw new IncorrectUserException("해당 playground 리더가 아님"); } } + + /** + * playground 삭제처리 + * 실제 삭제가 아닌 flag remove 설정 + */ + public void removePlayground() { + this.statusFlag = PlaygroundStatus.REMOVE; + } + + /** + * playground의 전체 인원수와 각 position의 인원수의 합이 같은지 체크 + */ + private static void checkMaxMemberNumWithPosition(PlaygroundApi playgroundApi, List playgroundPositionList) { + if(playgroundPositionList.stream().mapToInt(PlaygroundPosition::getMaxPositionNum).sum() != playgroundApi.getMaxUserNum()) { + throw new WrongRequestException("playground 인원과 position 합산 인원이 다름"); + } + } + + /** + * Playground의 Position 등록 + */ + private void addPosition(PlaygroundPosition position) { + this.playgroundPositionList.add(position); + position.setPlayground(this); + } + + /** + * Playground의 Leader 설정 + */ + private void addLeader(OAuthUser leader) { + this.leader = leader; + leader.getLeaderPlaygrounds().add(this); + } + + /** + * Playground 멤버 가득찼는지 확인 + */ + private boolean isFullMember() { + return maxMemberCount <= currentMemberCount; + } } diff --git a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java index e1d0b71..05a279b 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java @@ -100,9 +100,8 @@ private static boolean isCorrectMemberNum(int playgroundMaxNum, List playgroundPositions, String positionName) { //입력받은 Position중에 Leader가 신청한 Position탐색 return playgroundPositions.stream() - .filter(playgroundPosition -> { - return playgroundPosition.getPosition().name().equals(positionName); - }).findFirst() + .filter(playgroundPosition -> playgroundPosition.getPosition().name().equals(positionName)) + .findFirst() .orElseThrow(() -> new NoSuchElementException("입력되지 않은 포지션입니다")); } diff --git a/Backend/src/main/java/com/pg/programmerground/domain/enumerated/PlaygroundStatus.java b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/PlaygroundStatus.java new file mode 100644 index 0000000..631960e --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/PlaygroundStatus.java @@ -0,0 +1,5 @@ +package com.pg.programmerground.domain.enumerated; + +public enum PlaygroundStatus { + ACTIVE, REMOVE +} diff --git a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java index 09b14f3..b3e584d 100644 --- a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java +++ b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java @@ -1,8 +1,11 @@ package com.pg.programmerground.model; +import com.pg.programmerground.domain.OAuthUser; import com.pg.programmerground.domain.Playground; import org.springframework.data.jpa.repository.JpaRepository; -public interface PlaygroundRepository extends JpaRepository { +import java.util.Optional; +public interface PlaygroundRepository extends JpaRepository { + Optional findPlaygroundByIdAndLeader(Long id, OAuthUser leader); } diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 4f89b5e..4807a18 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -85,6 +85,9 @@ public Long applyPlayground(Long playgroundId, ApplyPlaygroundApi applyPlaygroun return playgroundApply.getId(); } + /** + * Playground 신청 취소 + */ @Transactional public boolean cancelPlayground(Long playgroundApplyId) { //유저 정보 @@ -106,6 +109,9 @@ public Boolean acceptPlayground(Long playgroundApplyId) { return true; } + /** + * Leader가 Playground 신청 거절 + */ @Transactional public Boolean rejectPlayground(Long playgroundApplyId) { PlaygroundApply playgroundApply = playgroundApplyRepository.findById(playgroundApplyId).orElseThrow(() -> new NoSuchElementException("존재하지 않는 Playground 요청입니다")); @@ -114,6 +120,18 @@ public Boolean rejectPlayground(Long playgroundApplyId) { return true; } + /** + * Playground 삭제 처리 + */ + @Transactional + public Boolean removePlayground(Long playgroundId) { + //유저 정보 + OAuthUser leader = oAuthUserRepository.findById(UserAuthenticationService.getUserId()).orElseThrow(() -> new NoSuchElementException("존재하지않는 유저")); + Playground playground = playgroundRepository.findPlaygroundByIdAndLeader(playgroundId, leader).orElseThrow(() -> new NoSuchElementException("해당 작업에대한 권한 없음")); + playground.removePlayground(); + return true; + } + public PlaygroundResponse getPlaygroundDetailInfo(Long playgroundId) { return PlaygroundResponse.of( playgroundRepository.findById(playgroundId).orElseThrow(() -> new NoSuchElementException("playground 존재 안함"))); @@ -153,7 +171,7 @@ public ResponseEntity applyCollaboratorPlaygroundGithubRepo(Long playgroundId } } - HttpEntity entity = new HttpEntity<>(GithubHttpUtil.generateGithubApiHeader(botConfig.getToken())); + HttpEntity entity = new HttpEntity<>(GithubHttpUtil.generateGithubApiHeader(botConfig.getToken())); for(PlaygroundApply user : temp) { String collaboratorUrl = GithubHttpUtil diff --git a/Backend/src/test/java/com/pg/programmerground/playground/PlaygroundServiceTest.java b/Backend/src/test/java/com/pg/programmerground/playground/PlaygroundServiceTest.java index 3bf156e..6e1e6d4 100644 --- a/Backend/src/test/java/com/pg/programmerground/playground/PlaygroundServiceTest.java +++ b/Backend/src/test/java/com/pg/programmerground/playground/PlaygroundServiceTest.java @@ -5,6 +5,7 @@ import com.pg.programmerground.domain.Playground; import com.pg.programmerground.domain.PlaygroundApply; import com.pg.programmerground.domain.enumerated.ApplyStatus; +import com.pg.programmerground.domain.enumerated.PlaygroundStatus; import com.pg.programmerground.dto.playground.api_req.ApplyPlaygroundApi; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.exception.FileExtractException; @@ -22,6 +23,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.test.context.ActiveProfiles; import javax.transaction.Transactional; import java.io.File; @@ -35,6 +37,7 @@ @SpringBootTest @TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ActiveProfiles("jeawoo-local") //테스트시 profile을 자기껄로 설정 public class PlaygroundServiceTest { private static final Long GITHUB_ID = 1234L; private static final Long GITHUB_ID2 = 12345L; @@ -194,6 +197,22 @@ void deleteTestUser() { }); } + @Test + @Transactional + void Playground_삭제() throws Exception { + //playground 생성 + PlaygroundApi playgroundApi = dtoList.applyPosition; + Long playgroundId = playgroundService.createPlayground(null, playgroundApi); + + //when + //playground 삭제 + playgroundService.removePlayground(playgroundId); + Playground playground = playgroundRepository.findById(playgroundId).orElseThrow(); + + //then + assertEquals(PlaygroundStatus.REMOVE, playground.getStatusFlag()); + } + @Test @Transactional void Playground_Member_같은_유저_신청_예외() throws Exception { From dfe73217fa5a287af9b014913687099ffb6e022b Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sat, 28 Aug 2021 22:29:50 +0900 Subject: [PATCH 080/176] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95(=EC=9D=BC=EB=8B=A8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EB=A7=8C=20=EC=88=98=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OAuthUserController.java | 12 +-- .../pg/programmerground/domain/OAuthUser.java | 8 ++ .../dto/user/api_req/ReviseUserApi.java | 11 +++ .../service/OAuthUserService.java | 17 +++++ .../user/userServiceTest.java | 75 +++++++++++++++++++ 5 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java create mode 100644 Backend/src/test/java/com/pg/programmerground/user/userServiceTest.java diff --git a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java index 84858db..7948135 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java @@ -1,6 +1,7 @@ package com.pg.programmerground.controller; import com.pg.programmerground.controller.response.ApiResponse; +import com.pg.programmerground.dto.user.api_req.ReviseUserApi; import com.pg.programmerground.dto.user.response.UserApplyNoticeListResponse; import com.pg.programmerground.dto.user.response.UserLeaderNoticeListResponse; import com.pg.programmerground.dto.user.response.UserResponse; @@ -10,9 +11,7 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @@ -51,8 +50,11 @@ public ResponseEntity> getUserNotice() return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserNoticeList(UserAuthenticationService.getUserId()))); } - //취소 기능도 넣어야겠네 - //취소일 경우 status cancel?? + @PutMapping("") + public ResponseEntity> updateUserInfo(@ModelAttribute ReviseUserApi userApi) { + return ResponseEntity.ok().body(new ApiResponse<>(oAuthUserService.updateUserInfo(UserAuthenticationService.getUserId(), userApi))); + } + @ApiOperation(value = "유저 신청 Playground 대기 리스트", notes = "유저가 신청한 Playground 리스트 중 대기중인 Playground") @GetMapping("/notices/waitings") public ResponseEntity> getUserWaitingNotice() { diff --git a/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java b/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java index bd5a0ef..6e6537f 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/OAuthUser.java @@ -3,6 +3,7 @@ import com.pg.programmerground.domain.common.BaseTimeEntity; import com.pg.programmerground.domain.github.Oauth2AuthorizedClient; import com.pg.programmerground.domain.github.UserGithubInfo; +import com.pg.programmerground.dto.user.api_req.ReviseUserApi; import lombok.*; import org.springframework.util.Assert; @@ -67,4 +68,11 @@ public OAuthUser(String userName, String OAuthName, String Role, String code, Oa this.code = code; this.oauth2AuthorizedClient = oauth2AuthorizedClient; } + + /** + * 유저 정보 수정 + */ + public void updateUser(ReviseUserApi userApi) { + this.userName = userApi.getUserName(); + } } diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java new file mode 100644 index 0000000..ebf34f1 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java @@ -0,0 +1,11 @@ +package com.pg.programmerground.dto.user.api_req; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class ReviseUserApi { + private String userName; + +} diff --git a/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java b/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java index b6fd384..d65253b 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java @@ -3,17 +3,21 @@ import com.pg.programmerground.auth.MyUserDetails; import com.pg.programmerground.domain.OAuthUser; import com.pg.programmerground.domain.github.Oauth2AuthorizedClient; +import com.pg.programmerground.dto.user.api_req.ReviseUserApi; import com.pg.programmerground.dto.user.response.UserResponse; import com.pg.programmerground.model.OAuthUserRepository; import com.pg.programmerground.model.Oauth2AuthorizedClientRepository; import lombok.RequiredArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityNotFoundException; +import java.util.NoSuchElementException; @Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class OAuthUserService { private final OAuthUserRepository oAuthUserRepository; private final Oauth2AuthorizedClientRepository oauth2AuthorizedClientRepository; @@ -30,8 +34,21 @@ public UserDetails loadUserByOAuthId(Long OAuthId) { return new MyUserDetails(oAuthUser); } + /** + * 유저 정보 + */ public UserResponse getUserInfo(Long userId) { return UserResponse.of(oAuthUserRepository.findById(userId).orElseThrow()); } + + /** + * 유저 정보 수정 + */ + @Transactional + public Boolean updateUserInfo(Long oauthUserId, ReviseUserApi userApi) { + OAuthUser user = oAuthUserRepository.findById(oauthUserId).orElseThrow((() -> new NoSuchElementException("잘못된 유저 요청"))); + user.updateUser(userApi); + return true; + } } diff --git a/Backend/src/test/java/com/pg/programmerground/user/userServiceTest.java b/Backend/src/test/java/com/pg/programmerground/user/userServiceTest.java new file mode 100644 index 0000000..8cbeffe --- /dev/null +++ b/Backend/src/test/java/com/pg/programmerground/user/userServiceTest.java @@ -0,0 +1,75 @@ +package com.pg.programmerground.user; + +import com.pg.programmerground.TestUserManagement; +import com.pg.programmerground.auth.jwt.JwtAuthenticationToken; +import com.pg.programmerground.domain.OAuthUser; +import com.pg.programmerground.dto.user.api_req.ReviseUserApi; +import com.pg.programmerground.model.OAuthUserRepository; +import com.pg.programmerground.playground.TestJsonPackage; +import com.pg.programmerground.service.OAuthUserService; +import com.pg.programmerground.service.UserAuthenticationService; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ActiveProfiles("jeawoo-local") //테스트시 profile을 자기껄로 설정 +public class userServiceTest { + private static final Long GITHUB_ID = 1234L; + private TestJsonPackage dtoList; + @Autowired + private OAuthUserService oAuthUserService; + @Autowired + TestUserManagement management; + @Autowired + OAuthUserRepository oAuthUserRepository; + + /** + * *@BeforeAll 한번 실행되고 각 테스트 케이스마다 @BeforeEach 실행 + */ + @BeforeAll + void dataSetUp() throws IOException { + dtoList = TestJsonPackage.of(); + management.saveTestUser(); + } + + @BeforeEach + void authenticationSetUp() { + //Github 로그인을 한번 시도하고 + UserDetails userDetails = oAuthUserService.loadUserByOAuthId(GITHUB_ID); + Authentication authentication = new JwtAuthenticationToken(userDetails, "토큰 값 필요없음", userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + @AfterAll + void deleteTestUser() { + management.deleteTestUser(); + } + + @Test + @Transactional + void User_정보_수정() { + //given + String reviseUserName = "Test"; + OAuthUser user = oAuthUserRepository.findById(UserAuthenticationService.getUserId()).orElseThrow(); + ReviseUserApi reviseUserApi = new ReviseUserApi(); + reviseUserApi.setUserName(reviseUserName); + + //then + user.updateUser(reviseUserApi); + + //then + OAuthUser thenUser = oAuthUserRepository.findById(user.getId()).orElseThrow(); + assertEquals(reviseUserName, thenUser.getUserName()); + } +} From c1b36d42aef6b16c05775bcd06e859be09185469 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sat, 28 Aug 2021 22:41:24 +0900 Subject: [PATCH 081/176] =?UTF-8?q?feat:=20constant=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pg/programmerground/constant/PgConstant.java | 6 ++++++ .../pg/programmerground/controller/OAuthUserController.java | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/constant/PgConstant.java diff --git a/Backend/src/main/java/com/pg/programmerground/constant/PgConstant.java b/Backend/src/main/java/com/pg/programmerground/constant/PgConstant.java new file mode 100644 index 0000000..4891aa6 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/constant/PgConstant.java @@ -0,0 +1,6 @@ +package com.pg.programmerground.constant; + +public final class PgConstant { + public final static String NOTICE_WAIT = "wait"; + public final static String NOTICE_RESULT = "result"; +} diff --git a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java index 7948135..f863853 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java @@ -1,5 +1,6 @@ package com.pg.programmerground.controller; +import com.pg.programmerground.constant.PgConstant; import com.pg.programmerground.controller.response.ApiResponse; import com.pg.programmerground.dto.user.api_req.ReviseUserApi; import com.pg.programmerground.dto.user.response.UserApplyNoticeListResponse; @@ -50,6 +51,7 @@ public ResponseEntity> getUserNotice() return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserNoticeList(UserAuthenticationService.getUserId()))); } + @ApiOperation(value = "유저 정보 수정", notes = "유저 정보를 수정") @PutMapping("") public ResponseEntity> updateUserInfo(@ModelAttribute ReviseUserApi userApi) { return ResponseEntity.ok().body(new ApiResponse<>(oAuthUserService.updateUserInfo(UserAuthenticationService.getUserId(), userApi))); @@ -58,12 +60,12 @@ public ResponseEntity> updateUserInfo(@ModelAttribute Revis @ApiOperation(value = "유저 신청 Playground 대기 리스트", notes = "유저가 신청한 Playground 리스트 중 대기중인 Playground") @GetMapping("/notices/waitings") public ResponseEntity> getUserWaitingNotice() { - return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserStatusNoticeList(UserAuthenticationService.getUserId(), "wait"))); + return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserStatusNoticeList(UserAuthenticationService.getUserId(), PgConstant.NOTICE_WAIT))); } @ApiOperation(value = "유저 신청 Playground 결과 리스트", notes = "유저가 신청한 Playground중 결과(수락, 거절)가 나온 리스트") @GetMapping("/notices/results") public ResponseEntity> getUserResultNotice() { - return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserStatusNoticeList(UserAuthenticationService.getUserId(), "result"))); + return ResponseEntity.ok().body(new ApiResponse<>(noticeService.getUserStatusNoticeList(UserAuthenticationService.getUserId(), PgConstant.NOTICE_RESULT))); } } From 4a04db8b6266f1357e8194959b7d5780112d7965 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sun, 29 Aug 2021 13:30:09 +0900 Subject: [PATCH 082/176] =?UTF-8?q?feat:=20spring=20gateway=20predicate=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Authentication/build.gradle | 2 +- .../src/main/resources/application.yml | 2 ++ Backend/build.gradle | 2 +- Backend/src/main/resources/application.yml | 2 ++ .../java/com/pg/gateway/GatewayApplication.java | 3 ++- Cloud/Gateway/src/main/resources/application.yml | 16 ++++++++++++---- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Authentication/build.gradle b/Authentication/build.gradle index 281ec77..c9695f4 100644 --- a/Authentication/build.gradle +++ b/Authentication/build.gradle @@ -25,7 +25,7 @@ ext { } dependencies { - //implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-security' diff --git a/Authentication/src/main/resources/application.yml b/Authentication/src/main/resources/application.yml index 608260a..d577c96 100644 --- a/Authentication/src/main/resources/application.yml +++ b/Authentication/src/main/resources/application.yml @@ -21,6 +21,8 @@ server: port: 8080 eureka: client: + register-with-eureka: true + fetch-registry: true service-url: defaultZone: http://127.0.0.1:8761/eureka --- diff --git a/Backend/build.gradle b/Backend/build.gradle index d4a2702..d1bf1ea 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -30,7 +30,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-webflux' - //implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.hibernate.validator:hibernate-validator:6.1.2.Final' implementation 'io.jsonwebtoken:jjwt:0.7.0' implementation 'com.h2database:h2' diff --git a/Backend/src/main/resources/application.yml b/Backend/src/main/resources/application.yml index d270e1a..d2f1326 100644 --- a/Backend/src/main/resources/application.yml +++ b/Backend/src/main/resources/application.yml @@ -25,6 +25,8 @@ server: eureka: client: + register-with-eureka: true + fetch-registry: true service-url: defaultZone: http://127.0.0.1:8761/eureka --- diff --git a/Cloud/Gateway/src/main/java/com/pg/gateway/GatewayApplication.java b/Cloud/Gateway/src/main/java/com/pg/gateway/GatewayApplication.java index ee0eb0c..7f535fa 100644 --- a/Cloud/Gateway/src/main/java/com/pg/gateway/GatewayApplication.java +++ b/Cloud/Gateway/src/main/java/com/pg/gateway/GatewayApplication.java @@ -2,12 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication +@EnableDiscoveryClient public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } - } diff --git a/Cloud/Gateway/src/main/resources/application.yml b/Cloud/Gateway/src/main/resources/application.yml index 197fa81..d7ad358 100644 --- a/Cloud/Gateway/src/main/resources/application.yml +++ b/Cloud/Gateway/src/main/resources/application.yml @@ -3,8 +3,8 @@ server: eureka: client: - register-with-eureka: false - fetch-registry: false + register-with-eureka: true + fetch-registry: true service-url: defaultZone: http://127.0.0.1:8761/eureka @@ -14,8 +14,16 @@ spring: cloud: gateway: routes: + - id: auth-service + uri: lb://AUTH-SERVICE + predicates: + - Path=/auth/** + filters: + - RewritePath=/auth/(?.*), /$\{segment} - id: programmerground-service - uri: http://127.0.0.1:9000/ + uri: lb://PROGRAMMERGROUND-SERVICE predicates: - - Path=/programmerground/ + - Path=/pg/** + filters: + - RewritePath=/pg/(?.*), /$\{segment} From 813e9acd50dcc447df610a77fe646430f01a660b Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Tue, 31 Aug 2021 00:39:55 +0900 Subject: [PATCH 083/176] #127 remove api --- Frontend/src/components/sameUI/index.tsx | 1 + Frontend/src/lib/axios/playground.ts | 4 +--- Frontend/src/lib/axios/request.ts | 15 +++++++++------ Frontend/src/pages/PlaygroundIdPage/index.tsx | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Frontend/src/components/sameUI/index.tsx b/Frontend/src/components/sameUI/index.tsx index 621acfa..9c5c7a6 100644 --- a/Frontend/src/components/sameUI/index.tsx +++ b/Frontend/src/components/sameUI/index.tsx @@ -26,6 +26,7 @@ const SameUI = ({ if (selectModal) { deleteOnePlayground(id); history.push('/'); + location.reload(); } }; return ( diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 86a4728..0b5cf23 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -37,8 +37,6 @@ export const getOneUser = async () => { }; export const deleteOnePlayground = async (playgroundId: number) => { - const playground = await deleteData( - `${url.DELETE_ONE_PLAYGROUND}${playgroundId}`, - ); + const playground = await deleteData(`${url.DELETE_ONE_PLAYGROUND}${playgroundId}`, 'delete'); return playground; }; diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index ecce25f..80df988 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -13,7 +13,7 @@ const informError = (error: Error) => { : '오류가 발생하여 요청에 실패하였습니다'; }; -export const getOptions = async (type: undefined) => { +export const getOptions = async (type?: string) => { const refreshToken = useCookie('refresh_token'); if (refreshToken[0] === '') { document.cookie = 'access_token=; Max-Age=0'; @@ -27,6 +27,9 @@ export const getOptions = async (type: undefined) => { await getReissued(); cookie = useCookie('access_token'); } + if(type === 'delete') { + return cookie[0]; + } const options = setOptions(cookie[0], type); return options; }; @@ -74,6 +77,7 @@ const getReissued = async () => { export const getData = async (url: string) => { const options = await getOptions(); + console.log(options); try { const response = await axios.get(url, options); return response.data.data; @@ -93,7 +97,7 @@ export const postData = async (url: string, body: any, type: string) => { }; export const patchData = async (url: string, body: string) => { - const options = getOptions(); + const options = await getOptions(); try { const response = await axios.patch(url, body, options); @@ -104,7 +108,7 @@ export const patchData = async (url: string, body: string) => { }; export const putData = async (url: string, body: string) => { - const options = getOptions(); + const options = await getOptions(); try { const response = await axios.put(url, body, options); @@ -114,9 +118,8 @@ export const putData = async (url: string, body: string) => { } }; -export const deleteData = async (url: string) => { - const options = getOptions(); - +export const deleteData = async (url: string, type: string) => { + const options = await getOptions(); try { const response = await axios.delete(url, options); return response.data; diff --git a/Frontend/src/pages/PlaygroundIdPage/index.tsx b/Frontend/src/pages/PlaygroundIdPage/index.tsx index 045823e..4825984 100644 --- a/Frontend/src/pages/PlaygroundIdPage/index.tsx +++ b/Frontend/src/pages/PlaygroundIdPage/index.tsx @@ -15,6 +15,7 @@ const PlaygroundIdPage = () => { positionList, id, } = location.state as any; + console.log(id, loginUserName, data, playgroundTitle); return ( <>
From ae0c3b48e76f36d955c6f4b0fca6f129f746a386 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 2 Sep 2021 23:57:18 +0900 Subject: [PATCH 084/176] =?UTF-8?q?#127=20feat:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EB=94=94=20=EC=88=98=EC=A0=95=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20UI=20=EB=A7=8C=EB=93=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/pages/ProfilePage/index.tsx | 26 +++++++++++++++++++++--- Frontend/src/pages/ProfilePage/style.ts | 22 +++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Frontend/src/pages/ProfilePage/index.tsx b/Frontend/src/pages/ProfilePage/index.tsx index 34110bb..8ba2871 100644 --- a/Frontend/src/pages/ProfilePage/index.tsx +++ b/Frontend/src/pages/ProfilePage/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useState} from 'react'; import Header from '@src/components/header'; import { useLocation } from 'react-router-dom'; import * as StyledComponent from './style'; @@ -6,7 +6,15 @@ import * as StyledComponent from './style'; const ProfilePage = () => { const location = useLocation(); const user = (location.state as any).userData; - console.log(user); + const [edit, setEdit] = useState(false); + const ProfileEditHandler = () => { + setEdit(true); + } + + const ProfileSaveHandler = () => { + console.log('save'); + } + return (
@@ -28,6 +36,16 @@ const ProfilePage = () => { General Info + {edit? + + + Name + + + + Save + : + Name @@ -35,7 +53,9 @@ const ProfilePage = () => { {user.oauth_name} - + Edit + + } GitHub diff --git a/Frontend/src/pages/ProfilePage/style.ts b/Frontend/src/pages/ProfilePage/style.ts index 1d936f2..7e9936e 100644 --- a/Frontend/src/pages/ProfilePage/style.ts +++ b/Frontend/src/pages/ProfilePage/style.ts @@ -69,14 +69,34 @@ export const ProfileGeneralAttribute = styled.div` border-top: 1px solid #e6ecf5; } display: flex; + position: relative; padding: 30px 20px; `; export const ProfileGeneralName = styled.span` font-weight: bold; - flex: 1 1 25%; + flex: 0 0 25%; `; export const ProfileGeneralValue = styled.span` flex: 1 1 75%; `; + +export const ProfileInput = styled.input.attrs((props) => ({ + type:'text', + maxlength:'30', + placeholder:'수정할 아이디' +}))` + flex: 0 0 auto; + border: 1px solid #e9e9e9; + outline: none; +`; + +export const ProfileButton = styled.button` + position: absolute; + top: 23px; + right: 20px; + padding: 5px; + background-color: #fff; + border: 1px solid #e9e9e9; +`; \ No newline at end of file From ebca820cc7f45e83a55e5b6b100310ebd672766c Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sat, 4 Sep 2021 23:30:01 +0900 Subject: [PATCH 085/176] feat: spring cloud config --- Authentication/build.gradle | 2 ++ .../java/com/pg/auth/config/Oauth2WebSecurityConfig.java | 5 +---- .../main/java/com/pg/auth/controller/AuthController.java | 7 +++++++ Authentication/src/main/resources/bootstrap.yml | 5 +++++ Backend/build.gradle | 2 ++ .../java/com/pg/programmerground/domain/Playground.java | 2 +- Backend/src/main/resources/bootstrap.yml | 5 +++++ 7 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 Authentication/src/main/resources/bootstrap.yml create mode 100644 Backend/src/main/resources/bootstrap.yml diff --git a/Authentication/build.gradle b/Authentication/build.gradle index c9695f4..b4cf4fd 100644 --- a/Authentication/build.gradle +++ b/Authentication/build.gradle @@ -25,6 +25,8 @@ ext { } dependencies { + implementation 'org.springframework.cloud:spring-cloud-starter-config' + implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' diff --git a/Authentication/src/main/java/com/pg/auth/config/Oauth2WebSecurityConfig.java b/Authentication/src/main/java/com/pg/auth/config/Oauth2WebSecurityConfig.java index da6ee3e..1f06042 100644 --- a/Authentication/src/main/java/com/pg/auth/config/Oauth2WebSecurityConfig.java +++ b/Authentication/src/main/java/com/pg/auth/config/Oauth2WebSecurityConfig.java @@ -35,7 +35,7 @@ public class Oauth2WebSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .mvcMatchers(HttpMethod.POST, "/jwtLogin", "/reissued").permitAll() - .mvcMatchers("/oauth2/**", "/err", "/loginCode", "/test-token").permitAll() + .mvcMatchers("/oauth2/**", "/err", "/loginCode", "/test-token", "/test").permitAll() .anyRequest().authenticated(); http.httpBasic().disable(); //OAuthLogin 설정 @@ -65,9 +65,6 @@ public CorsConfigurationSource corsConfigurationSource() { * OAUTH 인증 성공 후 처리 * 유저 정보가 존재하지 않으면(최초 로그인) DB에 유저 정보 저장 * /getToken으로 보내 JWT 토큰을 생성해 보냄 - * - * @return - * @throws OAuthLoginException */ private AuthenticationSuccessHandler successHandler() { return (request, response, authentication) -> { diff --git a/Authentication/src/main/java/com/pg/auth/controller/AuthController.java b/Authentication/src/main/java/com/pg/auth/controller/AuthController.java index bfc301e..e134198 100644 --- a/Authentication/src/main/java/com/pg/auth/controller/AuthController.java +++ b/Authentication/src/main/java/com/pg/auth/controller/AuthController.java @@ -7,6 +7,7 @@ import com.pg.auth.service.OAuthUserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; @@ -21,6 +22,7 @@ public class AuthController { private static final String COOKIE_DOMAIN = ".localhost"; private final OAuthUserService oAuthUserService; private final JwtTokenProvider jwtTokenProvider; + private final Environment env; //http://localhost:8080/oauth2/authorization/github /** * 프론트용 테스트 @@ -66,6 +68,11 @@ public ResponseEntity info(Authentication authentication) { return ResponseEntity.ok().body(authentication.getPrincipal()); } + @GetMapping("/test") + public String test() { + return env.getProperty("test.name"); + } + /** * 에러 페이지 */ diff --git a/Authentication/src/main/resources/bootstrap.yml b/Authentication/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..0d7a573 --- /dev/null +++ b/Authentication/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +spring: + cloud: + config: + uri: http://127.0.0.1:8888 + name: application-auth-dev \ No newline at end of file diff --git a/Backend/build.gradle b/Backend/build.gradle index d1bf1ea..149f3b2 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -25,6 +25,8 @@ ext { } dependencies { + implementation 'org.springframework.cloud:spring-cloud-starter-config' + implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' diff --git a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java index f1f748b..a333f64 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java @@ -19,7 +19,7 @@ @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Where(clause = "STATUS_FLAG='ACTIVE'") +@Where(clause = "STATUS_FLAG='ACTIVE'") //기본적으로 ACTIVE만 불러옴 public class Playground extends BaseTimeEntity { @Id diff --git a/Backend/src/main/resources/bootstrap.yml b/Backend/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..5bb03c8 --- /dev/null +++ b/Backend/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +spring: + cloud: + config: + uri: http://127.0.0.1:8888 + name: application-pg-dev \ No newline at end of file From 4251a683063bb5bd02abd361ceb3ae9cc81d5102 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sun, 5 Sep 2021 00:24:07 +0900 Subject: [PATCH 086/176] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pg/programmerground/domain/Playground.java | 6 ++++-- .../dto/user/response/UserPlaygroundResponse.java | 2 +- .../com/pg/programmerground/model/PlaygroundRepository.java | 6 ++++++ .../com/pg/programmerground/service/PlaygroundService.java | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java index f1f748b..8bdf7e8 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/Playground.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/Playground.java @@ -8,7 +8,6 @@ import com.pg.programmerground.exception.IncorrectUserException; import com.pg.programmerground.exception.WrongRequestException; import lombok.*; -import org.hibernate.annotations.Where; import javax.persistence.*; import java.util.ArrayList; @@ -19,7 +18,6 @@ @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Where(clause = "STATUS_FLAG='ACTIVE'") public class Playground extends BaseTimeEntity { @Id @@ -124,6 +122,10 @@ public void isLeaderUser(OAuthUser user) { } } + public boolean isRemovePlayground() { + return this.statusFlag == PlaygroundStatus.REMOVE; + } + /** * playground 삭제처리 * 실제 삭제가 아닌 flag remove 설정 diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserPlaygroundResponse.java b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserPlaygroundResponse.java index 5e6de5c..ca3caed 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserPlaygroundResponse.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserPlaygroundResponse.java @@ -27,7 +27,7 @@ public class UserPlaygroundResponse { public static List ofList(List playgroundApplies) { return playgroundApplies.stream() - .filter(PlaygroundApply::isAcceptApply) + .filter(playgroundApply -> playgroundApply.getPlayground().isRemovePlayground()) .map(playgroundApply -> UserPlaygroundResponse.builder() .playgroundId(playgroundApply.getPlayground().getId()) .title(playgroundApply.getPlayground().getTitle()) diff --git a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java index b3e584d..3cadddb 100644 --- a/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java +++ b/Backend/src/main/java/com/pg/programmerground/model/PlaygroundRepository.java @@ -3,9 +3,15 @@ import com.pg.programmerground.domain.OAuthUser; import com.pg.programmerground.domain.Playground; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.util.List; import java.util.Optional; public interface PlaygroundRepository extends JpaRepository { Optional findPlaygroundByIdAndLeader(Long id, OAuthUser leader); + @Query("SELECT p " + + "FROM PLAYGROUND p " + + "WHERE p.statusFlag = 'ACTIVE'") + List findPlaygroundsByStatsActive(); } diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 4807a18..1046656 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -44,7 +44,7 @@ public class PlaygroundService { * 메인 페이지 playground card 목록 가져오기 */ public List getPlaygroundCardList() { - return PlaygroundCardResponse.ofList(playgroundRepository.findAll()); + return PlaygroundCardResponse.ofList(playgroundRepository.findPlaygroundsByStatsActive()); } /** From 0f102ff6688d7585c27ad74caf6fff799bc7b658 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Sun, 5 Sep 2021 23:46:37 +0900 Subject: [PATCH 087/176] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20validated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../programmerground/controller/OAuthUserController.java | 5 +++-- .../programmerground/dto/user/api_req/ReviseUserApi.java | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java index f863853..70e18a3 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java @@ -12,6 +12,7 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @RestController @@ -52,8 +53,8 @@ public ResponseEntity> getUserNotice() } @ApiOperation(value = "유저 정보 수정", notes = "유저 정보를 수정") - @PutMapping("") - public ResponseEntity> updateUserInfo(@ModelAttribute ReviseUserApi userApi) { + @PatchMapping("") + public ResponseEntity> updateUserInfo(@ModelAttribute @Validated ReviseUserApi userApi) { return ResponseEntity.ok().body(new ApiResponse<>(oAuthUserService.updateUserInfo(UserAuthenticationService.getUserId(), userApi))); } diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java index ebf34f1..eb6fce9 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java @@ -3,9 +3,16 @@ import lombok.Getter; import lombok.Setter; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + @Setter @Getter public class ReviseUserApi { + @NotNull + @Min(value = 1, message = "최소 1글자") + @Max(value = 5, message = "최대 5글자") private String userName; } From ae0f923c46c1ead9475789afb8b3e06987e31c4d Mon Sep 17 00:00:00 2001 From: dailyworker Date: Mon, 6 Sep 2021 00:37:17 +0900 Subject: [PATCH 088/176] [#131] refactor : UserResponse, OAuthUserService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UserResponse : 생략된 user_name 추가 - OAuthUserService : 코드 수정 (불필요한 변수 생성 없게) --- .../programmerground/dto/user/response/UserResponse.java | 4 ++++ .../com/pg/programmerground/service/OAuthUserService.java | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserResponse.java b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserResponse.java index c4c6616..9077ce7 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserResponse.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserResponse.java @@ -21,6 +21,9 @@ public class UserResponse { @JsonProperty(value = "oauth_name") private final String oauthName; + @JsonProperty(value = "user_name") + private final String userName; + @JsonProperty(value = "commit_cnt") private final int commitCnt; @@ -46,6 +49,7 @@ public static UserResponse of(OAuthUser user) { return UserResponse.builder() .oauthId(user.getOauth2AuthorizedClient().getId()) .userId(user.getId()) + .userName(user.getUserName()) .oauthName(user.getOAuthName()) .commitCnt(user.getUserGithubInfo().getCommitCnt()) .pullRequestCnt(user.getUserGithubInfo().getPullRequestCnt()) diff --git a/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java b/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java index d65253b..0df0191 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/OAuthUserService.java @@ -38,7 +38,8 @@ public UserDetails loadUserByOAuthId(Long OAuthId) { * 유저 정보 */ public UserResponse getUserInfo(Long userId) { - return UserResponse.of(oAuthUserRepository.findById(userId).orElseThrow()); + return UserResponse.of(oAuthUserRepository.findById(userId) + .orElseThrow(() -> new EntityNotFoundException("사용자가 존재하지 않습니다."))); } /** @@ -46,8 +47,9 @@ public UserResponse getUserInfo(Long userId) { */ @Transactional public Boolean updateUserInfo(Long oauthUserId, ReviseUserApi userApi) { - OAuthUser user = oAuthUserRepository.findById(oauthUserId).orElseThrow((() -> new NoSuchElementException("잘못된 유저 요청"))); - user.updateUser(userApi); + oAuthUserRepository.findById(oauthUserId) + .orElseThrow((() -> new NoSuchElementException("잘못된 유저 요청"))) + .updateUser(userApi); return true; } } From 55a5ff25511bf01ffa7fc2b620bee92f650f19f6 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Mon, 6 Sep 2021 22:36:48 +0900 Subject: [PATCH 089/176] [#132] refactor : OAuthUserController, ReviseUserApi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - OAuthUserController : 기존 Form데이터로 넘어오던거 JSON으로 변경 - ReviseUserApi : validate 수정 --- .../controller/OAuthUserController.java | 2 +- .../dto/user/api_req/ReviseUserApi.java | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java index 70e18a3..d26a0ae 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/OAuthUserController.java @@ -54,7 +54,7 @@ public ResponseEntity> getUserNotice() @ApiOperation(value = "유저 정보 수정", notes = "유저 정보를 수정") @PatchMapping("") - public ResponseEntity> updateUserInfo(@ModelAttribute @Validated ReviseUserApi userApi) { + public ResponseEntity> updateUserInfo(@RequestBody @Validated ReviseUserApi userApi) { return ResponseEntity.ok().body(new ApiResponse<>(oAuthUserService.updateUserInfo(UserAuthenticationService.getUserId(), userApi))); } diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java index eb6fce9..07679bc 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java @@ -2,17 +2,14 @@ import lombok.Getter; import lombok.Setter; +import org.hibernate.validator.constraints.Length; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; @Setter @Getter public class ReviseUserApi { - @NotNull - @Min(value = 1, message = "최소 1글자") - @Max(value = 5, message = "최대 5글자") + @Length(max = 5) + @NotBlank private String userName; - } From 6a653219dca2b27c43a9a0122c9ff44495909336 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Mon, 6 Sep 2021 22:40:21 +0900 Subject: [PATCH 090/176] =?UTF-8?q?fix=20:=20Notnull=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/pg/programmerground/dto/user/api_req/ReviseUserApi.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java index 07679bc..0a55ea0 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/api_req/ReviseUserApi.java @@ -5,11 +5,13 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; @Setter @Getter public class ReviseUserApi { @Length(max = 5) @NotBlank + @NotNull private String userName; } From d100922fa16722cb20ad71f11769587bd96e2a4a Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Mon, 6 Sep 2021 00:43:19 +0900 Subject: [PATCH 091/176] =?UTF-8?q?#127:=20=EC=9C=A0=EC=A0=80=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 7 +++++++ Frontend/src/lib/axios/request.ts | 14 +++++++------- Frontend/src/pages/ProfilePage/index.tsx | 16 +++++++++++++--- Frontend/src/pages/ProfilePage/style.ts | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 0b5cf23..219c52a 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -8,6 +8,7 @@ const url = { GET_ONE_PLAYGROUND: 'http://localhost:9000/playground/', CREATE_IMAGE_PLAYGROUND: 'http://localhost:9000/images/pgmainimg/', GET_ONE_USER: 'http://localhost:9000/user', + PUT_ONE_USER: 'http://localhost:9000/user', DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', }; @@ -40,3 +41,9 @@ export const deleteOnePlayground = async (playgroundId: number) => { const playground = await deleteData(`${url.DELETE_ONE_PLAYGROUND}${playgroundId}`, 'delete'); return playground; }; + +export const PutOneUser = async(userName: string, type:string) => { + const user = await putData(`${url.PUT_ONE_USER}`, userName, type); + console.log(user); + return user; +} \ No newline at end of file diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index 80df988..35f7843 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -36,16 +36,17 @@ export const getOptions = async (type?: string) => { const setOptions = (token: string, type: string): any => { const headers = {}; - if (type !== 'image') { + console.log(type); + if (type === 'image' || type === 'profile') { headers = { - 'Content-Type': 'application/json;charset=UTF-8', + 'Content-Type': 'multipart/form-data', 'Access-Control-Allow-Origin': '*', Accept: 'application/json', Authorization: `Bearer ${token}`, }; } else { headers = { - 'Content-Type': 'multipart/form-data', + 'Content-Type': 'application/json;charset=UTF-8', 'Access-Control-Allow-Origin': '*', Accept: 'application/json', Authorization: `Bearer ${token}`, @@ -77,8 +78,7 @@ const getReissued = async () => { export const getData = async (url: string) => { const options = await getOptions(); - console.log(options); - try { + try { const response = await axios.get(url, options); return response.data.data; } catch (error) { @@ -107,8 +107,8 @@ export const patchData = async (url: string, body: string) => { } }; -export const putData = async (url: string, body: string) => { - const options = await getOptions(); +export const putData = async (url: string, body: string, type: string) => { + const options = await getOptions(type); try { const response = await axios.put(url, body, options); diff --git a/Frontend/src/pages/ProfilePage/index.tsx b/Frontend/src/pages/ProfilePage/index.tsx index 8ba2871..a6884c9 100644 --- a/Frontend/src/pages/ProfilePage/index.tsx +++ b/Frontend/src/pages/ProfilePage/index.tsx @@ -2,19 +2,29 @@ import React, {useState} from 'react'; import Header from '@src/components/header'; import { useLocation } from 'react-router-dom'; import * as StyledComponent from './style'; +import {PutOneUser} from '@src/lib/axios/playground'; const ProfilePage = () => { const location = useLocation(); const user = (location.state as any).userData; + const [userName, setUserName] = useState(''); const [edit, setEdit] = useState(false); const ProfileEditHandler = () => { setEdit(true); } - const ProfileSaveHandler = () => { - console.log('save'); + const ProfileSaveHandler = async () => { + if(userName.length >= 1 && userName.length <= 5) { + alert('글자 수가 너무 짧습니다. 다시 입력해주세요'); + return; + } + const response = await PutOneUser(userName, 'profile'); + setEdit(false); } + const ProfileInput = (e: any) => { + setUserName(e.target.value); + } return (
@@ -41,7 +51,7 @@ const ProfilePage = () => { Name - + Save : diff --git a/Frontend/src/pages/ProfilePage/style.ts b/Frontend/src/pages/ProfilePage/style.ts index 7e9936e..b66e853 100644 --- a/Frontend/src/pages/ProfilePage/style.ts +++ b/Frontend/src/pages/ProfilePage/style.ts @@ -85,7 +85,7 @@ export const ProfileGeneralValue = styled.span` export const ProfileInput = styled.input.attrs((props) => ({ type:'text', maxlength:'30', - placeholder:'수정할 아이디' + placeholder:'수정할 이름' }))` flex: 0 0 auto; border: 1px solid #e9e9e9; From ea5e5dd8e3cb52f95cb4b338ecfdee081d5c1bcf Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Mon, 6 Sep 2021 22:47:27 +0900 Subject: [PATCH 092/176] =?UTF-8?q?#127=20=EC=9C=A0=EC=A0=80=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20put=20->=20patch=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 5 ++--- Frontend/src/lib/axios/request.ts | 13 ++++++------- Frontend/src/pages/PlayGroundPage/index.tsx | 2 +- Frontend/src/pages/ProfilePage/index.tsx | 8 ++++---- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 219c52a..a144221 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -42,8 +42,7 @@ export const deleteOnePlayground = async (playgroundId: number) => { return playground; }; -export const PutOneUser = async(userName: string, type:string) => { - const user = await putData(`${url.PUT_ONE_USER}`, userName, type); - console.log(user); +export const patchOneUser = async(userName: string, type:string) => { + const user = await patchData(`${url.PUT_ONE_USER}`, userName, type); return user; } \ No newline at end of file diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index 35f7843..a6c8a34 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -36,15 +36,14 @@ export const getOptions = async (type?: string) => { const setOptions = (token: string, type: string): any => { const headers = {}; - console.log(type); - if (type === 'image' || type === 'profile') { + if (type === 'image') { headers = { 'Content-Type': 'multipart/form-data', 'Access-Control-Allow-Origin': '*', Accept: 'application/json', Authorization: `Bearer ${token}`, }; - } else { + } else{ headers = { 'Content-Type': 'application/json;charset=UTF-8', 'Access-Control-Allow-Origin': '*', @@ -96,8 +95,8 @@ export const postData = async (url: string, body: any, type: string) => { } }; -export const patchData = async (url: string, body: string) => { - const options = await getOptions(); +export const patchData = async (url: string, body: string, type: string) => { + const options = await getOptions(type); try { const response = await axios.patch(url, body, options); @@ -107,8 +106,8 @@ export const patchData = async (url: string, body: string) => { } }; -export const putData = async (url: string, body: string, type: string) => { - const options = await getOptions(type); +export const putData = async (url: string, body: string) => { + const options = await getOptions(); try { const response = await axios.put(url, body, options); diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index 0d2b418..c31d4c0 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -92,7 +92,7 @@ const PlayGroundPage = () => { positionList={v.position_list} src={v.logo_img_name} id={v.playground_id} - user={v.leader_oauth_name} + user={v.leader_user_name} createDate={v.created_date} /> ); diff --git a/Frontend/src/pages/ProfilePage/index.tsx b/Frontend/src/pages/ProfilePage/index.tsx index a6884c9..fe57550 100644 --- a/Frontend/src/pages/ProfilePage/index.tsx +++ b/Frontend/src/pages/ProfilePage/index.tsx @@ -2,7 +2,7 @@ import React, {useState} from 'react'; import Header from '@src/components/header'; import { useLocation } from 'react-router-dom'; import * as StyledComponent from './style'; -import {PutOneUser} from '@src/lib/axios/playground'; +import {patchOneUser} from '@src/lib/axios/playground'; const ProfilePage = () => { const location = useLocation(); @@ -18,7 +18,7 @@ const ProfilePage = () => { alert('글자 수가 너무 짧습니다. 다시 입력해주세요'); return; } - const response = await PutOneUser(userName, 'profile'); + const response = await patchOneUser(userName, 'profile'); setEdit(false); } @@ -39,7 +39,7 @@ const ProfilePage = () => { width="117px" height="117px" /> -

{user.oauth_name}

+

{user.user_name}

@@ -61,7 +61,7 @@ const ProfilePage = () => { Name - {user.oauth_name} + {user.user_name} Edit From 8bc8e7a9eabfc3adce48d9c2079d1d7312d23798 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Mon, 6 Sep 2021 23:16:20 +0900 Subject: [PATCH 093/176] =?UTF-8?q?feat:=20config=20server=20git=20private?= =?UTF-8?q?=20repo=20=EA=B4=80=EB=A6=AC=20=EC=85=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Authentication/build.gradle | 1 + .../src/main/resources/application.yml | 26 ++++++++++++------- .../src/main/resources/bootstrap.yml | 3 ++- Backend/build.gradle | 1 + Backend/src/main/resources/application.yml | 22 ++++++++++------ Backend/src/main/resources/bootstrap.yml | 3 ++- 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Authentication/build.gradle b/Authentication/build.gradle index b4cf4fd..7889db2 100644 --- a/Authentication/build.gradle +++ b/Authentication/build.gradle @@ -25,6 +25,7 @@ ext { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' diff --git a/Authentication/src/main/resources/application.yml b/Authentication/src/main/resources/application.yml index d577c96..bf11310 100644 --- a/Authentication/src/main/resources/application.yml +++ b/Authentication/src/main/resources/application.yml @@ -6,16 +6,22 @@ spring: config: activate: on-profile: "common" - security: - jwt-token: - secret-key: awdsd - oauth2: - client: - registration: - github: - client-id: 5f8150b5b4b06259a3aa - client-secret: 1fa30fbeceef904db5b2a1323b32dbcdd200379b - scope: public_repo, read:user +# security: +# jwt-token: +# secret-key: awdsd +# oauth2: +# client: +# registration: +# github: +# client-id: 5f8150b5b4b06259a3aa +# client-secret: 1fa30fbeceef904db5b2a1323b32dbcdd200379b +# scope: public_repo, read:user + +management: + endpoint: + web: + exposure: + include: refresh, health, beans server: port: 8080 diff --git a/Authentication/src/main/resources/bootstrap.yml b/Authentication/src/main/resources/bootstrap.yml index 0d7a573..7aa3e7e 100644 --- a/Authentication/src/main/resources/bootstrap.yml +++ b/Authentication/src/main/resources/bootstrap.yml @@ -2,4 +2,5 @@ spring: cloud: config: uri: http://127.0.0.1:8888 - name: application-auth-dev \ No newline at end of file + name: auth + profile: dev diff --git a/Backend/build.gradle b/Backend/build.gradle index 149f3b2..9f5e230 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -25,6 +25,7 @@ ext { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/Backend/src/main/resources/application.yml b/Backend/src/main/resources/application.yml index d2f1326..bede836 100644 --- a/Backend/src/main/resources/application.yml +++ b/Backend/src/main/resources/application.yml @@ -5,14 +5,20 @@ spring: config: activate: on-profile: "common" - security: - jwt-token: - secret-key: awdsd - -github: - token: "bearer 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" - org-url : "https://api.github.com/orgs/programmer-ground" - org-repo-url : "https://api.github.com/repos/programmer-ground" +# security: +# jwt-token: +# secret-key: awdsd + +#github: +# token: "bearer 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" +# org-url : "https://api.github.com/orgs/programmer-ground" +# org-repo-url : "https://api.github.com/repos/programmer-ground" + +management: + endpoint: + web: + exposure: + include: refresh, health, beans server: port: 9000 diff --git a/Backend/src/main/resources/bootstrap.yml b/Backend/src/main/resources/bootstrap.yml index 5bb03c8..ec91e62 100644 --- a/Backend/src/main/resources/bootstrap.yml +++ b/Backend/src/main/resources/bootstrap.yml @@ -2,4 +2,5 @@ spring: cloud: config: uri: http://127.0.0.1:8888 - name: application-pg-dev \ No newline at end of file + name: pg + profile: dev From c5efb7a92bdefa71118be92843c3d5ce4b49b1a1 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Tue, 7 Sep 2021 00:21:37 +0900 Subject: [PATCH 094/176] =?UTF-8?q?#127=20feat:=20user=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 4 ++-- Frontend/src/lib/axios/request.ts | 6 ++++-- Frontend/src/pages/ProfilePage/index.tsx | 14 ++++++++++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index a144221..687c19e 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -8,7 +8,7 @@ const url = { GET_ONE_PLAYGROUND: 'http://localhost:9000/playground/', CREATE_IMAGE_PLAYGROUND: 'http://localhost:9000/images/pgmainimg/', GET_ONE_USER: 'http://localhost:9000/user', - PUT_ONE_USER: 'http://localhost:9000/user', + PATCH_ONE_USER: 'http://localhost:9000/user', DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', }; @@ -43,6 +43,6 @@ export const deleteOnePlayground = async (playgroundId: number) => { }; export const patchOneUser = async(userName: string, type:string) => { - const user = await patchData(`${url.PUT_ONE_USER}`, userName, type); + const user = await patchData(`${url.PATCH_ONE_USER}`, userName, type); return user; } \ No newline at end of file diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index a6c8a34..6329bab 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -97,9 +97,11 @@ export const postData = async (url: string, body: any, type: string) => { export const patchData = async (url: string, body: string, type: string) => { const options = await getOptions(type); - + const data = { + 'userName': body + } try { - const response = await axios.patch(url, body, options); + const response = await axios.patch(url, data, options); return response.data; } catch (error) { informError(error); diff --git a/Frontend/src/pages/ProfilePage/index.tsx b/Frontend/src/pages/ProfilePage/index.tsx index fe57550..f17bd42 100644 --- a/Frontend/src/pages/ProfilePage/index.tsx +++ b/Frontend/src/pages/ProfilePage/index.tsx @@ -1,12 +1,13 @@ import React, {useState} from 'react'; import Header from '@src/components/header'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useHistory } from 'react-router-dom'; import * as StyledComponent from './style'; -import {patchOneUser} from '@src/lib/axios/playground'; +import {patchOneUser, getOneUser} from '@src/lib/axios/playground'; const ProfilePage = () => { const location = useLocation(); const user = (location.state as any).userData; + const history = useHistory(); const [userName, setUserName] = useState(''); const [edit, setEdit] = useState(false); const ProfileEditHandler = () => { @@ -14,12 +15,17 @@ const ProfilePage = () => { } const ProfileSaveHandler = async () => { - if(userName.length >= 1 && userName.length <= 5) { - alert('글자 수가 너무 짧습니다. 다시 입력해주세요'); + if(userName.length > 5) { + alert('글자 수가 너무 깁니다. 다시 입력해주세요'); return; } const response = await patchOneUser(userName, 'profile'); setEdit(false); + const userData = await getOneUser(); + history.push({ + pathname: '/profile', + state: { userData }, + }); } const ProfileInput = (e: any) => { From 2d2dce649224437d74d1dddec8947be3b7fc4060 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 11 Sep 2021 05:07:28 +0900 Subject: [PATCH 095/176] =?UTF-8?q?feat:=20user=20language=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/pages/ProfilePage/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Frontend/src/pages/ProfilePage/index.tsx b/Frontend/src/pages/ProfilePage/index.tsx index f17bd42..bb7cb6d 100644 --- a/Frontend/src/pages/ProfilePage/index.tsx +++ b/Frontend/src/pages/ProfilePage/index.tsx @@ -80,6 +80,14 @@ const ProfilePage = () => { {user.github_page} + + + Language + + + {user.most_language} + + From 404562ee7bbc3b2287851d9131dcd9baac78d54f Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sat, 11 Sep 2021 15:05:25 +0900 Subject: [PATCH 096/176] [#133] refactor : Position, PositionVo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - enum 값을 리스트로 전달하는 api를 위해 리팩토링 --- .../domain/enumerated/Position.java | 31 ++++++++++++++++++- .../pg/programmerground/vo/PositionVo.java | 18 +++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 Backend/src/main/java/com/pg/programmerground/vo/PositionVo.java diff --git a/Backend/src/main/java/com/pg/programmerground/domain/enumerated/Position.java b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/Position.java index 653125c..efc836a 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/enumerated/Position.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/enumerated/Position.java @@ -1,5 +1,34 @@ package com.pg.programmerground.domain.enumerated; +import com.pg.programmerground.vo.PositionVo; +import lombok.Getter; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Getter public enum Position { - BACKEND, FRONTEND, DESIGN, PLANNER, DEVOPS + BACKEND(1, "BACKEND"), + FRONTEND(2, "FRONTEND"), + DESIGN(3, "DESIGN"), + PLANNER(4, "PLANNER"), + DEVOPS(5, "DEVOPS"); + + private final int id; + private final String content; + + Position(int id, String content) { + this.id = id; + this.content = content; + } + + public static List toEntity() { + return Arrays.stream(Position.class.getEnumConstants()) + .map(item -> PositionVo.of(item.getId(), + item.getContent())) + .collect(Collectors.toList()); + } } diff --git a/Backend/src/main/java/com/pg/programmerground/vo/PositionVo.java b/Backend/src/main/java/com/pg/programmerground/vo/PositionVo.java new file mode 100644 index 0000000..bcb927b --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/vo/PositionVo.java @@ -0,0 +1,18 @@ +package com.pg.programmerground.vo; + +import lombok.Getter; + +@Getter +public class PositionVo { + private final int id; + private final String content; + + public static PositionVo of(int id, String content) { + return new PositionVo(id, content); + } + + private PositionVo(int id, String content) { + this.id = id; + this.content = content; + } +} From 239ed9dc4dc0bd47168add59651cdf6cf7c9dca9 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sat, 11 Sep 2021 15:11:07 +0900 Subject: [PATCH 097/176] [#133] refactor :PlaygroundController, PlaygroundService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Playground id로 PlaygroundPosition을 구하는 api를 만들 필요가 있어서 추가 기능 구현 - PlaygroundController.playgroundPositions : playground id 값을 전달받아 해당 playground의 playgroundPosition을 전달하는 엔드포인트 - playgroundController.positions : 포지션 이늄값 리스트 전달하는 메서드 --- .../controller/PlaygroundController.java | 15 +++++++++++++++ .../domain/PlaygroundPosition.java | 6 +++--- .../programmerground/domain/PositionLanguage.java | 5 ++++- .../service/PlaygroundService.java | 11 +++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java index b559520..74d1690 100644 --- a/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java +++ b/Backend/src/main/java/com/pg/programmerground/controller/PlaygroundController.java @@ -1,6 +1,8 @@ package com.pg.programmerground.controller; import com.pg.programmerground.controller.response.ApiResponse; +import com.pg.programmerground.domain.enumerated.Position; +import com.pg.programmerground.dto.playground.PlaygroundPositionsDto; import com.pg.programmerground.dto.playground.api_req.ApplyPlaygroundApi; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.dto.playground.api_req.RevisePlaygroundApi; @@ -42,6 +44,13 @@ public ResponseEntity> createPlayground(@RequestPart(required return ResponseEntity.ok().body(new ApiResponse<>(playgroundService.createPlayground(mainImg, info))); } + @ApiOperation(value = "PlaygroundPosition 리스트 정보", notes = "PlaygroundPosition 리스트 정보 요청") + @GetMapping("/{playgroundId}/slots") + public ResponseEntity> playgroundPositions(@PathVariable Long playgroundId) { + return ResponseEntity.ok() + .body(new ApiResponse<>(playgroundService.getPlaygroundPositions(playgroundId))); + } + @ApiOperation(value = "Playground 참가 신청", notes = "Playground 참가 신청 요청") @PostMapping("/{playgroundId}/apply") public ResponseEntity> applyPlayground(@PathVariable Long playgroundId, @RequestBody @Validated ApplyPlaygroundApi applyPlayground) { @@ -106,4 +115,10 @@ public ResponseEntity applyCollaborators( @Valid @RequestBody String repoTitle) { return ResponseEntity.ok().body(playgroundService.applyCollaboratorPlaygroundGithubRepo(playgroundId, repoTitle)); } + + @ApiOperation(value = "참여 신청할 Position 리스트 정보", notes = "PlaygroundPostion 리스트 정보 요청") + @GetMapping("/positions") + public ResponseEntity positions() { + return ResponseEntity.ok().body(Position.toEntity()); + } } diff --git a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java index 05a279b..a7e7a96 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/PlaygroundPosition.java @@ -40,13 +40,13 @@ public class PlaygroundPosition extends BaseTimeEntity { @Column(name = "POSITION_LEVEL") private PositionLevel positionLevel; - @OneToMany(mappedBy = "playgroundPosition", cascade = CascadeType.ALL, orphanRemoval = true) - private List playgroundApply = new ArrayList<>(); - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PLAYGROUND_ID") private Playground playground; + @OneToMany(mappedBy = "playgroundPosition", cascade = CascadeType.ALL, orphanRemoval = true) + private List playgroundApply = new ArrayList<>(); + @OneToMany(mappedBy = "playgroundPosition", cascade = CascadeType.ALL, orphanRemoval = true) private List positionLanguageList = new ArrayList<>(); diff --git a/Backend/src/main/java/com/pg/programmerground/domain/PositionLanguage.java b/Backend/src/main/java/com/pg/programmerground/domain/PositionLanguage.java index 971854d..7184663 100644 --- a/Backend/src/main/java/com/pg/programmerground/domain/PositionLanguage.java +++ b/Backend/src/main/java/com/pg/programmerground/domain/PositionLanguage.java @@ -2,7 +2,10 @@ import com.pg.programmerground.domain.enumerated.Language; import com.pg.programmerground.dto.playground.api_req.PositionLanguageApi; -import lombok.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import javax.persistence.*; import java.util.List; diff --git a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java index 1046656..967905f 100644 --- a/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java +++ b/Backend/src/main/java/com/pg/programmerground/service/PlaygroundService.java @@ -7,6 +7,7 @@ import com.pg.programmerground.domain.PlaygroundPosition; import com.pg.programmerground.domain.enumerated.ApplyStatus; import com.pg.programmerground.dto.UploadImg; +import com.pg.programmerground.dto.playground.PlaygroundPositionsDto; import com.pg.programmerground.dto.playground.api_req.ApplyPlaygroundApi; import com.pg.programmerground.dto.playground.api_req.PlaygroundApi; import com.pg.programmerground.dto.playground.response.PlaygroundCardResponse; @@ -85,6 +86,16 @@ public Long applyPlayground(Long playgroundId, ApplyPlaygroundApi applyPlaygroun return playgroundApply.getId(); } + /** + * Playground에 등록되어있는 PlaygroundPosition + */ + public PlaygroundPositionsDto getPlaygroundPositions(Long playgroundId) { + List playgroundPositions = playgroundRepository.findById(playgroundId) + .orElseThrow(() -> new NoSuchElementException("존재하지 않는 Playground 입니다.")) + .getPlaygroundPositionList(); + return new PlaygroundPositionsDto(playgroundPositions); + } + /** * Playground 신청 취소 */ From 0a2c1325d5fc4885c581c90e54550274bd5a0cc1 Mon Sep 17 00:00:00 2001 From: dailyworker Date: Sat, 11 Sep 2021 15:11:41 +0900 Subject: [PATCH 098/176] [#133] feat : PlaygroundPositionDto, PlaygroundPositionsDto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - dto 구현 --- .../dto/playground/PlayGroundPositionDto.java | 41 +++++++++++++++++++ .../playground/PlaygroundPositionsDto.java | 30 ++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 Backend/src/main/java/com/pg/programmerground/dto/playground/PlayGroundPositionDto.java create mode 100644 Backend/src/main/java/com/pg/programmerground/dto/playground/PlaygroundPositionsDto.java diff --git a/Backend/src/main/java/com/pg/programmerground/dto/playground/PlayGroundPositionDto.java b/Backend/src/main/java/com/pg/programmerground/dto/playground/PlayGroundPositionDto.java new file mode 100644 index 0000000..d590793 --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/dto/playground/PlayGroundPositionDto.java @@ -0,0 +1,41 @@ +package com.pg.programmerground.dto.playground; + +import com.pg.programmerground.domain.enumerated.Position; +import com.pg.programmerground.domain.enumerated.PositionLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class PlayGroundPositionDto { + private Long id; + private Position position; + private int maxPositionNum; + private int currentPositionNum; + private PositionLevel positionLevel; + private boolean fullPosition; + private LocalDateTime createdAt; + private LocalDateTime modifiedAt; + + @Builder + public PlayGroundPositionDto(Long id, + Position position, + int maxPositionNum, + int currentPositionNum, + PositionLevel positionLevel, + boolean fullPosition, + LocalDateTime createdAt, + LocalDateTime modifiedAt) { + this.id = id; + this.position = position; + this.maxPositionNum = maxPositionNum; + this.currentPositionNum = currentPositionNum; + this.positionLevel = positionLevel; + this.fullPosition = fullPosition; + this.createdAt = createdAt; + this.modifiedAt = modifiedAt; + }; +} diff --git a/Backend/src/main/java/com/pg/programmerground/dto/playground/PlaygroundPositionsDto.java b/Backend/src/main/java/com/pg/programmerground/dto/playground/PlaygroundPositionsDto.java new file mode 100644 index 0000000..e6abb2a --- /dev/null +++ b/Backend/src/main/java/com/pg/programmerground/dto/playground/PlaygroundPositionsDto.java @@ -0,0 +1,30 @@ +package com.pg.programmerground.dto.playground; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.pg.programmerground.domain.PlaygroundPosition; +import lombok.Getter; + +import java.util.List; +import java.util.stream.Collectors; + +@Getter +public class PlaygroundPositionsDto { + @JsonProperty("playground_positions") + private final List playgroundPositions; + + public PlaygroundPositionsDto(List playgroundPositions) { + this.playgroundPositions = playgroundPositions.stream() + .map(element -> { + return PlayGroundPositionDto.builder() + .id(element.getId()) + .position(element.getPosition()) + .maxPositionNum(element.getMaxPositionNum()) + .currentPositionNum(element.getCurrentPositionNum()) + .positionLevel(element.getPositionLevel()) + .fullPosition(element.isFullPosition()) + .createdAt(element.getCreatedAt()) + .modifiedAt(element.getModifiedAt()) + .build(); + }).collect(Collectors.toList()); + } +} From eec831172e80f76a2be58911a9e008834f317621 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Tue, 21 Sep 2021 11:58:15 +0900 Subject: [PATCH 099/176] =?UTF-8?q?#128=20=EC=95=8C=EB=A6=BC=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20ui=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/otherUI/index.tsx | 54 ++++++++++++++++- Frontend/src/components/otherUI/style.ts | 72 +++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/Frontend/src/components/otherUI/index.tsx b/Frontend/src/components/otherUI/index.tsx index 7fd8fd0..b4e287b 100644 --- a/Frontend/src/components/otherUI/index.tsx +++ b/Frontend/src/components/otherUI/index.tsx @@ -1,6 +1,8 @@ -import React from 'react'; +// @ts-nocheck +import React, {useState, useEffect} from 'react'; import { useHistory } from 'react-router-dom'; import * as StyledComponent from './style'; +import {getPositionList} from '@src/lib/axios/playground'; interface playground { playgroundTitle: string; @@ -20,7 +22,36 @@ const OtherUI = ({ }: playground) => { const colors = ['red', 'yellow', 'blue', 'green', 'purple', 'pink']; const history = useHistory(); + const [isShow, setIsShow] = useState(false); + const [list, setPositionList] = useState([]); + const [issue, setIssueList] = useState([]); + const applyHandler = async () => { + setIsShow(true); + } + + const onClose = () => { + setIsShow(false); + } + + const handleCheckboxChange = ( positionList:any, list: any) => { + const newItem = list.map((v:boolean) => !v); + setPositionList({ + positionList, + checkedList: newItem + }); + } + + useEffect(()=> { + const getData = async () => { + const data = await getPositionList(id); + setPositionList({ + positionList: data.playground_positions, + checkedList: new Array(data.playground_positions.length).fill(false) + }) + } + getData(); + },[]); return ( @@ -90,8 +121,27 @@ const OtherUI = ({ - 참가 요청하기 + 참가 요청하기 + {isShow && + + + + 포지션 리스트 - 원하는 포지션을 체크해주세요! + X + + + {list.positionList.map((v,i)=> { + return ( + <> + + handleCheckboxChange(list.positionList, list.checkedList)}>{v.position} + + ) + })} + + + } ); }; diff --git a/Frontend/src/components/otherUI/style.ts b/Frontend/src/components/otherUI/style.ts index 82e886b..357031c 100644 --- a/Frontend/src/components/otherUI/style.ts +++ b/Frontend/src/components/otherUI/style.ts @@ -19,6 +19,7 @@ export const ApplyButton = styled.button.attrs((_props) => ({ `; export const ApplyMainContainer = styled.div` + position: relative; padding-top: 150px; width: 960px; margin: 0 auto; @@ -128,3 +129,74 @@ export const ApplyContentLanguageLabel = styled.span` padding: 5px; color: #fff; `; + +export const ApplyModalContainer = styled.div` + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(0, 0, 0, 0.7); +`; + +export const ApplyModalContent = styled.div` + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; + border-radius: 1px; +`; + +export const ApplyModalHead = styled.div` + display: flex; + padding: 15px; +`; + +export const ApplyModalTitle = styled.strong` + flex: 1 1 auto; + font-size: 20px; + line-height: 35px; + font-weight: normal; + + &:not(:last-child) { + margin-right: 10px; + } +`; + +export const ApplyModalButton = styled.button.attrs((props) => { + type: 'button' +})` + flex: 1 1 auto; + padding: 10px; + border: none; + background-color: transparent; + cursor: pointer; +`; + +export const ApplyModalBody = styled.div` + &:not(:first-child) { + margin-top: 20px; + } + padding: 0 15px; +`; + +export const ApplyModalInput = styled.input.attrs((props) => { + type: 'checkbox' +})` + clip: rect(0 0 0 0); + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + overflow: hidden; + +`; + +export const ApplyModalLabel = styled.label.attrs((props) => { + +})` + width: 100%; + height: 40px; + background-color: ${props=> props.checkState? '#4c90dd' : '#fff'} +`; \ No newline at end of file From 2135a52fd9882189dff89ebb844f3ee77bba04f9 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Tue, 21 Sep 2021 11:58:40 +0900 Subject: [PATCH 100/176] =?UTF-8?q?#128=20feat:=20position=20api=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 687c19e..0e3c2bf 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -10,6 +10,7 @@ const url = { GET_ONE_USER: 'http://localhost:9000/user', PATCH_ONE_USER: 'http://localhost:9000/user', DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', + GET_POSITION_LIST:'http://localhost:9000/playground/' }; // eslint-disable-next-line import/prefer-default-export @@ -45,4 +46,9 @@ export const deleteOnePlayground = async (playgroundId: number) => { export const patchOneUser = async(userName: string, type:string) => { const user = await patchData(`${url.PATCH_ONE_USER}`, userName, type); return user; +} + +export const getPositionList = async (playgroundId: number) => { + const positionList = await getData(`${url.GET_POSITION_LIST}${playgroundId}/slots`); + return positionList; } \ No newline at end of file From 9c9346a7666bbe26dc798ad35d68a78318e86439 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Tue, 21 Sep 2021 12:12:57 +0900 Subject: [PATCH 101/176] =?UTF-8?q?#128=20style:=20position=20ui=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/otherUI/style.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Frontend/src/components/otherUI/style.ts b/Frontend/src/components/otherUI/style.ts index 357031c..7adc9e0 100644 --- a/Frontend/src/components/otherUI/style.ts +++ b/Frontend/src/components/otherUI/style.ts @@ -178,7 +178,7 @@ export const ApplyModalBody = styled.div` &:not(:first-child) { margin-top: 20px; } - padding: 0 15px; + padding: 0 15px 15px; `; export const ApplyModalInput = styled.input.attrs((props) => { @@ -196,7 +196,14 @@ export const ApplyModalInput = styled.input.attrs((props) => { export const ApplyModalLabel = styled.label.attrs((props) => { })` - width: 100%; + display: inline-block; + width: 33.3%; height: 40px; + line-height: 40px; + padding: 0 2px; + box-sizing: border-box; + text-align: center; + border: 1px solid #d9d9d9; + color: ${props=> props.checkState? '#fff': '#515254'}; background-color: ${props=> props.checkState? '#4c90dd' : '#fff'} `; \ No newline at end of file From f5e441bdbdc38ef1c5c28d91a4990d9da578cccd Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 15:37:24 +0900 Subject: [PATCH 102/176] =?UTF-8?q?#128=20style:=20position=20ui=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=8B=A0=EC=B2=AD=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/otherUI/style.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Frontend/src/components/otherUI/style.ts b/Frontend/src/components/otherUI/style.ts index 7adc9e0..2dc49e7 100644 --- a/Frontend/src/components/otherUI/style.ts +++ b/Frontend/src/components/otherUI/style.ts @@ -178,7 +178,7 @@ export const ApplyModalBody = styled.div` &:not(:first-child) { margin-top: 20px; } - padding: 0 15px 15px; + padding: 0 15px 30px; `; export const ApplyModalInput = styled.input.attrs((props) => { @@ -204,6 +204,19 @@ export const ApplyModalLabel = styled.label.attrs((props) => { box-sizing: border-box; text-align: center; border: 1px solid #d9d9d9; + cursor: pointer; color: ${props=> props.checkState? '#fff': '#515254'}; background-color: ${props=> props.checkState? '#4c90dd' : '#fff'} +`; + +export const ApplyModalSubmitButton = styled.button` + background-color: #4c94e8; + width: 100%; + text-align: center; + color: #fff; + font-weight: 700; + height: 45px; + line-height: 45px; + border: 0; + cursor: pointer; `; \ No newline at end of file From 23823afd53177d2374e009f5478437c572a482bc Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 15:37:45 +0900 Subject: [PATCH 103/176] =?UTF-8?q?#128=20feat:=20position=20ui=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=8B=A0=EC=B2=AD=20api=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/otherUI/index.tsx | 12 ++++++++++-- Frontend/src/lib/axios/playground.ts | 8 +++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Frontend/src/components/otherUI/index.tsx b/Frontend/src/components/otherUI/index.tsx index b4e287b..20b1df2 100644 --- a/Frontend/src/components/otherUI/index.tsx +++ b/Frontend/src/components/otherUI/index.tsx @@ -2,7 +2,7 @@ import React, {useState, useEffect} from 'react'; import { useHistory } from 'react-router-dom'; import * as StyledComponent from './style'; -import {getPositionList} from '@src/lib/axios/playground'; +import {getPositionList, createApplyRequest} from '@src/lib/axios/playground'; interface playground { playgroundTitle: string; @@ -24,7 +24,6 @@ const OtherUI = ({ const history = useHistory(); const [isShow, setIsShow] = useState(false); const [list, setPositionList] = useState([]); - const [issue, setIssueList] = useState([]); const applyHandler = async () => { setIsShow(true); @@ -42,6 +41,14 @@ const OtherUI = ({ }); } + const handleApply = (e: any) => { + const positionItemIndex = list.checkedList.indexOf(true); + const applyPlayground = { + position_id : positionItemIndex + } + createApplyRequest(applyPlayground, id); + } + useEffect(()=> { const getData = async () => { const data = await getPositionList(id); @@ -140,6 +147,7 @@ const OtherUI = ({ ) })} + handleApply(e)}>적용 } diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 0e3c2bf..1fa2a93 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -10,7 +10,8 @@ const url = { GET_ONE_USER: 'http://localhost:9000/user', PATCH_ONE_USER: 'http://localhost:9000/user', DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', - GET_POSITION_LIST:'http://localhost:9000/playground/' + GET_POSITION_LIST:'http://localhost:9000/playground/', + APPLY_PLAYGROUND: 'http://localhost:9000/playground/' }; // eslint-disable-next-line import/prefer-default-export @@ -51,4 +52,9 @@ export const patchOneUser = async(userName: string, type:string) => { export const getPositionList = async (playgroundId: number) => { const positionList = await getData(`${url.GET_POSITION_LIST}${playgroundId}/slots`); return positionList; +} + +export const createApplyRequest = async (applyPlayground: any, playgroundId: number) => { + const createApply = await postData(`${url.APPLY_PLAYGROUND}${playgroundId}/apply`, applyPlayground, 'apply'); + return createApply; } \ No newline at end of file From 7277725429d213f21a93eba6c3321b887612d550 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 16:07:59 +0900 Subject: [PATCH 104/176] =?UTF-8?q?#128=20feat:=20=EC=8B=A0=EC=B2=AD=20api?= =?UTF-8?q?=20=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C=20=EB=B0=8F=20histor?= =?UTF-8?q?y=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/otherUI/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Frontend/src/components/otherUI/index.tsx b/Frontend/src/components/otherUI/index.tsx index 20b1df2..818262c 100644 --- a/Frontend/src/components/otherUI/index.tsx +++ b/Frontend/src/components/otherUI/index.tsx @@ -44,9 +44,10 @@ const OtherUI = ({ const handleApply = (e: any) => { const positionItemIndex = list.checkedList.indexOf(true); const applyPlayground = { - position_id : positionItemIndex + position_id : list.positionList[positionItemIndex].id } createApplyRequest(applyPlayground, id); + history.push('/'); } useEffect(()=> { From 7082538b79ee0676c4d78fca0a9d73bc6824c81e Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 17:14:51 +0900 Subject: [PATCH 105/176] =?UTF-8?q?#135=20feat:=20leader=20=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=A1=B0=ED=9A=8C=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 29 ++++++++++++++++++++++-- Frontend/src/lib/axios/playground.ts | 6 +++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index b490d60..6e90cb3 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -1,16 +1,17 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import * as StyledComponent from './style'; import './headerImage.scss'; import useCookie from '@src/hooks/useCookie'; import { useHistory } from 'react-router-dom'; -import { getOneUser } from '@src/lib/axios/playground'; +import { getOneUser, getNoticeLeaderList } from '@src/lib/axios/playground'; const Header = () => { const [isAlarm, setAlarm] = useState(false); const [isUser, setUser] = useState(false); const [info, setInfo] = useState(false); + const [noticeItem, setNoticeItem] = useState([]); const history = useHistory(); const userClickHandler = (e: any) => { @@ -42,6 +43,14 @@ const Header = () => { state: { userData }, }); }; + + useEffect(() => { + const getData = async () => { + const noticeData = await getNoticeLeaderList(); + setNoticeItem(noticeData.user_notice); + } + getData(); + }, []); return ( <> @@ -101,6 +110,22 @@ const Header = () => { 닫기 + + {noticeItem.map((v,i)=> { + return ( + + {v.playground_title} + + + {v.user_name} + 님 + {v.position} + + + ) + })} + + )} diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 1fa2a93..d3f2c65 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -12,6 +12,7 @@ const url = { DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', GET_POSITION_LIST:'http://localhost:9000/playground/', APPLY_PLAYGROUND: 'http://localhost:9000/playground/' + GET_NOTICE_LEADER: 'http://localhost:9000/user/notices/leader' }; // eslint-disable-next-line import/prefer-default-export @@ -57,4 +58,9 @@ export const getPositionList = async (playgroundId: number) => { export const createApplyRequest = async (applyPlayground: any, playgroundId: number) => { const createApply = await postData(`${url.APPLY_PLAYGROUND}${playgroundId}/apply`, applyPlayground, 'apply'); return createApply; +} + +export const getNoticeLeaderList = async () => { + const noticeList = await getData(`${url.GET_NOTICE_LEADER}`); + return noticeList; } \ No newline at end of file From af5ac5bf1e3176aefc2d796f7d98319a09ccff0a Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 17:15:16 +0900 Subject: [PATCH 106/176] =?UTF-8?q?#135=20refactor:=20console.log=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/pages/PlaygroundIdPage/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/Frontend/src/pages/PlaygroundIdPage/index.tsx b/Frontend/src/pages/PlaygroundIdPage/index.tsx index 4825984..045823e 100644 --- a/Frontend/src/pages/PlaygroundIdPage/index.tsx +++ b/Frontend/src/pages/PlaygroundIdPage/index.tsx @@ -15,7 +15,6 @@ const PlaygroundIdPage = () => { positionList, id, } = location.state as any; - console.log(id, loginUserName, data, playgroundTitle); return ( <>
From d2faddf933d135e9ac35a2caa0d78dcff3856a6e Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Wed, 22 Sep 2021 17:15:50 +0900 Subject: [PATCH 107/176] =?UTF-8?q?#135=20style:=20=EC=95=8C=EB=A6=BC=20li?= =?UTF-8?q?st=20css=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/style.ts | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index 3e49d84..2cfc3f5 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -151,3 +151,52 @@ export const InfoTitleName = styled.span` } `; export const UserProfileLink = styled.a``; + +export const InfoBodyContainer = styled.div` + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyContent = styled.div` + padding: 4px 16px; + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyTitle = styled.strong` + font-weight: normal; + +`; + +export const InfoBodyAuthor = styled.div` + &:not(:first-child) { + margin-top: 4px; + } +`; + +export const InfoAuthorName = styled.span` + font-size: 5px; + &:not(:last-child) { + margin-right: 5px; + } +`; + +export const InfoNameEmphasis = styled.em` + font-weight: normal; + color: #0abe16; +`; + + +export const InfoAuthorPosition = styled.span` + &::before { + content: ''; + margin: 0 5px 2px 0; + display: inline-block; + width: 2px; + height: 2px; + background-color: #000; + } + font-size: 5px; +`; \ No newline at end of file From b76f48da14bd518bf0ceba4effbc12af12727796 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 23 Sep 2021 15:56:10 +0900 Subject: [PATCH 108/176] =?UTF-8?q?#137=20style:=20playground=20leader=20?= =?UTF-8?q?=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88=20=EB=B2=84=ED=8A=BC=20ui?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 22 ++++++++----- Frontend/src/components/header/style.ts | 40 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index 6e90cb3..6655fb9 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -114,13 +114,21 @@ const Header = () => { {noticeItem.map((v,i)=> { return ( - {v.playground_title} - - - {v.user_name} - 님 - {v.position} - + + + {v.playground_title} + + + {v.user_name} + 님 + {v.position} + + + + 수락 + 거절 + + ) })} diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index 2cfc3f5..a26a371 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -199,4 +199,44 @@ export const InfoAuthorPosition = styled.span` background-color: #000; } font-size: 5px; +`; + +export const InfoAuthorContainer = styled.div` + display: flex; +`; + +export const InfoContainerItem = styled.div` + flex: 1 1 auto; + &:not(:last-child) { + margin-right: 10px; + } + &:not(:first-child) { + line-height: 40px; + } +`; + +export const InfoAcceptButton = styled.button` + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoRejectButton = styled.button` + &:not(:first-child) { + margin-left: 5px; + } + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + &:hover { + color: #fff; + background-color: #00bcd4; + } `; \ No newline at end of file From 2070e7aa877a3349e8717d3b4baaeb5f8ef4e5c1 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 23 Sep 2021 16:53:46 +0900 Subject: [PATCH 109/176] =?UTF-8?q?#139=20style:=20playground=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EB=A9=94=EB=89=B4=20ui=20=EC=B0=BD=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 11 ++++++++++- Frontend/src/components/header/style.ts | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index 6655fb9..bb56b0b 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -12,6 +12,7 @@ const Header = () => { const [isUser, setUser] = useState(false); const [info, setInfo] = useState(false); const [noticeItem, setNoticeItem] = useState([]); + const [menu, setMenu] = useState(1); const history = useHistory(); const userClickHandler = (e: any) => { @@ -44,6 +45,9 @@ const Header = () => { }); }; + const changeScreen = (e:any) => { + } + useEffect(() => { const getData = async () => { const noticeData = await getNoticeLeaderList(); @@ -102,6 +106,11 @@ const Header = () => { {info && ( + + changeScreen(e)}>신청목록 + changeScreen(e)}>결과목록 + changeScreen(e)}>대기목록 + My Alarm Info @@ -111,7 +120,7 @@ const Header = () => { - {noticeItem.map((v,i)=> { + {noticeItem.map((v,i)=> { return ( diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index a26a371..df5cc49 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -133,6 +133,16 @@ export const InfoMenu = styled.div` animation: ${infoKeyframes} 1s forwards; `; +export const InfoMenuList = styled.div` + padding: 8px 15px; +`; + +export const InfoMenuLink = styled.a` + display: inline-block; + padding: 5px 15px; + cursor: pointer; +`; + export const InfoTitleContainer = styled.div` display: flex; padding: 8px 16px; From 482f73ec0762a01c99f6fb81a210a1b136387266 Mon Sep 17 00:00:00 2001 From: CJW23 Date: Thu, 23 Sep 2021 16:57:59 +0900 Subject: [PATCH 110/176] =?UTF-8?q?feat:=20API=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/user/response/UserApplyNoticeResponse.java | 5 ++++- .../dto/user/response/UserLeaderNoticeResponse.java | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java index 7ce7dc7..21205f1 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserApplyNoticeResponse.java @@ -7,6 +7,7 @@ import lombok.Builder; import lombok.Getter; +import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -20,6 +21,7 @@ public class UserApplyNoticeResponse { private final Long playgroundApplyId; private final String position; private final ApplyStatus status; + private final LocalDateTime date; public static List ofList(List playgroundApplyList) { return playgroundApplyList.stream() @@ -27,7 +29,8 @@ public static List ofList(List playgro .playgroundTitle(playgroundApply.getPlayground().getTitle()) .playgroundApplyId(playgroundApply.getId()) .status(playgroundApply.getApplyStatus()) - .position(playgroundApply.getPlaygroundPosition().getPosition().name()).build()) + .position(playgroundApply.getPlaygroundPosition().getPosition().name()) + .date(playgroundApply.getCreatedAt()).build()) .collect(Collectors.toList()); } } diff --git a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserLeaderNoticeResponse.java b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserLeaderNoticeResponse.java index c52d0e1..fc377fe 100644 --- a/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserLeaderNoticeResponse.java +++ b/Backend/src/main/java/com/pg/programmerground/dto/user/response/UserLeaderNoticeResponse.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Getter; +import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -20,6 +21,8 @@ public class UserLeaderNoticeResponse { private final String position; @JsonProperty(value = "user_name") private final String userName; + private final LocalDateTime date; + public static List ofList(List playgroundApplyList) { return playgroundApplyList.stream() @@ -28,6 +31,7 @@ public static List ofList(List playgr .playgroundTitle(playgroundApply.getPlayground().getTitle()) .userName(playgroundApply.getUser().getUserName()) .position(playgroundApply.getPlaygroundPosition().getPosition().name()) + .date(playgroundApply.getCreatedAt()) .build()) .collect(Collectors.toList()); } From 54d456f49c1003c759c9fea40522ebc8c45c1bf8 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 23 Sep 2021 17:09:19 +0900 Subject: [PATCH 111/176] =?UTF-8?q?#138=20feat:=20playground=20=EC=88=98?= =?UTF-8?q?=EB=9D=BD/=EC=82=AD=EC=A0=9C=20api=20=ED=8B=80=20=EC=A0=9C?= =?UTF-8?q?=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index d3f2c65..d65063c 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -11,8 +11,10 @@ const url = { PATCH_ONE_USER: 'http://localhost:9000/user', DELETE_ONE_PLAYGROUND: 'http://localhost:9000/playground/', GET_POSITION_LIST:'http://localhost:9000/playground/', - APPLY_PLAYGROUND: 'http://localhost:9000/playground/' - GET_NOTICE_LEADER: 'http://localhost:9000/user/notices/leader' + APPLY_PLAYGROUND: 'http://localhost:9000/playground/', + GET_NOTICE_LEADER: 'http://localhost:9000/user/notices/leader', + PUT_APPLY_ACCEPT: 'http://localhost:9000/playground/applicants/', + PUT_APPLY_REJECT: 'http://localhost:9000/playground/applicants/' }; // eslint-disable-next-line import/prefer-default-export @@ -63,4 +65,12 @@ export const createApplyRequest = async (applyPlayground: any, playgroundId: num export const getNoticeLeaderList = async () => { const noticeList = await getData(`${url.GET_NOTICE_LEADER}`); return noticeList; +export const applyAcceptPlayground = async (playgroundApplyId: number) => { + const acceptPlayground = await putData(`${url.PUT_APPLY_ACCEPT}/${playgroundApplyId}/accept`); + return acceptPlayground; +} + +export const applyRejectPlayground = async (playgroundApplyId: number) => { + const rejectPlayground = await putData(`${url.PUT_APPLY_REJECT}/${playgroundApplyId}/reject`); + return rejectPlayground; } \ No newline at end of file From c158c46650924d8ccf928b76ff49fcb819d6bc8a Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 23 Sep 2021 17:10:22 +0900 Subject: [PATCH 112/176] =?UTF-8?q?#140=20feat:=20playground=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC/=EB=8C=80=EA=B8=B0=20api=20=ED=8B=80=20=EC=A0=9C?= =?UTF-8?q?=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index d65063c..8513549 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -1,5 +1,3 @@ -import { AxiosResponse } from 'axios'; -import { getOptions } from '@src/lib/api'; import { getData, patchData, postData, putData, deleteData } from './request'; const url = { @@ -13,8 +11,11 @@ const url = { GET_POSITION_LIST:'http://localhost:9000/playground/', APPLY_PLAYGROUND: 'http://localhost:9000/playground/', GET_NOTICE_LEADER: 'http://localhost:9000/user/notices/leader', + GET_NOTICE_WAITING: 'http://localhost:9000/user/notices/waitings', + GET_NOTICE_RESULT: 'http://localhost:9000/user/notices/results', PUT_APPLY_ACCEPT: 'http://localhost:9000/playground/applicants/', PUT_APPLY_REJECT: 'http://localhost:9000/playground/applicants/' + }; // eslint-disable-next-line import/prefer-default-export @@ -65,6 +66,18 @@ export const createApplyRequest = async (applyPlayground: any, playgroundId: num export const getNoticeLeaderList = async () => { const noticeList = await getData(`${url.GET_NOTICE_LEADER}`); return noticeList; +} + +export const getNoticeWaitingList = async () => { + const waitList = await getData(`${url.GET_NOTICE_WAITING}`); + return waitList; +} + +export const getNoticeResult = async () => { + const resultList = await getData(`${url.GET_NOTICE_RESULT}`); + return resultList; +} + export const applyAcceptPlayground = async (playgroundApplyId: number) => { const acceptPlayground = await putData(`${url.PUT_APPLY_ACCEPT}/${playgroundApplyId}/accept`); return acceptPlayground; From d5de519024861915e86f41fcb799d7ec6072cfb4 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Fri, 24 Sep 2021 18:09:19 +0900 Subject: [PATCH 113/176] =?UTF-8?q?#136=20style:=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 5 +++- Frontend/src/components/header/style.ts | 29 +++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index bb56b0b..ec5842b 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -125,7 +125,10 @@ const Header = () => { - {v.playground_title} + + {v.playground_title} + {v.date.toString().slice(0, 10)} + {v.user_name} diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index df5cc49..c04cab9 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -177,7 +177,19 @@ export const InfoBodyContent = styled.div` export const InfoBodyTitle = styled.strong` font-weight: normal; + position: relative; + &::after { + position: absolute; + bottom: 1px; + left: 0; + width: 100%; + height: 7px; + background-color: #78ffe0; + opacity: 0.5; + content: ''; + + } `; export const InfoBodyAuthor = styled.div` @@ -249,4 +261,19 @@ export const InfoRejectButton = styled.button` color: #fff; background-color: #00bcd4; } -`; \ No newline at end of file +`; + +export const InfoTitleBody = styled.div` + display: flex; +`; + +export const InfoBodyDate = styled.span` + &:not(:first-child) { + margin-left: auto; + padding-top: 3px; + } + + font-size: 10px; + line-height: 15px; +`; + From 79147834ca89fb724bd1a735e8ef4952bd463476 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Fri, 24 Sep 2021 18:15:31 +0900 Subject: [PATCH 114/176] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=86=8D=EC=84=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 1 - Frontend/src/components/header/style.ts | 4 ---- Frontend/src/components/playgroundContent/index.tsx | 6 +----- Frontend/src/hooks/useCookie.ts | 1 - Frontend/src/pages/CreatePage/index.tsx | 6 +----- Frontend/src/pages/PlayGroundPage/index.tsx | 6 +++--- Frontend/src/pages/PlaygroundIdPage/index.tsx | 2 +- 7 files changed, 6 insertions(+), 20 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index ec5842b..70e6bdd 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -3,7 +3,6 @@ import React, { useState, useEffect } from 'react'; import * as StyledComponent from './style'; import './headerImage.scss'; -import useCookie from '@src/hooks/useCookie'; import { useHistory } from 'react-router-dom'; import { getOneUser, getNoticeLeaderList } from '@src/lib/axios/playground'; diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index c04cab9..013a1ad 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -1,10 +1,6 @@ /* eslint-disable import/prefer-default-export */ import styled, { createGlobalStyle, keyframes } from 'styled-components'; -import { lightTheme, darkTheme } from '@src/utils/theme'; import logo from '../../assets/programmerground.png'; -import projectIcon from '../../assets/projectIcon.png'; -import alarm from '../../assets/alarm.png'; -import user from '../../assets/user.png'; export const GlobalStyle = createGlobalStyle` body{ diff --git a/Frontend/src/components/playgroundContent/index.tsx b/Frontend/src/components/playgroundContent/index.tsx index 92d4046..c6cac5f 100644 --- a/Frontend/src/components/playgroundContent/index.tsx +++ b/Frontend/src/components/playgroundContent/index.tsx @@ -2,12 +2,9 @@ /* eslint-disable react/jsx-key */ /* eslint-disable react/require-default-props */ /* eslint-disable react/prop-types */ -import React, { useState } from 'react'; +import React from 'react'; import useShow from '@src/hooks/useShow'; -import { useDispatch, useSelector } from 'react-redux'; -import { RootState } from '@src/store/modules'; import { useHistory } from 'react-router-dom'; -import { playgroundModalMode } from '@src/store/modules/modal'; import { getOnePlayground, getOneUser } from '@src/lib/axios/playground'; import { getOnePlaygroundItem } from '@src/store/modules/Playground'; import * as StyledComponent from './style'; @@ -31,7 +28,6 @@ const PlaygroundContent = ({ }: Playground) => { const [show, dispatch] = useShow(); const history = useHistory(); - const [image, setImage] = useState(null); const createModalFunc = async ( playgroundId: number, event: any, diff --git a/Frontend/src/hooks/useCookie.ts b/Frontend/src/hooks/useCookie.ts index 6890517..4f329b4 100644 --- a/Frontend/src/hooks/useCookie.ts +++ b/Frontend/src/hooks/useCookie.ts @@ -1,4 +1,3 @@ -import React, { useState } from 'react'; import { getItem } from '@src/utils/getCookie'; const useCookie = (key: string) => { diff --git a/Frontend/src/pages/CreatePage/index.tsx b/Frontend/src/pages/CreatePage/index.tsx index 7188390..345f0d0 100644 --- a/Frontend/src/pages/CreatePage/index.tsx +++ b/Frontend/src/pages/CreatePage/index.tsx @@ -4,11 +4,10 @@ // @ts-nocheck /* eslint-disable jsx-a11y/label-has-associated-control */ -import HashTag from '@src/components/hashTag'; import React, { useState } from 'react'; import Editor from 'rich-markdown-editor'; import useShow from '@src/hooks/useShow'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import LoadingSpinner from '@src/components/loading'; import { useHistory } from 'react-router-dom'; import { @@ -31,11 +30,8 @@ const CreatePage = () => { const { position } = useSelector((state: RootState) => state.positionReducer); const [loading, setLoading] = useState(false); const [img, setImage] = useState(null); - // 프로젝트 이름 const [title, setTitle] = useState(''); - // 프로젝트 설명 const [description, setDescription] = useState(''); - // 리더 포지션 const [leaderPosition, setLeaderPosition] = useState(''); const plusPosition = () => { diff --git a/Frontend/src/pages/PlayGroundPage/index.tsx b/Frontend/src/pages/PlayGroundPage/index.tsx index c31d4c0..5474415 100644 --- a/Frontend/src/pages/PlayGroundPage/index.tsx +++ b/Frontend/src/pages/PlayGroundPage/index.tsx @@ -5,11 +5,11 @@ /* eslint-disable react/jsx-pascal-case */ /* eslint-disable array-callback-return */ // @ts-nocheck -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect} from 'react'; import Header from '@src/components/header'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import PlaygroundContent from '@src/components/playgroundContent'; -import { getAllPlaygrounds, getOneUser } from '@src/lib/axios/playground'; +import { getAllPlaygrounds} from '@src/lib/axios/playground'; import OnePlaygroundModal from '@src/components/Common/modal/onePlaygroundModal'; import { RootState } from '@src/store/modules'; import { throttling } from '@src/utils/throttle'; diff --git a/Frontend/src/pages/PlaygroundIdPage/index.tsx b/Frontend/src/pages/PlaygroundIdPage/index.tsx index 045823e..275b5da 100644 --- a/Frontend/src/pages/PlaygroundIdPage/index.tsx +++ b/Frontend/src/pages/PlaygroundIdPage/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { useLocation } from 'react-router-dom'; import OtherUI from '@src/components/otherUI/'; import Header from '@src/components/header'; From 68086d2e7cebb25a8ee747e23d43d1f120c69387 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 25 Sep 2021 16:43:07 +0900 Subject: [PATCH 115/176] =?UTF-8?q?#139=20chore:=20=EC=8B=A0=EC=B2=AD=20ui?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/applyList/index.tsx | 49 ++++++++ Frontend/src/components/applyList/style.ts | 118 ++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 Frontend/src/components/applyList/index.tsx create mode 100644 Frontend/src/components/applyList/style.ts diff --git a/Frontend/src/components/applyList/index.tsx b/Frontend/src/components/applyList/index.tsx new file mode 100644 index 0000000..0236ef9 --- /dev/null +++ b/Frontend/src/components/applyList/index.tsx @@ -0,0 +1,49 @@ +import React, {useState, useEffect} from 'react'; +import { getNoticeLeaderList } from '@src/lib/axios/playground'; +import * as StyledComponent from './style'; + +const ApplyList = () => { + + const [noticeItem, setNoticeItem] = useState([]); + + useEffect(() => { + const getData = async () => { + const noticeData = await getNoticeLeaderList(); + setNoticeItem(noticeData.user_notice); + } + getData(); + }, []); + + return ( + <> + {noticeItem.map((v,i)=> { + return ( + + + + + {v.playground_title} + {v.date.toString().slice(0, 10)} + + + + {v.user_name} + 님 + {v.position} + + + + 수락 + 거절 + + + + ) + })} + + ) +} + +export default ApplyList; + + diff --git a/Frontend/src/components/applyList/style.ts b/Frontend/src/components/applyList/style.ts new file mode 100644 index 0000000..d4d93ad --- /dev/null +++ b/Frontend/src/components/applyList/style.ts @@ -0,0 +1,118 @@ +import styled, { createGlobalStyle, keyframes } from 'styled-components'; + + +export const InfoBodyContainer = styled.div` + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyContent = styled.div` + padding: 4px 16px; + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyTitle = styled.strong` + font-weight: normal; + position: relative; + + &::after { + position: absolute; + bottom: 1px; + left: 0; + width: 100%; + height: 7px; + background-color: #78ffe0; + opacity: 0.5; + content: ''; + + } +`; + +export const InfoBodyAuthor = styled.div` + &:not(:first-child) { + margin-top: 4px; + } +`; + +export const InfoAuthorName = styled.span` + font-size: 5px; + &:not(:last-child) { + margin-right: 5px; + } +`; + +export const InfoNameEmphasis = styled.em` + font-weight: normal; + color: #0abe16; +`; + + +export const InfoAuthorPosition = styled.span` + &::before { + content: ''; + margin: 0 5px 2px 0; + display: inline-block; + width: 2px; + height: 2px; + background-color: #000; + } + font-size: 5px; +`; + +export const InfoAuthorContainer = styled.div` + display: flex; +`; + +export const InfoContainerItem = styled.div` + flex: 1 1 auto; + &:not(:last-child) { + margin-right: 10px; + } + &:not(:first-child) { + line-height: 40px; + } +`; + +export const InfoAcceptButton = styled.button` + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoRejectButton = styled.button` + &:not(:first-child) { + margin-left: 5px; + } + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoTitleBody = styled.div` + display: flex; +`; + +export const InfoBodyDate = styled.span` + &:not(:first-child) { + margin-left: auto; + padding-top: 3px; + } + + font-size: 10px; + line-height: 15px; +`; + From 59095151017604aff6528b09fea28400504f47b5 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 25 Sep 2021 16:43:39 +0900 Subject: [PATCH 116/176] =?UTF-8?q?#139=20#140=20chore:=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20api=20=EC=97=B0=EB=8F=99=20=EB=B0=8F=20ui=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/resultList/index.tsx | 39 ++++++ Frontend/src/components/resultList/style.ts | 118 +++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 Frontend/src/components/resultList/index.tsx create mode 100644 Frontend/src/components/resultList/style.ts diff --git a/Frontend/src/components/resultList/index.tsx b/Frontend/src/components/resultList/index.tsx new file mode 100644 index 0000000..197faac --- /dev/null +++ b/Frontend/src/components/resultList/index.tsx @@ -0,0 +1,39 @@ +import React, {useState, useEffect} from 'react'; +import {getNoticeResult} from '@src/lib/axios/playground'; +import * as StyledComponent from './style'; + +const ResultList = () => { + const [resultItem, setResultItem] = useState([]); + useEffect(() => { + const getData = async () => { + const userNoticeList = await getNoticeResult(); + setResultItem(userNoticeList.user_notice); + }; + getData(); + },[]); + + return ( + <> + {resultItem.map((v, i) => { + + + + + {v.playground_title} + {v.date.toString().slice(0, 10)} + + + + {v.user_name} + 님 + {v.position} + + + + + })} + + ) +} + +export default ResultList; \ No newline at end of file diff --git a/Frontend/src/components/resultList/style.ts b/Frontend/src/components/resultList/style.ts new file mode 100644 index 0000000..d4d93ad --- /dev/null +++ b/Frontend/src/components/resultList/style.ts @@ -0,0 +1,118 @@ +import styled, { createGlobalStyle, keyframes } from 'styled-components'; + + +export const InfoBodyContainer = styled.div` + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyContent = styled.div` + padding: 4px 16px; + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyTitle = styled.strong` + font-weight: normal; + position: relative; + + &::after { + position: absolute; + bottom: 1px; + left: 0; + width: 100%; + height: 7px; + background-color: #78ffe0; + opacity: 0.5; + content: ''; + + } +`; + +export const InfoBodyAuthor = styled.div` + &:not(:first-child) { + margin-top: 4px; + } +`; + +export const InfoAuthorName = styled.span` + font-size: 5px; + &:not(:last-child) { + margin-right: 5px; + } +`; + +export const InfoNameEmphasis = styled.em` + font-weight: normal; + color: #0abe16; +`; + + +export const InfoAuthorPosition = styled.span` + &::before { + content: ''; + margin: 0 5px 2px 0; + display: inline-block; + width: 2px; + height: 2px; + background-color: #000; + } + font-size: 5px; +`; + +export const InfoAuthorContainer = styled.div` + display: flex; +`; + +export const InfoContainerItem = styled.div` + flex: 1 1 auto; + &:not(:last-child) { + margin-right: 10px; + } + &:not(:first-child) { + line-height: 40px; + } +`; + +export const InfoAcceptButton = styled.button` + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoRejectButton = styled.button` + &:not(:first-child) { + margin-left: 5px; + } + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoTitleBody = styled.div` + display: flex; +`; + +export const InfoBodyDate = styled.span` + &:not(:first-child) { + margin-left: auto; + padding-top: 3px; + } + + font-size: 10px; + line-height: 15px; +`; + From bfcbc52f1e322681869dee29604a95b71ecf2578 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 25 Sep 2021 16:44:02 +0900 Subject: [PATCH 117/176] =?UTF-8?q?#139=20#140=20chore:=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0=20api=20=EC=97=B0=EB=8F=99=20=EB=B0=8F=20ui=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/waitingList/index.tsx | 39 ++++++ Frontend/src/components/waitingList/style.ts | 118 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 Frontend/src/components/waitingList/index.tsx create mode 100644 Frontend/src/components/waitingList/style.ts diff --git a/Frontend/src/components/waitingList/index.tsx b/Frontend/src/components/waitingList/index.tsx new file mode 100644 index 0000000..9e2983d --- /dev/null +++ b/Frontend/src/components/waitingList/index.tsx @@ -0,0 +1,39 @@ +import React, {useState, useEffect} from 'react'; +import {getNoticeWaitingList} from '@src/lib/axios/playground'; +import * as StyledComponent from './style'; + +const ResultList = () => { + const [resultItem, setResultItem] = useState([]); + useEffect(() => { + const getData = async () => { + const userNoticeWaitingList = await getNoticeWaitingList(); + setResultItem(userNoticeWaitingList.user_notice); + }; + getData(); + },[]); + + return ( + <> + {resultItem.map((v, i) => { + + + + + {v.playground_title} + {v.date.toString().slice(0, 10)} + + + + {v.user_name} + 님 + {v.position} + + + + + })} + + ) +} + +export default ResultList; \ No newline at end of file diff --git a/Frontend/src/components/waitingList/style.ts b/Frontend/src/components/waitingList/style.ts new file mode 100644 index 0000000..d4d93ad --- /dev/null +++ b/Frontend/src/components/waitingList/style.ts @@ -0,0 +1,118 @@ +import styled, { createGlobalStyle, keyframes } from 'styled-components'; + + +export const InfoBodyContainer = styled.div` + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyContent = styled.div` + padding: 4px 16px; + &:not(:first-child) { + border-top: 1px solid #e9e9e9; + } +`; + +export const InfoBodyTitle = styled.strong` + font-weight: normal; + position: relative; + + &::after { + position: absolute; + bottom: 1px; + left: 0; + width: 100%; + height: 7px; + background-color: #78ffe0; + opacity: 0.5; + content: ''; + + } +`; + +export const InfoBodyAuthor = styled.div` + &:not(:first-child) { + margin-top: 4px; + } +`; + +export const InfoAuthorName = styled.span` + font-size: 5px; + &:not(:last-child) { + margin-right: 5px; + } +`; + +export const InfoNameEmphasis = styled.em` + font-weight: normal; + color: #0abe16; +`; + + +export const InfoAuthorPosition = styled.span` + &::before { + content: ''; + margin: 0 5px 2px 0; + display: inline-block; + width: 2px; + height: 2px; + background-color: #000; + } + font-size: 5px; +`; + +export const InfoAuthorContainer = styled.div` + display: flex; +`; + +export const InfoContainerItem = styled.div` + flex: 1 1 auto; + &:not(:last-child) { + margin-right: 10px; + } + &:not(:first-child) { + line-height: 40px; + } +`; + +export const InfoAcceptButton = styled.button` + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoRejectButton = styled.button` + &:not(:first-child) { + margin-left: 5px; + } + border: 1px solid #e9e9e9; + background-color: #fff; + border-radius: 10px; + cursor: pointer; + &:hover { + color: #fff; + background-color: #00bcd4; + } +`; + +export const InfoTitleBody = styled.div` + display: flex; +`; + +export const InfoBodyDate = styled.span` + &:not(:first-child) { + margin-left: auto; + padding-top: 3px; + } + + font-size: 10px; + line-height: 15px; +`; + From 577cbcf743e7923254ad2c30cfc187023e531c61 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Sat, 25 Sep 2021 16:44:40 +0900 Subject: [PATCH 118/176] =?UTF-8?q?#139=20chore:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=84=A0=ED=83=9D=EC=B0=BD=20ui=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/index.tsx | 52 +++++++----------------- Frontend/src/components/header/style.ts | 20 ++++++++- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index 70e6bdd..063f0da 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -4,15 +4,18 @@ import React, { useState, useEffect } from 'react'; import * as StyledComponent from './style'; import './headerImage.scss'; import { useHistory } from 'react-router-dom'; -import { getOneUser, getNoticeLeaderList } from '@src/lib/axios/playground'; +import { getOneUser } from '@src/lib/axios/playground'; +import ApplyList from '@src/components/applyList'; +import ResultList from '@src/components/resultList'; +import WaitingList from '@src/components/waitingList'; const Header = () => { const [isAlarm, setAlarm] = useState(false); const [isUser, setUser] = useState(false); const [info, setInfo] = useState(false); - const [noticeItem, setNoticeItem] = useState([]); const [menu, setMenu] = useState(1); const history = useHistory(); + const textArray = ["신청목록", "결과목록", "대기목록"]; const userClickHandler = (e: any) => { setUser(!isUser); @@ -44,16 +47,10 @@ const Header = () => { }); }; - const changeScreen = (e:any) => { + const changeScreen = (e:any, menuNumber: number) => { + setMenu(menuNumber); } - useEffect(() => { - const getData = async () => { - const noticeData = await getNoticeLeaderList(); - setNoticeItem(noticeData.user_notice); - } - getData(); - }, []); return ( <> @@ -106,9 +103,11 @@ const Header = () => { {info && ( - changeScreen(e)}>신청목록 - changeScreen(e)}>결과목록 - changeScreen(e)}>대기목록 + {textArray.map((v, i) => { + return ( + changeScreen(e, i+1)}>{v} + ) + })} @@ -119,30 +118,9 @@ const Header = () => { - {noticeItem.map((v,i)=> { - return ( - - - - - {v.playground_title} - {v.date.toString().slice(0, 10)} - - - - {v.user_name} - 님 - {v.position} - - - - 수락 - 거절 - - - - ) - })} + {menu === 1 && } + {menu === 2 && } + {menu === 3 && } diff --git a/Frontend/src/components/header/style.ts b/Frontend/src/components/header/style.ts index 013a1ad..724d943 100644 --- a/Frontend/src/components/header/style.ts +++ b/Frontend/src/components/header/style.ts @@ -1,5 +1,5 @@ /* eslint-disable import/prefer-default-export */ -import styled, { createGlobalStyle, keyframes } from 'styled-components'; +import styled, { createGlobalStyle, keyframes , css} from 'styled-components'; import logo from '../../assets/programmerground.png'; export const GlobalStyle = createGlobalStyle` @@ -131,12 +131,28 @@ export const InfoMenu = styled.div` export const InfoMenuList = styled.div` padding: 8px 15px; + text-align: center; `; -export const InfoMenuLink = styled.a` +interface selectedProps { + selected: boolean; +} + +export const InfoMenuLink = styled.a` display: inline-block; padding: 5px 15px; + max-width: 120px; cursor: pointer; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + ${props=> + props.selected && css` + color: #fff; + font-weight: bold; + background-color: #3b7cf5; + ` + } `; export const InfoTitleContainer = styled.div` From bfb3a1159e3b07fac45b3c9a36d1386fa4c85a20 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 30 Sep 2021 20:18:59 +0900 Subject: [PATCH 119/176] =?UTF-8?q?#138=20chore:=20api=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/lib/axios/playground.ts | 4 ++-- Frontend/src/lib/axios/request.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Frontend/src/lib/axios/playground.ts b/Frontend/src/lib/axios/playground.ts index 8513549..951ac05 100644 --- a/Frontend/src/lib/axios/playground.ts +++ b/Frontend/src/lib/axios/playground.ts @@ -79,11 +79,11 @@ export const getNoticeResult = async () => { } export const applyAcceptPlayground = async (playgroundApplyId: number) => { - const acceptPlayground = await putData(`${url.PUT_APPLY_ACCEPT}/${playgroundApplyId}/accept`); + const acceptPlayground = await putData(`${url.PUT_APPLY_ACCEPT}${playgroundApplyId}/accept`); return acceptPlayground; } export const applyRejectPlayground = async (playgroundApplyId: number) => { - const rejectPlayground = await putData(`${url.PUT_APPLY_REJECT}/${playgroundApplyId}/reject`); + const rejectPlayground = await putData(`${url.PUT_APPLY_REJECT}${playgroundApplyId}/reject`); return rejectPlayground; } \ No newline at end of file diff --git a/Frontend/src/lib/axios/request.ts b/Frontend/src/lib/axios/request.ts index 6329bab..355fa82 100644 --- a/Frontend/src/lib/axios/request.ts +++ b/Frontend/src/lib/axios/request.ts @@ -11,6 +11,7 @@ const informError = (error: Error) => { const message = error.message ? error.message : '오류가 발생하여 요청에 실패하였습니다'; + console.info(message); }; export const getOptions = async (type?: string) => { @@ -108,11 +109,10 @@ export const patchData = async (url: string, body: string, type: string) => { } }; -export const putData = async (url: string, body: string) => { +export const putData = async (url: string) => { const options = await getOptions(); - try { - const response = await axios.put(url, body, options); + const response = await axios.put(url, options); return response.data; } catch (error) { informError(error); From 443c979cdc57e640556f82b78907b10c7e6a7bfc Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 30 Sep 2021 20:20:59 +0900 Subject: [PATCH 120/176] =?UTF-8?q?#138=20style:=20=EC=88=98=EB=9D=BD=20?= =?UTF-8?q?=EC=B0=B8=EA=B0=80=20=EA=B1=B0=EC=A0=88=20api=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=EB=A1=9C=EC=A7=81=20=EC=9D=BC=EB=B6=80=20=EC=99=84?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/applyList/index.tsx | 24 ++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Frontend/src/components/applyList/index.tsx b/Frontend/src/components/applyList/index.tsx index 0236ef9..86c7886 100644 --- a/Frontend/src/components/applyList/index.tsx +++ b/Frontend/src/components/applyList/index.tsx @@ -1,5 +1,5 @@ import React, {useState, useEffect} from 'react'; -import { getNoticeLeaderList } from '@src/lib/axios/playground'; +import { getNoticeLeaderList, applyAcceptPlayground, applyRejectPlayground } from '@src/lib/axios/playground'; import * as StyledComponent from './style'; const ApplyList = () => { @@ -14,6 +14,24 @@ const ApplyList = () => { getData(); }, []); + const acceptHandler = async (playgroundApplyId: number) => { + // const applyMessage = confirm('수락하시겠습니까?'); + await applyAcceptPlayground(playgroundApplyId); + + // if (applyMessage) { + // location.href="/"; + // } + } + + const rejectHandler = async (playgroundApplyId: number) => { + const rejectMessage = confirm('거절하시겠습니까?'); + + if (rejectMessage) { + await applyRejectPlayground(playgroundApplyId); + location.href="/"; + } + } + return ( <> {noticeItem.map((v,i)=> { @@ -33,8 +51,8 @@ const ApplyList = () => { - 수락 - 거절 + acceptHandler(v.playground_apply_id)}>수락 + rejectHandler(v.playground_apply_id)}>거절 From 717e8406275f46a467c28e862fbeae5442dfbc28 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 30 Sep 2021 20:21:27 +0900 Subject: [PATCH 121/176] =?UTF-8?q?style:=20=EB=82=B4=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=9C=84=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/components/header/headerImage.scss | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Frontend/src/components/header/headerImage.scss b/Frontend/src/components/header/headerImage.scss index 17a3fae..64af457 100644 --- a/Frontend/src/components/header/headerImage.scss +++ b/Frontend/src/components/header/headerImage.scss @@ -72,14 +72,9 @@ .my_alarm_icon { flex: 1 1 0; - position: relative; - &::before { - position:absolute; - top: -2px; - left: -34px; - margin:-1px 10px 0 0; + margin:-1px 10px 0 -13px; vertical-align: bottom; display: inline-block; content: ''; From c4c4990f3f15e106abe4469f9dd08d49a1ff84c8 Mon Sep 17 00:00:00 2001 From: thdwlsgus0 Date: Thu, 30 Sep 2021 20:22:03 +0900 Subject: [PATCH 122/176] =?UTF-8?q?#142=20style:=20repository=20ui=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend/src/App.tsx | 9 ++- .../Common/modalComponent/index.tsx | 36 +++++++++++ .../components/Common/modalComponent/style.ts | 64 +++++++++++++++++++ Frontend/src/components/header/index.tsx | 24 +++++-- Frontend/src/components/header/style.ts | 2 +- Frontend/src/store/modules/modal.ts | 12 ++++ 6 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 Frontend/src/components/Common/modalComponent/index.tsx create mode 100644 Frontend/src/components/Common/modalComponent/style.ts diff --git a/Frontend/src/App.tsx b/Frontend/src/App.tsx index da45f00..aebe8db 100644 --- a/Frontend/src/App.tsx +++ b/Frontend/src/App.tsx @@ -4,11 +4,15 @@ import LoginPage from '@src/pages/LoginPage'; import PlayGroundPage from '@src/pages/PlayGroundPage'; import CreatePage from '@src/pages/CreatePage'; import PlaygroundIdPage from '@src/pages/PlaygroundIdPage'; -import ModalWrapper from '@src/components/Common/modal'; import ProfilePage from '@src/pages/ProfilePage'; import { GlobalStyle } from './Global'; +import ModalComponent from '@src/components/Common/modalComponent'; +import { useSelector } from 'react-redux'; +import { RootState } from '@src/store/modules/index'; const App = () => { + const { repositoryShow } = useSelector((state: RootState) => state.modalReducer); + return ( <> @@ -21,7 +25,8 @@ const App = () => { - + {repositoryShow && } + ); }; diff --git a/Frontend/src/components/Common/modalComponent/index.tsx b/Frontend/src/components/Common/modalComponent/index.tsx new file mode 100644 index 0000000..b1889ad --- /dev/null +++ b/Frontend/src/components/Common/modalComponent/index.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import * as StyledComponent from './style'; +import useShow from '@src/hooks/useShow'; +import { repositoryModalMode } from '@src/store/modules/modal'; + +interface modalProps { + title: string; + itemList?: [] + state?: boolean, +} + +const ModalComponent:React.FC = ({title, itemList, state}) => { + const [show, dispatch] = useShow(); + + const onClose = (e: React.MouseEvent) => { + dispatch(repositoryModalMode(!state)); + } + + return ( + <> + + + + {title} + X + + {title} + + + + ); +} + +export default ModalComponent; + + diff --git a/Frontend/src/components/Common/modalComponent/style.ts b/Frontend/src/components/Common/modalComponent/style.ts new file mode 100644 index 0000000..d6fc5fc --- /dev/null +++ b/Frontend/src/components/Common/modalComponent/style.ts @@ -0,0 +1,64 @@ +import styled from 'styled-components'; + +export const ModalContainer = styled.div` + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(0, 0, 0, 0.7); +`; + +export const ModalHead = styled.div` + display: flex; + padding: 15px; +`; + +export const ModalContent = styled.div` + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; + border-radius: 1px; +`; + +export const ModalTitle = styled.strong` + flex: 1 1 auto; + font-size: 20px; + line-height: 35px; + font-weight: normal; + + &:not(:last-child) { + margin-right: 10px; + } +`; + +export const ModalBody = styled.div` + &:not(:first-child) { + margin-top: 20px; + } + padding: 0 15px 30px; +`; + +export const ModalButton = styled.button.attrs((props) => { + type: 'button' +})` + flex: 1 1 auto; + padding: 10px; + border: none; + background-color: transparent; + cursor: pointer; +`; + +export const ModalSubmitButton = styled.button` + background-color: #4c94e8; + width: 100%; + text-align: center; + color: #fff; + font-weight: 700; + height: 45px; + line-height: 45px; + border: 0; + cursor: pointer; +`; diff --git a/Frontend/src/components/header/index.tsx b/Frontend/src/components/header/index.tsx index 063f0da..18cfcc2 100644 --- a/Frontend/src/components/header/index.tsx +++ b/Frontend/src/components/header/index.tsx @@ -4,36 +4,48 @@ import React, { useState, useEffect } from 'react'; import * as StyledComponent from './style'; import './headerImage.scss'; import { useHistory } from 'react-router-dom'; +import { useSelector } from 'react-redux'; import { getOneUser } from '@src/lib/axios/playground'; import ApplyList from '@src/components/applyList'; import ResultList from '@src/components/resultList'; import WaitingList from '@src/components/waitingList'; +import { RootState } from '@src/store/modules/index'; +import useShow from '@src/hooks/useShow'; +import { repositoryModalMode } from '@src/store/modules/modal'; const Header = () => { const [isAlarm, setAlarm] = useState(false); const [isUser, setUser] = useState(false); const [info, setInfo] = useState(false); const [menu, setMenu] = useState(1); + const [show, dispatch] = useShow(); + const history = useHistory(); + const { repositoryShow } = useSelector((state: RootState) => state.modalReducer); + const textArray = ["신청목록", "결과목록", "대기목록"]; - const userClickHandler = (e: any) => { + const userClickHandler = (e: React) => { setUser(!isUser); if (isAlarm) setAlarm(!isAlarm); }; - const alarmClickHandler = (e: any) => { + const alarmClickHandler = (e: React) => { setAlarm(!isAlarm); if (isUser) setUser(!isUser); }; - const onClickInfoHandler = (e: any) => { + const onClickInfoHandler = (e:React) => { setInfo(!info); }; - const onClickCloseHandler = (e: any) => { + const onClickCloseHandler = (e:React) => { setInfo(!info); }; + const onClickMakeRepoHandler = (e:React) => { + dispatch(repositoryModalMode(!repositoryShow)); + } + const onLogout = (e) => { document.cookie = `access_token=; Max-Age=0`; document.cookie = `refresh_token=; Max-Age=0`; @@ -88,10 +100,10 @@ const Header = () => { /> {isAlarm && ( - +