From f45de90a466a4230c3161378d03d3ae2b905f7c4 Mon Sep 17 00:00:00 2001 From: waterricecake <91263263+waterricecake@users.noreply.github.com> Date: Thu, 21 Sep 2023 10:37:09 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EB=82=B4=20=EC=97=AC=ED=96=89=20api=20,=20?= =?UTF-8?q?=EA=B3=B5=EC=9C=A0=20api=20=EC=88=98=EC=A0=95=20(#599)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 멤버 단일 여행 조회 api 수정 * refactor: 공유 여행 조회 dto 분리 * refactor: 공유 여행 조회 dto 분리 * refactor: 공개 판단 로직 이동 * style: 코드 컨벤션 적용 --- backend/src/docs/asciidoc/docs.adoc | 3 +- .../response/SharedTripDetailResponse.java | 54 +++++++++++++++++++ .../share/dto/response/WriterResponse.java | 19 +++++++ .../presentation/SharedTripController.java | 8 +-- .../share/service/SharedTripService.java | 21 +++++++- .../main/java/hanglog/trip/domain/Trip.java | 4 ++ .../trip/dto/response/TripDetailResponse.java | 6 ++- .../trip/dto/response/TripResponse.java | 2 +- .../SharedTripControllerTest.java | 26 +++++++-- .../trip/presentation/TripControllerTest.java | 4 ++ 10 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 backend/src/main/java/hanglog/share/dto/response/SharedTripDetailResponse.java create mode 100644 backend/src/main/java/hanglog/share/dto/response/WriterResponse.java diff --git a/backend/src/docs/asciidoc/docs.adoc b/backend/src/docs/asciidoc/docs.adoc index 7a383a885..2dc7e222a 100644 --- a/backend/src/docs/asciidoc/docs.adoc +++ b/backend/src/docs/asciidoc/docs.adoc @@ -296,13 +296,14 @@ include::{snippets}/shared-trip-controller-test/get-shared-trip/path-parameters. ==== 응답 include::{snippets}/shared-trip-controller-test/get-shared-trip/http-response.adoc[] -include::{snippets}/shared-trip-controller-test/get-shared-trip/path-parameters.adoc[] +include::{snippets}/shared-trip-controller-test/get-shared-trip/response-fields.adoc[] === 공유 상태 수정 (PATCH /trips/:tripId/share) ==== 요청 include::{snippets}/shared-trip-controller-test/update-shared-status/http-request.adoc[] include::{snippets}/shared-trip-controller-test/update-shared-status/path-parameters.adoc[] +include::{snippets}/shared-trip-controller-test/update-shared-status/request-fields.adoc[] ==== 응답 include::{snippets}/shared-trip-controller-test/update-shared-status/http-response.adoc[] diff --git a/backend/src/main/java/hanglog/share/dto/response/SharedTripDetailResponse.java b/backend/src/main/java/hanglog/share/dto/response/SharedTripDetailResponse.java new file mode 100644 index 000000000..39cac883f --- /dev/null +++ b/backend/src/main/java/hanglog/share/dto/response/SharedTripDetailResponse.java @@ -0,0 +1,54 @@ +package hanglog.share.dto.response; + +import static hanglog.image.util.ImageUrlConverter.convertNameToUrl; +import static lombok.AccessLevel.PRIVATE; + +import hanglog.city.domain.City; +import hanglog.city.dto.response.CityWithPositionResponse; +import hanglog.trip.domain.Trip; +import hanglog.trip.dto.response.DayLogResponse; +import java.time.LocalDate; +import java.util.List; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = PRIVATE) +public class SharedTripDetailResponse { + + private final Long id; + private final List cities; + private final WriterResponse writer; + private final String title; + private final LocalDate startDate; + private final LocalDate endDate; + private final String description; + private final String imageUrl; + private final String sharedCode; + private final List dayLogs; + + public static SharedTripDetailResponse of(final Trip trip, final List cities) { + final List dayLogResponses = trip.getDayLogs().stream() + .map(DayLogResponse::of) + .toList(); + + final List cityWithPositionResponses = cities.stream() + .map(CityWithPositionResponse::of) + .toList(); + + final String sharedCode = trip.getSharedCode().orElse(null); + + return new SharedTripDetailResponse( + trip.getId(), + cityWithPositionResponses, + WriterResponse.of(trip.getMember()), + trip.getTitle(), + trip.getStartDate(), + trip.getEndDate(), + trip.getDescription(), + convertNameToUrl(trip.getImageName()), + sharedCode, + dayLogResponses + ); + } +} diff --git a/backend/src/main/java/hanglog/share/dto/response/WriterResponse.java b/backend/src/main/java/hanglog/share/dto/response/WriterResponse.java new file mode 100644 index 000000000..6213e9708 --- /dev/null +++ b/backend/src/main/java/hanglog/share/dto/response/WriterResponse.java @@ -0,0 +1,19 @@ +package hanglog.share.dto.response; + +import static lombok.AccessLevel.PRIVATE; + +import hanglog.member.domain.Member; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = PRIVATE) +public class WriterResponse { + + private final String nickname; + private final String imageUrl; + + public static WriterResponse of(final Member member) { + return new WriterResponse(member.getNickname(), member.getImageUrl()); + } +} diff --git a/backend/src/main/java/hanglog/share/presentation/SharedTripController.java b/backend/src/main/java/hanglog/share/presentation/SharedTripController.java index 7fe40e7c2..2a688ebe6 100644 --- a/backend/src/main/java/hanglog/share/presentation/SharedTripController.java +++ b/backend/src/main/java/hanglog/share/presentation/SharedTripController.java @@ -6,8 +6,8 @@ import hanglog.expense.service.ExpenseService; import hanglog.share.dto.request.SharedTripStatusRequest; import hanglog.share.dto.response.SharedTripCodeResponse; +import hanglog.share.dto.response.SharedTripDetailResponse; import hanglog.share.service.SharedTripService; -import hanglog.trip.dto.response.TripDetailResponse; import hanglog.trip.service.TripService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -28,10 +28,10 @@ public class SharedTripController { private final ExpenseService expenseService; @GetMapping("/shared-trips/{sharedCode}") - public ResponseEntity getSharedTrip(@PathVariable final String sharedCode) { + public ResponseEntity getSharedTrip(@PathVariable final String sharedCode) { final Long tripId = sharedTripService.getTripId(sharedCode); - final TripDetailResponse tripDetailResponse = tripService.getTripDetail(tripId); - return ResponseEntity.ok().body(tripDetailResponse); + final SharedTripDetailResponse sharedTripDetailResponse = sharedTripService.getSharedTripDetail(tripId); + return ResponseEntity.ok().body(sharedTripDetailResponse); } @PatchMapping("/trips/{tripId}/share") diff --git a/backend/src/main/java/hanglog/share/service/SharedTripService.java b/backend/src/main/java/hanglog/share/service/SharedTripService.java index d3628ff67..9bc036ca4 100644 --- a/backend/src/main/java/hanglog/share/service/SharedTripService.java +++ b/backend/src/main/java/hanglog/share/service/SharedTripService.java @@ -4,13 +4,18 @@ import static hanglog.global.exception.ExceptionCode.NOT_FOUND_SHARED_CODE; import static hanglog.global.exception.ExceptionCode.NOT_FOUND_TRIP_ID; +import hanglog.city.domain.City; import hanglog.global.exception.BadRequestException; import hanglog.share.domain.SharedTrip; import hanglog.share.domain.repository.SharedTripRepository; import hanglog.share.dto.request.SharedTripStatusRequest; import hanglog.share.dto.response.SharedTripCodeResponse; +import hanglog.share.dto.response.SharedTripDetailResponse; import hanglog.trip.domain.Trip; +import hanglog.trip.domain.TripCity; +import hanglog.trip.domain.repository.TripCityRepository; import hanglog.trip.domain.repository.TripRepository; +import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -22,6 +27,7 @@ public class SharedTripService { private final SharedTripRepository sharedTripRepository; + private final TripCityRepository tripCityRepository; private final TripRepository tripRepository; @Transactional(readOnly = true) @@ -36,6 +42,19 @@ public Long getTripId(final String sharedCode) { return sharedTrip.getTrip().getId(); } + public SharedTripDetailResponse getSharedTripDetail(final Long tripId) { + final Trip trip = tripRepository.findById(tripId) + .orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ID)); + final List cities = getCitiesByTripId(tripId); + return SharedTripDetailResponse.of(trip, cities); + } + + private List getCitiesByTripId(final Long tripId) { + return tripCityRepository.findByTripId(tripId).stream() + .map(TripCity::getCity) + .toList(); + } + public SharedTripCodeResponse updateSharedTripStatus( final Long tripId, final SharedTripStatusRequest sharedTripStatusRequest @@ -51,7 +70,7 @@ public SharedTripCodeResponse updateSharedTripStatus( return SharedTripCodeResponse.of(sharedTrip); } - private Trip findTripWithNoFetch(final Long tripId){ + private Trip findTripWithNoFetch(final Long tripId) { return tripRepository.findById(tripId) .orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ID)); } diff --git a/backend/src/main/java/hanglog/trip/domain/Trip.java b/backend/src/main/java/hanglog/trip/domain/Trip.java index d2824e819..f8030326b 100644 --- a/backend/src/main/java/hanglog/trip/domain/Trip.java +++ b/backend/src/main/java/hanglog/trip/domain/Trip.java @@ -142,6 +142,10 @@ public Optional getSharedCode() { return Optional.of(sharedTrip.getSharedCode()); } + public Boolean isPublished() { + return this.publishedStatus.equals(PublishedStatusType.PUBLISHED); + } + public void changePublishedStatus(final Boolean isPublished) { this.publishedStatus = PublishedStatusType.mappingType(isPublished); } diff --git a/backend/src/main/java/hanglog/trip/dto/response/TripDetailResponse.java b/backend/src/main/java/hanglog/trip/dto/response/TripDetailResponse.java index 70cebbc53..c988619cd 100644 --- a/backend/src/main/java/hanglog/trip/dto/response/TripDetailResponse.java +++ b/backend/src/main/java/hanglog/trip/dto/response/TripDetailResponse.java @@ -3,8 +3,8 @@ import static hanglog.image.util.ImageUrlConverter.convertNameToUrl; import static lombok.AccessLevel.PRIVATE; -import hanglog.city.dto.response.CityWithPositionResponse; import hanglog.city.domain.City; +import hanglog.city.dto.response.CityWithPositionResponse; import hanglog.trip.domain.Trip; import java.time.LocalDate; import java.util.List; @@ -24,6 +24,7 @@ public class TripDetailResponse { private final String imageUrl; private final String sharedCode; private final List dayLogs; + private final Boolean isPublished; public static TripDetailResponse of(final Trip trip, final List cities) { final List dayLogResponses = trip.getDayLogs().stream() @@ -45,7 +46,8 @@ public static TripDetailResponse of(final Trip trip, final List cities) { trip.getDescription(), convertNameToUrl(trip.getImageName()), sharedCode, - dayLogResponses + dayLogResponses, + trip.isPublished() ); } } diff --git a/backend/src/main/java/hanglog/trip/dto/response/TripResponse.java b/backend/src/main/java/hanglog/trip/dto/response/TripResponse.java index d6e8978aa..63fb17ccd 100644 --- a/backend/src/main/java/hanglog/trip/dto/response/TripResponse.java +++ b/backend/src/main/java/hanglog/trip/dto/response/TripResponse.java @@ -3,8 +3,8 @@ import static hanglog.image.util.ImageUrlConverter.convertNameToUrl; import static lombok.AccessLevel.PRIVATE; -import hanglog.city.dto.response.CityResponse; import hanglog.city.domain.City; +import hanglog.city.dto.response.CityResponse; import hanglog.trip.domain.Trip; import java.time.LocalDate; import java.util.List; diff --git a/backend/src/test/java/hanglog/share/presentation/SharedTripControllerTest.java b/backend/src/test/java/hanglog/share/presentation/SharedTripControllerTest.java index 4f1834090..866467550 100644 --- a/backend/src/test/java/hanglog/share/presentation/SharedTripControllerTest.java +++ b/backend/src/test/java/hanglog/share/presentation/SharedTripControllerTest.java @@ -23,6 +23,7 @@ import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; @@ -38,9 +39,9 @@ import hanglog.global.ControllerTest; import hanglog.share.dto.request.SharedTripStatusRequest; import hanglog.share.dto.response.SharedTripCodeResponse; +import hanglog.share.dto.response.SharedTripDetailResponse; import hanglog.share.service.SharedTripService; import hanglog.trip.domain.TripCity; -import hanglog.trip.dto.response.TripDetailResponse; import hanglog.trip.fixture.CityFixture; import hanglog.trip.service.TripService; import jakarta.servlet.http.Cookie; @@ -80,8 +81,8 @@ void getSharedTrip() throws Exception { // given when(sharedTripService.getTripId(anyString())) .thenReturn(1L); - when(tripService.getTripDetail(anyLong())) - .thenReturn(TripDetailResponse.of(TRIP, List.of(CALIFORNIA, TOKYO, BEIJING))); + when(sharedTripService.getSharedTripDetail(anyLong())) + .thenReturn(SharedTripDetailResponse.of(TRIP, List.of(CALIFORNIA, TOKYO, BEIJING))); // when mockMvc.perform(get("/shared-trips/{sharedCode}", "xxxxxx").contentType(APPLICATION_JSON)) @@ -96,6 +97,17 @@ void getSharedTrip() throws Exception { .type(JsonFieldType.NUMBER) .description("여행 ID") .attributes(field("constraint", "양의 정수")), + fieldWithPath("writer") + .type(JsonFieldType.OBJECT) + .description("작성자"), + fieldWithPath("writer.nickname") + .type(JsonFieldType.STRING) + .description("작성자 닉네임") + .attributes(field("constraint", "문자열")), + fieldWithPath("writer.imageUrl") + .type(JsonFieldType.STRING) + .description("작성자 이미지") + .attributes(field("constraint", "문자열")), fieldWithPath("title") .type(JsonFieldType.STRING) .description("여행 제목") @@ -118,7 +130,7 @@ void getSharedTrip() throws Exception { .attributes(field("constraint", "이미지 URL")), fieldWithPath("sharedCode") .type(JsonFieldType.STRING) - .description("공유 코") + .description("공유 코드") .attributes(field("constraint", "문자열 비공유시 null 입력")) .optional(), fieldWithPath("cities") @@ -195,6 +207,12 @@ void updateSharedStatus() throws Exception { parameterWithName("tripId") .description("여행 ID") ), + requestFields( + fieldWithPath("sharedStatus") + .type(JsonFieldType.BOOLEAN) + .description("공유 유무") + .attributes(field("constraint", "공유시: true, 비공유시: false")) + ), responseFields( fieldWithPath("sharedCode") .type(JsonFieldType.STRING) diff --git a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java index ad58e1965..88e0cd496 100644 --- a/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java +++ b/backend/src/test/java/hanglog/trip/presentation/TripControllerTest.java @@ -292,6 +292,10 @@ void getTrip() throws Exception { .description("공유 코드") .attributes(field("constraint", "문자열 비공유시 null")) .optional(), + fieldWithPath("isPublished") + .type(JsonFieldType.BOOLEAN) + .description("공개 여부") + .attributes(field("constraint", "boolean 공개시 true")), fieldWithPath("cities") .type(JsonFieldType.ARRAY) .description("여행 도시 배열") From aa38d2ea5d92be888cf1e0b877b346a07529009b Mon Sep 17 00:00:00 2001 From: waterricecake <91263263+waterricecake@users.noreply.github.com> Date: Thu, 21 Sep 2023 13:30:18 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EC=97=AC=ED=96=89=20=EC=A1=B0=ED=9A=8C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=84=A4=EC=9D=B4=EC=85=98=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#587)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 전체 여행 페이지네이션 조회 구현 * test: controller 테스트 구현 * refactor: like 테이블 어노테이션 추가 * refactor: like 테이블명 변경 * feat: 전체 여행 페이지네이션 조회 구현 * test: controller 테스트 구현 * refactor: like 테이블명 변경 * refactor: 요청된 페이지 이전 페이지 조회 적용 * feat: 마지막 페이지 반환 기능 구현 * docs: restdocs 문서 수정 * style: final 키워드 추가 * refactor: 공개된 여행 수 조회 메서드 변경 * refactor: 작성자 추가 * refactor: 테스트 명 변경 * refactor: 마이그레이션 스크립트 파일명 수정 * refactor: 패키지 위치 변경 * refactor: controller 메서드 public 접근자 부여 * style: final 키워드 추가 * refactor: test 패키지 변경 * chore: db마이그레이션 스크립트 버전 변경 * chore: 컨플릭트 해결 * refactor: response 객체 명 변경 * refactor: response 작성자 필드 추가 * refactor: like 개수 반환 매개변수 변경 * refactor: tripId 메서드 메게변수 수정 --- backend/src/docs/asciidoc/docs.adoc | 23 +++ .../Like.java => community/domain/Likes.java} | 5 +- .../domain/PublishedTrip.java | 3 +- .../domain/repository/LikesRepository.java | 11 ++ .../domain/type/PublishedStatusType.java | 2 +- .../response/CommunityTripListResponse.java | 13 ++ .../dto/response/CommunityTripResponse.java | 55 ++++++ .../presentation/CommunityController.java | 32 ++++ .../community/service/CommunityService.java | 55 ++++++ .../main/java/hanglog/trip/domain/Trip.java | 2 +- .../repository/PublishedTripRepository.java | 2 +- .../domain/repository/TripRepository.java | 10 ++ .../hanglog/trip/service/TripService.java | 4 +- .../V7__Rename_table_like_to_likes.sql | 1 + .../presentation/CommunityControllerTest.java | 170 ++++++++++++++++++ .../expense/fixture/TripExpenseFixture.java | 2 +- .../hanglog/share/fixture/ShareFixture.java | 2 +- .../hanglog/trip/fixture/DayLogFixture.java | 2 +- .../hanglog/trip/fixture/TripFixture.java | 2 +- .../hanglog/trip/service/TripServiceTest.java | 4 +- 20 files changed, 386 insertions(+), 14 deletions(-) rename backend/src/main/java/hanglog/{trip/domain/Like.java => community/domain/Likes.java} (90%) rename backend/src/main/java/hanglog/{trip => community}/domain/PublishedTrip.java (93%) create mode 100644 backend/src/main/java/hanglog/community/domain/repository/LikesRepository.java rename backend/src/main/java/hanglog/{trip => community}/domain/type/PublishedStatusType.java (86%) create mode 100644 backend/src/main/java/hanglog/community/dto/response/CommunityTripListResponse.java create mode 100644 backend/src/main/java/hanglog/community/dto/response/CommunityTripResponse.java create mode 100644 backend/src/main/java/hanglog/community/presentation/CommunityController.java create mode 100644 backend/src/main/java/hanglog/community/service/CommunityService.java create mode 100644 backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql create mode 100644 backend/src/test/java/hanglog/community/presentation/CommunityControllerTest.java diff --git a/backend/src/docs/asciidoc/docs.adoc b/backend/src/docs/asciidoc/docs.adoc index 2dc7e222a..de274b762 100644 --- a/backend/src/docs/asciidoc/docs.adoc +++ b/backend/src/docs/asciidoc/docs.adoc @@ -318,3 +318,26 @@ include::{snippets}/shared-trip-controller-test/get-shared-expenses/path-paramet ==== 응답 include::{snippets}/shared-trip-controller-test/get-shared-expenses/http-response.adoc[] include::{snippets}/shared-trip-controller-test/get-shared-expenses/response-fields.adoc[] + +== 커뮤니티 API + +=== 공개 여행 페이지 조회 (GET /community/trips) + +==== 요청 +include::{snippets}/community-controller-test/get-trips-by-page/http-request.adoc[] +include::{snippets}/community-controller-test/get-trips-by-page/path-parameters.adoc[] + +==== 응답 +include::{snippets}/community-controller-test/get-trips-by-page/http-response.adoc[] +include::{snippets}/community-controller-test/get-trips-by-page/path-parameters.adoc[] + +== 커뮤니티 API + +=== 공개 여행 페이지 조회 (GET /community/trips) + +==== 요청 +include::{snippets}/community-controller-test/get-trips-by-page/http-request.adoc[] + +==== 응답 +include::{snippets}/community-controller-test/get-trips-by-page/http-response.adoc[] +include::{snippets}/community-controller-test/get-trips-by-page/response-fields.adoc[] diff --git a/backend/src/main/java/hanglog/trip/domain/Like.java b/backend/src/main/java/hanglog/community/domain/Likes.java similarity index 90% rename from backend/src/main/java/hanglog/trip/domain/Like.java rename to backend/src/main/java/hanglog/community/domain/Likes.java index 6984a48aa..041935043 100644 --- a/backend/src/main/java/hanglog/trip/domain/Like.java +++ b/backend/src/main/java/hanglog/community/domain/Likes.java @@ -1,10 +1,11 @@ -package hanglog.trip.domain; +package hanglog.community.domain; import static jakarta.persistence.FetchType.LAZY; import static jakarta.persistence.GenerationType.IDENTITY; import static lombok.AccessLevel.PROTECTED; import hanglog.member.domain.Member; +import hanglog.trip.domain.Trip; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @@ -18,7 +19,7 @@ @Getter @AllArgsConstructor @NoArgsConstructor(access = PROTECTED) -public class Like { +public class Likes { @Id @GeneratedValue(strategy = IDENTITY) diff --git a/backend/src/main/java/hanglog/trip/domain/PublishedTrip.java b/backend/src/main/java/hanglog/community/domain/PublishedTrip.java similarity index 93% rename from backend/src/main/java/hanglog/trip/domain/PublishedTrip.java rename to backend/src/main/java/hanglog/community/domain/PublishedTrip.java index dd3d7f64f..8043feb79 100644 --- a/backend/src/main/java/hanglog/trip/domain/PublishedTrip.java +++ b/backend/src/main/java/hanglog/community/domain/PublishedTrip.java @@ -1,10 +1,11 @@ -package hanglog.trip.domain; +package hanglog.community.domain; import static jakarta.persistence.FetchType.LAZY; import static jakarta.persistence.GenerationType.IDENTITY; import static lombok.AccessLevel.PROTECTED; import hanglog.global.BaseEntity; +import hanglog.trip.domain.Trip; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; diff --git a/backend/src/main/java/hanglog/community/domain/repository/LikesRepository.java b/backend/src/main/java/hanglog/community/domain/repository/LikesRepository.java new file mode 100644 index 000000000..fe33a9503 --- /dev/null +++ b/backend/src/main/java/hanglog/community/domain/repository/LikesRepository.java @@ -0,0 +1,11 @@ +package hanglog.community.domain.repository; + +import hanglog.community.domain.Likes; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LikesRepository extends JpaRepository { + + boolean existsByMemberIdAndTripId(final Long memberId, final Long tripId); + + Long countLikesByTripId(final Long tripId); +} diff --git a/backend/src/main/java/hanglog/trip/domain/type/PublishedStatusType.java b/backend/src/main/java/hanglog/community/domain/type/PublishedStatusType.java similarity index 86% rename from backend/src/main/java/hanglog/trip/domain/type/PublishedStatusType.java rename to backend/src/main/java/hanglog/community/domain/type/PublishedStatusType.java index 2574c52dd..cf230e61f 100644 --- a/backend/src/main/java/hanglog/trip/domain/type/PublishedStatusType.java +++ b/backend/src/main/java/hanglog/community/domain/type/PublishedStatusType.java @@ -1,4 +1,4 @@ -package hanglog.trip.domain.type; +package hanglog.community.domain.type; public enum PublishedStatusType { diff --git a/backend/src/main/java/hanglog/community/dto/response/CommunityTripListResponse.java b/backend/src/main/java/hanglog/community/dto/response/CommunityTripListResponse.java new file mode 100644 index 000000000..a9ae81128 --- /dev/null +++ b/backend/src/main/java/hanglog/community/dto/response/CommunityTripListResponse.java @@ -0,0 +1,13 @@ +package hanglog.community.dto.response; + +import java.util.List; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class CommunityTripListResponse { + + final List trips; + final Long lastPageIndex; +} diff --git a/backend/src/main/java/hanglog/community/dto/response/CommunityTripResponse.java b/backend/src/main/java/hanglog/community/dto/response/CommunityTripResponse.java new file mode 100644 index 000000000..16a480927 --- /dev/null +++ b/backend/src/main/java/hanglog/community/dto/response/CommunityTripResponse.java @@ -0,0 +1,55 @@ +package hanglog.community.dto.response; + +import static hanglog.image.util.ImageUrlConverter.convertNameToUrl; +import static lombok.AccessLevel.PRIVATE; + +import hanglog.city.domain.City; +import hanglog.city.dto.response.CityResponse; +import hanglog.share.dto.response.WriterResponse; +import hanglog.trip.domain.Trip; +import java.time.LocalDate; +import java.util.List; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor(access = PRIVATE) +public class CommunityTripResponse { + + private final Long id; + private final List cities; + private final WriterResponse writer; + private final String title; + private final LocalDate startDate; + private final LocalDate endDate; + private final String description; + private final String imageUrl; + private final Boolean isLike; + private final String authorNickname; + private final Long likeCount; + + public static CommunityTripResponse of( + final Trip trip, + final List cities, + final boolean isLike, + final Long likeCount + ) { + final List cityResponses = cities.stream() + .map(CityResponse::of) + .toList(); + + return new CommunityTripResponse( + trip.getId(), + cityResponses, + WriterResponse.of(trip.getMember()), + trip.getTitle(), + trip.getStartDate(), + trip.getEndDate(), + trip.getDescription(), + convertNameToUrl(trip.getImageName()), + isLike, + trip.getMember().getNickname(), + likeCount + ); + } +} diff --git a/backend/src/main/java/hanglog/community/presentation/CommunityController.java b/backend/src/main/java/hanglog/community/presentation/CommunityController.java new file mode 100644 index 000000000..c86501116 --- /dev/null +++ b/backend/src/main/java/hanglog/community/presentation/CommunityController.java @@ -0,0 +1,32 @@ +package hanglog.community.presentation; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +import hanglog.auth.Auth; +import hanglog.auth.domain.Accessor; +import hanglog.community.dto.response.CommunityTripListResponse; +import hanglog.community.service.CommunityService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +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; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/community") +public class CommunityController { + + private final CommunityService communityService; + + @GetMapping("/trips") + public ResponseEntity getTrips( + @Auth final Accessor accessor, + @PageableDefault(sort = "publishedTrip.id", direction = DESC) final Pageable pageable + ) { + final CommunityTripListResponse communityTripListResponse = communityService.getTripsByPage(accessor, pageable); + return ResponseEntity.ok().body(communityTripListResponse); + } +} diff --git a/backend/src/main/java/hanglog/community/service/CommunityService.java b/backend/src/main/java/hanglog/community/service/CommunityService.java new file mode 100644 index 000000000..721d2c251 --- /dev/null +++ b/backend/src/main/java/hanglog/community/service/CommunityService.java @@ -0,0 +1,55 @@ +package hanglog.community.service; + +import static hanglog.community.domain.type.PublishedStatusType.PUBLISHED; + +import hanglog.auth.domain.Accessor; +import hanglog.city.domain.City; +import hanglog.community.domain.repository.LikesRepository; +import hanglog.community.dto.response.CommunityTripListResponse; +import hanglog.community.dto.response.CommunityTripResponse; +import hanglog.trip.domain.Trip; +import hanglog.trip.domain.TripCity; +import hanglog.trip.domain.repository.TripCityRepository; +import hanglog.trip.domain.repository.TripRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class CommunityService { + + private final LikesRepository likesRepository; + private final TripRepository tripRepository; + private final TripCityRepository tripCityRepository; + + public CommunityTripListResponse getTripsByPage(final Accessor accessor, final Pageable pageable) { + final List trips = tripRepository.findPublishedTripByPageable(pageable.previousOrFirst()); + final List communityTripResponse = trips.stream() + .map(trip -> getTripResponse(accessor, trip)) + .toList(); + final Long lastPageIndex = + tripRepository.countTripByPublishedStatus(PUBLISHED) / pageable.getPageSize() + 1; + return new CommunityTripListResponse(communityTripResponse, lastPageIndex); + } + + private CommunityTripResponse getTripResponse(final Accessor accessor, final Trip trip) { + final List cities = getCitiesByTripId(trip.getId()); + final Long likeCount = likesRepository.countLikesByTripId(trip.getId()); + + if (accessor.isMember()) { + final boolean isLike = likesRepository.existsByMemberIdAndTripId(trip.getMember().getId(), trip.getId()); + return CommunityTripResponse.of(trip, cities, isLike, likeCount); + } + return CommunityTripResponse.of(trip, cities, false, likeCount); + } + + private List getCitiesByTripId(final Long tripId) { + return tripCityRepository.findByTripId(tripId).stream() + .map(TripCity::getCity) + .toList(); + } +} diff --git a/backend/src/main/java/hanglog/trip/domain/Trip.java b/backend/src/main/java/hanglog/trip/domain/Trip.java index f8030326b..6bfb2699c 100644 --- a/backend/src/main/java/hanglog/trip/domain/Trip.java +++ b/backend/src/main/java/hanglog/trip/domain/Trip.java @@ -10,10 +10,10 @@ import static jakarta.persistence.GenerationType.IDENTITY; import static lombok.AccessLevel.PROTECTED; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.global.BaseEntity; import hanglog.member.domain.Member; import hanglog.share.domain.SharedTrip; -import hanglog.trip.domain.type.PublishedStatusType; import hanglog.trip.dto.request.TripUpdateRequest; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/backend/src/main/java/hanglog/trip/domain/repository/PublishedTripRepository.java b/backend/src/main/java/hanglog/trip/domain/repository/PublishedTripRepository.java index b03d9ff42..693375187 100644 --- a/backend/src/main/java/hanglog/trip/domain/repository/PublishedTripRepository.java +++ b/backend/src/main/java/hanglog/trip/domain/repository/PublishedTripRepository.java @@ -1,6 +1,6 @@ package hanglog.trip.domain.repository; -import hanglog.trip.domain.PublishedTrip; +import hanglog.community.domain.PublishedTrip; import org.springframework.data.jpa.repository.JpaRepository; public interface PublishedTripRepository extends JpaRepository { diff --git a/backend/src/main/java/hanglog/trip/domain/repository/TripRepository.java b/backend/src/main/java/hanglog/trip/domain/repository/TripRepository.java index 88535b3f2..3a7431d6e 100644 --- a/backend/src/main/java/hanglog/trip/domain/repository/TripRepository.java +++ b/backend/src/main/java/hanglog/trip/domain/repository/TripRepository.java @@ -1,8 +1,10 @@ package hanglog.trip.domain.repository; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.trip.domain.Trip; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -17,5 +19,13 @@ public interface TripRepository extends JpaRepository { @Query("SELECT trip FROM Trip trip LEFT JOIN FETCH trip.sharedTrip WHERE trip.member.id = :memberId") List findAllByMemberId(@Param("memberId") final Long memberId); + @Query("SELECT trip FROM Trip trip " + + "LEFT JOIN PublishedTrip publishedTrip ON publishedTrip.trip = trip " + + "WHERE trip.publishedStatus = 'PUBLISHED'") + List findPublishedTripByPageable(final Pageable pageable); + + Long countTripByPublishedStatus(final PublishedStatusType publishedStatusType); + void deleteAllByMemberId(final Long memberId); + } diff --git a/backend/src/main/java/hanglog/trip/service/TripService.java b/backend/src/main/java/hanglog/trip/service/TripService.java index 5988b4678..2790eb99c 100644 --- a/backend/src/main/java/hanglog/trip/service/TripService.java +++ b/backend/src/main/java/hanglog/trip/service/TripService.java @@ -7,18 +7,18 @@ import hanglog.city.domain.City; import hanglog.city.domain.repository.CityRepository; +import hanglog.community.domain.PublishedTrip; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.global.exception.AuthException; import hanglog.global.exception.BadRequestException; import hanglog.member.domain.Member; import hanglog.member.domain.repository.MemberRepository; import hanglog.trip.domain.DayLog; -import hanglog.trip.domain.PublishedTrip; import hanglog.trip.domain.Trip; import hanglog.trip.domain.TripCity; import hanglog.trip.domain.repository.PublishedTripRepository; import hanglog.trip.domain.repository.TripCityRepository; import hanglog.trip.domain.repository.TripRepository; -import hanglog.trip.domain.type.PublishedStatusType; import hanglog.trip.dto.request.PublishedStatusRequest; import hanglog.trip.dto.request.TripCreateRequest; import hanglog.trip.dto.request.TripUpdateRequest; diff --git a/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql b/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql new file mode 100644 index 000000000..b6d1341f8 --- /dev/null +++ b/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql @@ -0,0 +1 @@ +ALTER TABLE `like` RENAME `likes`; diff --git a/backend/src/test/java/hanglog/community/presentation/CommunityControllerTest.java b/backend/src/test/java/hanglog/community/presentation/CommunityControllerTest.java new file mode 100644 index 000000000..8df2a4d99 --- /dev/null +++ b/backend/src/test/java/hanglog/community/presentation/CommunityControllerTest.java @@ -0,0 +1,170 @@ +package hanglog.community.presentation; + +import static hanglog.global.restdocs.RestDocsConfiguration.field; +import static hanglog.trip.fixture.CityFixture.LONDON; +import static hanglog.trip.fixture.CityFixture.PARIS; +import static hanglog.trip.fixture.TripFixture.LONDON_TRIP; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import hanglog.auth.domain.MemberTokens; +import hanglog.city.domain.City; +import hanglog.community.dto.response.CommunityTripListResponse; +import hanglog.community.dto.response.CommunityTripResponse; +import hanglog.community.service.CommunityService; +import hanglog.global.ControllerTest; +import jakarta.servlet.http.Cookie; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; + + +@WebMvcTest(CommunityController.class) +@MockBean(JpaMetamodelMappingContext.class) +@AutoConfigureRestDocs +class CommunityControllerTest extends ControllerTest { + + private static final List CITIES = List.of(PARIS, LONDON); + private static final MemberTokens MEMBER_TOKENS = new MemberTokens("refreshToken", "accessToken"); + private static final Cookie COOKIE = new Cookie("refresh-token", MEMBER_TOKENS.getRefreshToken()); + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private CommunityService communityService; + + @BeforeEach + void setUp() { + given(refreshTokenRepository.existsByToken(any())).willReturn(true); + doNothing().when(jwtProvider).validateTokens(any()); + given(jwtProvider.getSubject(any())).willReturn("1"); + } + + private ResultActions performGetRequest() throws Exception { + return mockMvc.perform(get("/community/trips") + .queryParam("page", "0") + .queryParam("size", "1") + .header(AUTHORIZATION, MEMBER_TOKENS.getAccessToken()) + .cookie(COOKIE) + .contentType(APPLICATION_JSON)); + } + + @DisplayName("공개된 전체 여행 목록을 조회한다") + @Test + void getTripsByPage() throws Exception { + // given + when(communityService.getTripsByPage(any(), any())) + .thenReturn(new CommunityTripListResponse( + List.of(CommunityTripResponse.of(LONDON_TRIP, CITIES, true, 1L)), + 1L + )); + + // when + final ResultActions resultActions = performGetRequest(); + + // then + final MvcResult mvcResult = resultActions.andExpect(status().isOk()) + .andDo(restDocs.document( + responseFields( + fieldWithPath("trips") + .type(JsonFieldType.ARRAY) + .description("여행 목록") + .attributes(field("constraint", "10개 이하의 여행")), + fieldWithPath("trips[].id") + .type(JsonFieldType.NUMBER) + .description("여행 ID") + .attributes(field("constraint", "양의 정수")), + fieldWithPath("trips[].writer") + .type(JsonFieldType.OBJECT) + .description("작성자"), + fieldWithPath("trips[].writer.nickname") + .type(JsonFieldType.STRING) + .description("작성자 닉네임") + .attributes(field("constraint", "문자열")), + fieldWithPath("trips[].writer.imageUrl") + .type(JsonFieldType.STRING) + .description("작성자 이미지") + .attributes(field("constraint", "문자열")), + fieldWithPath("trips[].authorNickname") + .type(JsonFieldType.STRING) + .description("작성자") + .attributes(field("constraint", "문자열")), + fieldWithPath("trips[].title") + .type(JsonFieldType.STRING) + .description("여행 제목") + .attributes(field("constraint", "50자 이하의 문자열")), + fieldWithPath("trips[].startDate") + .type(JsonFieldType.STRING) + .description("여행 시작 날짜") + .attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("trips[].endDate") + .type(JsonFieldType.STRING) + .description("여행 종료 날짜") + .attributes(field("constraint", "yyyy-MM-dd")), + fieldWithPath("trips[].description") + .type(JsonFieldType.STRING) + .description("여행 요약") + .attributes(field("constraint", "200자 이하의 문자열")), + fieldWithPath("trips[].likeCount") + .type(JsonFieldType.NUMBER) + .description("좋아요 숫자") + .attributes(field("constraint", "0과 양의 정수")), + fieldWithPath("trips[].isLike") + .type(JsonFieldType.BOOLEAN) + .description("좋아요 유무") + .attributes(field("constraint", "boolean (true : 좋아요)")), + fieldWithPath("trips[].imageUrl") + .type(JsonFieldType.STRING) + .description("여행 대표 이미지") + .attributes(field("constraint", "이미지 URL")), + fieldWithPath("trips[].cities") + .type(JsonFieldType.ARRAY) + .description("여행 도시 배열") + .attributes(field("constraint", "1개 이상의 도시 정보")), + fieldWithPath("trips[].cities[].id") + .type(JsonFieldType.NUMBER) + .description("여행 도시 ID") + .attributes(field("constraint", "양의 정수")), + fieldWithPath("trips[].cities[].name") + .type(JsonFieldType.STRING) + .description("여행 도시 이름") + .attributes(field("constraint", "도시")), + fieldWithPath("lastPageIndex") + .type(JsonFieldType.NUMBER) + .description("마지막 페이지 인덱스") + .attributes(field("constraint", "양의 정수")) + ) + )) + .andReturn(); + + final CommunityTripListResponse communityTripListResponses = objectMapper.readValue( + mvcResult.getResponse().getContentAsString(), + CommunityTripListResponse.class + ); + + assertThat(communityTripListResponses).usingRecursiveComparison().isEqualTo(new CommunityTripListResponse( + List.of(CommunityTripResponse.of(LONDON_TRIP, CITIES, true, 1L)), + 1L + )); + } +} diff --git a/backend/src/test/java/hanglog/expense/fixture/TripExpenseFixture.java b/backend/src/test/java/hanglog/expense/fixture/TripExpenseFixture.java index 1f36d8e9c..3a1f72def 100644 --- a/backend/src/test/java/hanglog/expense/fixture/TripExpenseFixture.java +++ b/backend/src/test/java/hanglog/expense/fixture/TripExpenseFixture.java @@ -5,11 +5,11 @@ import static hanglog.expense.fixture.ExpenseFixture.USD_100_ACCOMMODATION_EXPENSE; import static hanglog.integration.IntegrationFixture.MEMBER; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.trip.domain.DayLog; import hanglog.trip.domain.Item; import hanglog.trip.domain.Trip; import hanglog.trip.domain.type.ItemType; -import hanglog.trip.domain.type.PublishedStatusType; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; diff --git a/backend/src/test/java/hanglog/share/fixture/ShareFixture.java b/backend/src/test/java/hanglog/share/fixture/ShareFixture.java index 01b951aa1..e965afd22 100644 --- a/backend/src/test/java/hanglog/share/fixture/ShareFixture.java +++ b/backend/src/test/java/hanglog/share/fixture/ShareFixture.java @@ -5,10 +5,10 @@ import static hanglog.share.domain.type.SharedStatusType.UNSHARED; import hanglog.city.domain.City; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.share.domain.SharedTrip; import hanglog.trip.domain.DayLog; import hanglog.trip.domain.Trip; -import hanglog.trip.domain.type.PublishedStatusType; import java.math.BigDecimal; import java.time.LocalDate; import java.util.ArrayList; diff --git a/backend/src/test/java/hanglog/trip/fixture/DayLogFixture.java b/backend/src/test/java/hanglog/trip/fixture/DayLogFixture.java index 5029afdec..81bc44884 100644 --- a/backend/src/test/java/hanglog/trip/fixture/DayLogFixture.java +++ b/backend/src/test/java/hanglog/trip/fixture/DayLogFixture.java @@ -5,9 +5,9 @@ import static hanglog.trip.fixture.ItemFixture.JAPAN_HOTEL; import static hanglog.trip.fixture.ItemFixture.LONDON_EYE_ITEM; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.trip.domain.DayLog; import hanglog.trip.domain.Trip; -import hanglog.trip.domain.type.PublishedStatusType; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; diff --git a/backend/src/test/java/hanglog/trip/fixture/TripFixture.java b/backend/src/test/java/hanglog/trip/fixture/TripFixture.java index a13521afa..4a84a651b 100644 --- a/backend/src/test/java/hanglog/trip/fixture/TripFixture.java +++ b/backend/src/test/java/hanglog/trip/fixture/TripFixture.java @@ -7,8 +7,8 @@ import static hanglog.trip.fixture.DayLogFixture.LONDON_DAYLOG_2; import static hanglog.trip.fixture.DayLogFixture.LONDON_DAYLOG_EXTRA; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.trip.domain.Trip; -import hanglog.trip.domain.type.PublishedStatusType; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; diff --git a/backend/src/test/java/hanglog/trip/service/TripServiceTest.java b/backend/src/test/java/hanglog/trip/service/TripServiceTest.java index 4e381937f..93e900f7a 100644 --- a/backend/src/test/java/hanglog/trip/service/TripServiceTest.java +++ b/backend/src/test/java/hanglog/trip/service/TripServiceTest.java @@ -14,16 +14,16 @@ import static org.mockito.Mockito.verify; import hanglog.city.domain.repository.CityRepository; +import hanglog.community.domain.PublishedTrip; +import hanglog.community.domain.type.PublishedStatusType; import hanglog.global.exception.BadRequestException; import hanglog.member.domain.repository.MemberRepository; import hanglog.trip.domain.DayLog; -import hanglog.trip.domain.PublishedTrip; import hanglog.trip.domain.Trip; import hanglog.trip.domain.TripCity; import hanglog.trip.domain.repository.PublishedTripRepository; import hanglog.trip.domain.repository.TripCityRepository; import hanglog.trip.domain.repository.TripRepository; -import hanglog.trip.domain.type.PublishedStatusType; import hanglog.trip.dto.request.PublishedStatusRequest; import hanglog.trip.dto.request.TripCreateRequest; import hanglog.trip.dto.request.TripUpdateRequest; From d00e1c4f4a7670e1b4ea0a0ddcdb9ff9f6c4e766 Mon Sep 17 00:00:00 2001 From: waterricecake <91263263+waterricecake@users.noreply.github.com> Date: Thu, 21 Sep 2023 13:51:03 +0900 Subject: [PATCH 3/4] =?UTF-8?q?db=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(#616)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../db/migration/V4__Creat_table_published_trip_and_like.sql | 2 +- .../resources/db/migration/V7__Rename_table_like_to_likes.sql | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql diff --git a/backend/src/main/resources/db/migration/V4__Creat_table_published_trip_and_like.sql b/backend/src/main/resources/db/migration/V4__Creat_table_published_trip_and_like.sql index b5eba3b2a..f7aae0523 100644 --- a/backend/src/main/resources/db/migration/V4__Creat_table_published_trip_and_like.sql +++ b/backend/src/main/resources/db/migration/V4__Creat_table_published_trip_and_like.sql @@ -1,4 +1,4 @@ -CREATE TABLE IF NOT EXISTS `like` ( +CREATE TABLE IF NOT EXISTS likes ( id BIGINT NOT NULL AUTO_INCREMENT, member_id BIGINT NOT NULL, trip_id BIGINT NOT NULL, diff --git a/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql b/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql deleted file mode 100644 index b6d1341f8..000000000 --- a/backend/src/main/resources/db/migration/V7__Rename_table_like_to_likes.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `like` RENAME `likes`; From ec9f769f813cb904c2aadc26cede3af1298b7182 Mon Sep 17 00:00:00 2001 From: Dahye Yun <102305630+Dahyeeee@users.noreply.github.com> Date: Thu, 21 Sep 2023 20:35:11 +0900 Subject: [PATCH 4/4] =?UTF-8?q?tripId=20=ED=94=84=EB=A1=AD=EC=8A=A4,=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=A0=84=EB=B6=80=20string=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(#619)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:로그인 화면에서 다시 로그인으로 돌아오는 버그 수정 * fix: 모바일 공유페이지 버그 수정 (tripId타입수정) * refactor: tripId 프롭, 인자 타입 string으로 변경 --- frontend/src/api/dayLog/patchDayLogItemOrder.ts | 2 +- frontend/src/api/dayLog/patchDayLogTitle.ts | 2 +- frontend/src/api/expense/getExpense.ts | 2 +- frontend/src/api/trip/deleteTrip.ts | 2 +- frontend/src/api/trip/getTrip.ts | 2 +- frontend/src/api/trip/patchTripShareStatus.ts | 2 +- frontend/src/api/trip/putTrip.ts | 2 +- frontend/src/api/tripItem/deleteTripItem.ts | 2 +- frontend/src/api/tripItem/postTripItem.ts | 2 +- frontend/src/api/tripItem/putTripItem.ts | 2 +- .../components/common/DayLogItem/DayLogItem.tsx | 2 +- .../common/DayLogItem/TitleInput/TitleInput.tsx | 2 +- .../components/common/DayLogList/DayLogList.tsx | 2 +- .../TripInformation/TripButtons/TripButtons.tsx | 2 +- .../TripEditButtons/TripEditButtons.tsx | 2 +- .../common/TripInformation/TripInformation.tsx | 6 +++--- .../TripShareButton/TripShareButton.tsx | 2 +- .../common/TripItem/EditMenu/EditMenu.tsx | 2 +- .../src/components/common/TripItem/TripItem.tsx | 2 +- .../common/TripItemList/TripItemList.tsx | 4 ++-- .../ExpenseCategories/ExpenseCategories.tsx | 2 +- .../ExpenseCategoryInformation.tsx | 2 +- .../expense/ExpenseDates/ExpenseDates.tsx | 2 +- .../ExpenseInformation/ExpenseInformation.tsx | 2 +- .../expense/ExpenseList/ExpenseList.tsx | 2 +- .../ExpenseListSection/ExpenseListSection.tsx | 2 +- .../TotalExpenseSection/TotalExpenseSection.tsx | 4 ++-- .../TripItemAddModal/DateInput/DateInput.tsx | 2 +- .../trip/TripItemAddModal/TripItemAddModal.tsx | 2 +- frontend/src/constants/api.ts | 16 ++++++++-------- frontend/src/constants/path.ts | 10 +++++----- frontend/src/hooks/api/useExpenseQuery.ts | 4 ++-- frontend/src/hooks/api/useLogInMutation.ts | 3 ++- frontend/src/hooks/api/useSharedTripQuery.ts | 4 +--- frontend/src/hooks/api/useTripEditPageQueries.ts | 2 +- frontend/src/hooks/api/useTripQuery.ts | 9 +++++++-- frontend/src/hooks/expense/useExpense.ts | 2 +- frontend/src/hooks/trip/useAddTripItemForm.ts | 2 +- frontend/src/hooks/trip/useTrip.ts | 3 +-- frontend/src/hooks/trip/useTripEditForm.ts | 2 +- frontend/src/pages/ExpensePage/ExpensePage.tsx | 6 +++--- frontend/src/pages/SharedPage/SharedTripPage.tsx | 14 +++++++------- frontend/src/pages/TripEditPage/TripEditPage.tsx | 12 ++++-------- frontend/src/pages/TripPage/TripMobilePage.tsx | 13 ++++++++----- frontend/src/pages/TripPage/TripPage.tsx | 6 +++--- frontend/src/router/AppRouter.tsx | 2 +- .../src/stories/common/DayLogItem.stories.tsx | 2 +- .../src/stories/common/DayLogList.stories.tsx | 6 +++--- .../stories/common/TripInformation.stories.tsx | 4 ++-- frontend/src/stories/common/TripItem.stories.tsx | 2 +- .../src/stories/common/TripItemList.stories.tsx | 2 +- .../expense/ExpenseCategories.stories.tsx | 4 ++-- .../ExpenseCategoryInformation.stories.tsx | 4 ++-- .../src/stories/expense/ExpenseDates.stories.tsx | 4 ++-- .../expense/ExpenseInformation.stories.tsx | 4 ++-- .../src/stories/expense/ExpenseList.stories.tsx | 2 +- .../expense/ExpenseListSection.stories.tsx | 2 +- .../expense/TotalExpenseSection.stories.tsx | 4 ++-- frontend/src/stories/trip/DateInput.stories.tsx | 4 ++-- .../stories/trip/TripItemAddModal.stories.tsx | 4 ++-- 60 files changed, 113 insertions(+), 111 deletions(-) diff --git a/frontend/src/api/dayLog/patchDayLogItemOrder.ts b/frontend/src/api/dayLog/patchDayLogItemOrder.ts index becfe40cf..e31374eac 100644 --- a/frontend/src/api/dayLog/patchDayLogItemOrder.ts +++ b/frontend/src/api/dayLog/patchDayLogItemOrder.ts @@ -3,7 +3,7 @@ import { axiosInstance } from '@api/axiosInstance'; import { END_POINTS } from '@constants/api'; export interface PatchDayLogItemOrderParams { - tripId: number; + tripId: string; dayLogId: number; itemIds: number[]; } diff --git a/frontend/src/api/dayLog/patchDayLogTitle.ts b/frontend/src/api/dayLog/patchDayLogTitle.ts index fe5985921..498463b17 100644 --- a/frontend/src/api/dayLog/patchDayLogTitle.ts +++ b/frontend/src/api/dayLog/patchDayLogTitle.ts @@ -7,7 +7,7 @@ export interface PatchDayLogTitleRequestBody { } interface PatchDayLogTitleParams extends PatchDayLogTitleRequestBody { - tripId: number; + tripId: string; dayLogId: number; } diff --git a/frontend/src/api/expense/getExpense.ts b/frontend/src/api/expense/getExpense.ts index 632dafdf3..9d2f6b10f 100644 --- a/frontend/src/api/expense/getExpense.ts +++ b/frontend/src/api/expense/getExpense.ts @@ -4,7 +4,7 @@ import type { ExpenseData } from '@type/expense'; import { END_POINTS } from '@constants/api'; -export const getExpense = async (tripId: number) => { +export const getExpense = async (tripId: string) => { const { data } = await axiosInstance.get(END_POINTS.EXPENSE(tripId)); return data; diff --git a/frontend/src/api/trip/deleteTrip.ts b/frontend/src/api/trip/deleteTrip.ts index 7b9c3dc5c..b3dd87160 100644 --- a/frontend/src/api/trip/deleteTrip.ts +++ b/frontend/src/api/trip/deleteTrip.ts @@ -3,7 +3,7 @@ import { axiosInstance } from '@api/axiosInstance'; import { END_POINTS } from '@constants/api'; interface DeleteTripParams { - tripId: number; + tripId: string; } export const deleteTrip = ({ tripId }: DeleteTripParams) => { diff --git a/frontend/src/api/trip/getTrip.ts b/frontend/src/api/trip/getTrip.ts index 35270be3b..48fea5b09 100644 --- a/frontend/src/api/trip/getTrip.ts +++ b/frontend/src/api/trip/getTrip.ts @@ -4,7 +4,7 @@ import type { TripData } from '@type/trip'; import { END_POINTS } from '@constants/api'; -export const getTrip = async (tripId: number) => { +export const getTrip = async (tripId: string) => { const { data } = await axiosInstance.get(END_POINTS.TRIP(tripId)); return data; diff --git a/frontend/src/api/trip/patchTripShareStatus.ts b/frontend/src/api/trip/patchTripShareStatus.ts index d77e8b000..03c53ac87 100644 --- a/frontend/src/api/trip/patchTripShareStatus.ts +++ b/frontend/src/api/trip/patchTripShareStatus.ts @@ -5,7 +5,7 @@ import type { TripData, TripSharedStatusData } from '@type/trip'; import { END_POINTS } from '@constants/api'; interface PatchTripSharedStatusParams extends TripSharedStatusData { - tripId: number; + tripId: string; } interface ResponseData { diff --git a/frontend/src/api/trip/putTrip.ts b/frontend/src/api/trip/putTrip.ts index b9b642a6d..7eeb6ce62 100644 --- a/frontend/src/api/trip/putTrip.ts +++ b/frontend/src/api/trip/putTrip.ts @@ -5,7 +5,7 @@ import type { TripFormData } from '@type/trip'; import { END_POINTS } from '@constants/api'; export interface PutTripParams extends TripFormData { - tripId: number; + tripId: string; } export const putTrip = ({ tripId, ...tripInformation }: PutTripParams) => { diff --git a/frontend/src/api/tripItem/deleteTripItem.ts b/frontend/src/api/tripItem/deleteTripItem.ts index 9f2fc5b14..b6f6de6ef 100644 --- a/frontend/src/api/tripItem/deleteTripItem.ts +++ b/frontend/src/api/tripItem/deleteTripItem.ts @@ -3,7 +3,7 @@ import { axiosInstance } from '@api/axiosInstance'; import { END_POINTS } from '@constants/api'; interface DeleteTripItemParams { - tripId: number; + tripId: string; itemId: number; } diff --git a/frontend/src/api/tripItem/postTripItem.ts b/frontend/src/api/tripItem/postTripItem.ts index 9172b16e4..6da104d23 100644 --- a/frontend/src/api/tripItem/postTripItem.ts +++ b/frontend/src/api/tripItem/postTripItem.ts @@ -5,7 +5,7 @@ import type { TripItemFormData } from '@type/tripItem'; import { END_POINTS } from '@constants/api'; export interface PostTripItemParams extends TripItemFormData { - tripId: number; + tripId: string; } export const postTripItem = ({ tripId, ...information }: PostTripItemParams) => { diff --git a/frontend/src/api/tripItem/putTripItem.ts b/frontend/src/api/tripItem/putTripItem.ts index 5e995a2c3..847d65f7a 100644 --- a/frontend/src/api/tripItem/putTripItem.ts +++ b/frontend/src/api/tripItem/putTripItem.ts @@ -5,7 +5,7 @@ import type { TripItemFormData } from '@type/tripItem'; import { END_POINTS } from '@constants/api'; interface PutTripItemParams extends TripItemFormData { - tripId: number; + tripId: string; itemId: number; } diff --git a/frontend/src/components/common/DayLogItem/DayLogItem.tsx b/frontend/src/components/common/DayLogItem/DayLogItem.tsx index 0d82c3be5..c4e676bf5 100644 --- a/frontend/src/components/common/DayLogItem/DayLogItem.tsx +++ b/frontend/src/components/common/DayLogItem/DayLogItem.tsx @@ -11,7 +11,7 @@ import type { DayLogData } from '@type/dayLog'; import { DAY_LOG_ITEM_FILTERS } from '@constants/trip'; interface DayLogItemProps extends DayLogData { - tripId: number; + tripId: string; isEditable?: boolean; isShared?: boolean; openAddModal?: () => void; diff --git a/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.tsx b/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.tsx index a70c2ca43..0fe36e684 100644 --- a/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.tsx +++ b/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.tsx @@ -8,7 +8,7 @@ import { useDayLogTitleMutation } from '@hooks/api/useDayLogTitleMutation'; import { DAYLOG_TITLE_MAX_LENGTH } from '@constants/ui'; interface TitleInputProps { - tripId: number; + tripId: string; dayLogId: number; initialTitle: string; } diff --git a/frontend/src/components/common/DayLogList/DayLogList.tsx b/frontend/src/components/common/DayLogList/DayLogList.tsx index fce658536..45c7a33f2 100644 --- a/frontend/src/components/common/DayLogList/DayLogList.tsx +++ b/frontend/src/components/common/DayLogList/DayLogList.tsx @@ -10,7 +10,7 @@ import { formatMonthDate } from '@utils/formatter'; import type { DayLogData } from '@type/dayLog'; interface DayLogListProps { - tripId: number; + tripId: string; selectedDayLog: DayLogData; isEditable?: boolean; isShared?: boolean; diff --git a/frontend/src/components/common/TripInformation/TripButtons/TripButtons.tsx b/frontend/src/components/common/TripInformation/TripButtons/TripButtons.tsx index e5e41a674..9f96d8616 100644 --- a/frontend/src/components/common/TripInformation/TripButtons/TripButtons.tsx +++ b/frontend/src/components/common/TripInformation/TripButtons/TripButtons.tsx @@ -21,7 +21,7 @@ import BinIcon from '@assets/svg/bin-icon.svg'; import EditIcon from '@assets/svg/edit-icon.svg'; interface TripButtonsProps { - tripId: number; + tripId: string; sharedCode: TripData['sharedCode']; isShared: boolean; } diff --git a/frontend/src/components/common/TripInformation/TripEditButtons/TripEditButtons.tsx b/frontend/src/components/common/TripInformation/TripEditButtons/TripEditButtons.tsx index ecdd36013..d5ddf60ec 100644 --- a/frontend/src/components/common/TripInformation/TripEditButtons/TripEditButtons.tsx +++ b/frontend/src/components/common/TripInformation/TripEditButtons/TripEditButtons.tsx @@ -5,7 +5,7 @@ import { Button } from 'hang-log-design-system'; import { editButtonStyling } from '@components/common/TripInformation/TripEditButtons/TripEditButtons.style'; interface TripEditButtonsProps { - tripId: number; + tripId: string; openEditModal?: () => void; } diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index e3f09f278..386969711 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -26,7 +26,7 @@ import { formatDate } from '@utils/formatter'; import DefaultThumbnail from '@assets/png/trip-information_default-thumbnail.png'; interface TripInformationProps { - tripId: number; + tripId: string; isEditable?: boolean; isShared?: boolean; } @@ -65,10 +65,10 @@ const TripInformation = ({ isEditable = true, isShared = false, tripId }: TripIn {isEditable ? ( - + ) : ( diff --git a/frontend/src/components/common/TripInformation/TripShareButton/TripShareButton.tsx b/frontend/src/components/common/TripInformation/TripShareButton/TripShareButton.tsx index bc8f77252..3d568c964 100644 --- a/frontend/src/components/common/TripInformation/TripShareButton/TripShareButton.tsx +++ b/frontend/src/components/common/TripInformation/TripShareButton/TripShareButton.tsx @@ -23,7 +23,7 @@ import { PATH } from '@constants/path'; import ShareIcon from '@assets/svg/share-icon.svg'; interface TripShareButtonProps { - tripId: number; + tripId: string; sharedCode: TripData['sharedCode']; } diff --git a/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx b/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx index 79f084dbb..2deb54d70 100644 --- a/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx +++ b/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx @@ -17,7 +17,7 @@ import BinIcon from '@assets/svg/bin-icon.svg'; import EditIcon from '@assets/svg/edit-icon.svg'; interface EditMenuProps extends TripItemData { - tripId: number; + tripId: string; dayLogId: number; hasImage: boolean; imageHeight: number; diff --git a/frontend/src/components/common/TripItem/TripItem.tsx b/frontend/src/components/common/TripItem/TripItem.tsx index 3b276bd3a..5dfc33499 100644 --- a/frontend/src/components/common/TripItem/TripItem.tsx +++ b/frontend/src/components/common/TripItem/TripItem.tsx @@ -34,7 +34,7 @@ import { CURRENCY_ICON } from '@constants/trip'; import { TRIP_ITEM_IMAGE_HEIGHT, TRIP_ITEM_IMAGE_WIDTH } from '@constants/ui'; interface TripListItemProps extends TripItemData { - tripId: number; + tripId: string; dayLogId: number; isEditable?: boolean; observer?: IntersectionObserver | null; diff --git a/frontend/src/components/common/TripItemList/TripItemList.tsx b/frontend/src/components/common/TripItemList/TripItemList.tsx index d084a690f..47a867093 100644 --- a/frontend/src/components/common/TripItemList/TripItemList.tsx +++ b/frontend/src/components/common/TripItemList/TripItemList.tsx @@ -24,7 +24,7 @@ import type { TripItemData } from '@type/tripItem'; import { PATH } from '@constants/path'; interface TripItemListProps { - tripId: number; + tripId: string; dayLogId: number; tripItems: TripItemData[]; isEditable?: boolean; @@ -86,7 +86,7 @@ const TripItemList = ({ tripId, dayLogId, tripItems, isEditable = true }: TripIt }; interface EmptyTripItemListProps { - tripId: number; + tripId: string; isEditable?: boolean; isShared?: boolean; openAddModal?: () => void; diff --git a/frontend/src/components/expense/ExpenseCategories/ExpenseCategories.tsx b/frontend/src/components/expense/ExpenseCategories/ExpenseCategories.tsx index 52edfe019..b8a8e326c 100644 --- a/frontend/src/components/expense/ExpenseCategories/ExpenseCategories.tsx +++ b/frontend/src/components/expense/ExpenseCategories/ExpenseCategories.tsx @@ -10,7 +10,7 @@ import { formatDate, formatNumberToMoney } from '@utils/formatter'; import { CURRENCY_ICON, DEFAULT_CURRENCY } from '@constants/trip'; interface ExpenseCategoriesProps { - tripId: number; + tripId: string; } const ExpenseCategories = ({ tripId }: ExpenseCategoriesProps) => { diff --git a/frontend/src/components/expense/ExpenseCategoryInformation/ExpenseCategoryInformation.tsx b/frontend/src/components/expense/ExpenseCategoryInformation/ExpenseCategoryInformation.tsx index cb481337a..2f8b31e46 100644 --- a/frontend/src/components/expense/ExpenseCategoryInformation/ExpenseCategoryInformation.tsx +++ b/frontend/src/components/expense/ExpenseCategoryInformation/ExpenseCategoryInformation.tsx @@ -14,7 +14,7 @@ import { formatNumberToMoney } from '@utils/formatter'; import { CURRENCY_ICON, DEFAULT_CURRENCY } from '@constants/trip'; interface ExpenseCategoryInformationProps { - tripId: number; + tripId: string; } const ExpenseCategoryInformation = ({ tripId }: ExpenseCategoryInformationProps) => { diff --git a/frontend/src/components/expense/ExpenseDates/ExpenseDates.tsx b/frontend/src/components/expense/ExpenseDates/ExpenseDates.tsx index cd59d5a1a..154d06dd7 100644 --- a/frontend/src/components/expense/ExpenseDates/ExpenseDates.tsx +++ b/frontend/src/components/expense/ExpenseDates/ExpenseDates.tsx @@ -10,7 +10,7 @@ import { formatDate, formatMonthDate, formatNumberToMoney } from '@utils/formatt import { CURRENCY_ICON, DEFAULT_CURRENCY } from '@constants/trip'; interface ExpenseDatesProps { - tripId: number; + tripId: string; } const ExpenseDates = ({ tripId }: ExpenseDatesProps) => { diff --git a/frontend/src/components/expense/ExpenseInformation/ExpenseInformation.tsx b/frontend/src/components/expense/ExpenseInformation/ExpenseInformation.tsx index c7ca6f17e..cc0c2f263 100644 --- a/frontend/src/components/expense/ExpenseInformation/ExpenseInformation.tsx +++ b/frontend/src/components/expense/ExpenseInformation/ExpenseInformation.tsx @@ -20,7 +20,7 @@ import { formatDate } from '@utils/formatter'; import { PATH } from '@constants/path'; interface ExpenseInformationProps { - tripId: number; + tripId: string; isShared: boolean; } diff --git a/frontend/src/components/expense/ExpenseList/ExpenseList.tsx b/frontend/src/components/expense/ExpenseList/ExpenseList.tsx index 84a84cc7e..9bece5640 100644 --- a/frontend/src/components/expense/ExpenseList/ExpenseList.tsx +++ b/frontend/src/components/expense/ExpenseList/ExpenseList.tsx @@ -37,7 +37,7 @@ const ExpenseList = ({ items }: ExpenseListProps) => { export default ExpenseList; -ExpenseList.Empty = ({ tripId }: { tripId: number }) => { +ExpenseList.Empty = ({ tripId }: { tripId: string }) => { // eslint-disable-next-line react-hooks/rules-of-hooks const navigate = useNavigate(); diff --git a/frontend/src/components/expense/ExpenseListSection/ExpenseListSection.tsx b/frontend/src/components/expense/ExpenseListSection/ExpenseListSection.tsx index f4c0b1a60..3ab30f4a2 100644 --- a/frontend/src/components/expense/ExpenseListSection/ExpenseListSection.tsx +++ b/frontend/src/components/expense/ExpenseListSection/ExpenseListSection.tsx @@ -14,7 +14,7 @@ import { mediaQueryMobileState } from '@store/mediaQuery'; import { EXPENSE_LIST_FILTERS } from '@constants/expense'; interface ExpenseListProps { - tripId: number; + tripId: string; } const ExpenseListSection = ({ tripId }: ExpenseListProps) => { diff --git a/frontend/src/components/expense/TotalExpenseSection/TotalExpenseSection.tsx b/frontend/src/components/expense/TotalExpenseSection/TotalExpenseSection.tsx index c12b5a449..e7ac287aa 100644 --- a/frontend/src/components/expense/TotalExpenseSection/TotalExpenseSection.tsx +++ b/frontend/src/components/expense/TotalExpenseSection/TotalExpenseSection.tsx @@ -20,7 +20,7 @@ import { CURRENCY_ICON, DEFAULT_CURRENCY } from '@constants/trip'; import { EXPENSE_CATEGORY_CHART_SIZE, EXPENSE_CATEGORY_CHART_STROKE_WIDTH } from '@constants/ui'; interface TotalExpenseSectionProps { - tripId: number; + tripId: string; isShared: boolean; } @@ -31,7 +31,7 @@ const TotalExpenseSection = ({ tripId, isShared }: TotalExpenseSectionProps) => return (
- + 총 경비 :{' '} diff --git a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx index de4f1fe5d..c1c2cd04f 100644 --- a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx +++ b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx @@ -14,7 +14,7 @@ import type { TripItemFormData } from '@type/tripItem'; interface DateInputProps { currentCategory: TripItemFormData['itemType']; - tripId: number; + tripId: string; dayLogId: number; updateInputValue: (key: K, value: TripItemFormData[K]) => void; } diff --git a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx index 1d56154c2..2e72cee0e 100644 --- a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx +++ b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx @@ -23,7 +23,7 @@ import { mediaQueryMobileState } from '@store/mediaQuery'; import type { TripItemFormData } from '@type/tripItem'; interface TripItemAddModalProps { - tripId: number; + tripId: string; dayLogId: number; itemId?: number; initialData?: TripItemFormData; diff --git a/frontend/src/constants/api.ts b/frontend/src/constants/api.ts index 9666e57a4..83d43e5c0 100644 --- a/frontend/src/constants/api.ts +++ b/frontend/src/constants/api.ts @@ -10,23 +10,23 @@ export const AXIOS_BASE_URL = PROD export const END_POINTS = { TRIPS: '/trips', - TRIP: (tripId: number) => `/trips/${tripId}`, - DAY_LOG: (tripId: number, dayLogId: number) => `/trips/${tripId}/daylogs/${dayLogId}`, - DAY_LOG_ORDER: (tripId: number, dayLogId: number) => `/trips/${tripId}/daylogs/${dayLogId}/order`, - CREATE_TRIP_ITEM: (tripId: number) => `/trips/${tripId}/items`, - CHANGE_TRIP_ITEM: (tripId: number, itemId: number) => `/trips/${tripId}/items/${itemId}`, + TRIP: (tripId: string) => `/trips/${tripId}`, + DAY_LOG: (tripId: string, dayLogId: number) => `/trips/${tripId}/daylogs/${dayLogId}`, + DAY_LOG_ORDER: (tripId: string, dayLogId: number) => `/trips/${tripId}/daylogs/${dayLogId}/order`, + CREATE_TRIP_ITEM: (tripId: string) => `/trips/${tripId}/items`, + CHANGE_TRIP_ITEM: (tripId: string, itemId: number) => `/trips/${tripId}/items/${itemId}`, CITY: '/cities', EXPENSE_CATEGORY: '/categories', - EXPENSE: (tripId: number | string) => `/trips/${tripId}/expense`, + EXPENSE: (tripId: string) => `/trips/${tripId}/expense`, IMAGES: '/images', - SHARE: (tripId: number | string) => `/trips/${tripId}/share`, + SHARE: (tripId: string) => `/trips/${tripId}/share`, TOKEN: '/token', LOGIN: (provider: string) => `/login/${provider}`, LOGOUT: '/logout', MY_PAGE: '/mypage', ACCOUNT: '/account', SHARED_TRIP: (code: string | number) => `/shared-trips/${code}`, - SHARED_EXPENSE: (tripId: string | number) => `/shared-trips/${tripId}/expense`, + SHARED_EXPENSE: (tripId: string) => `/shared-trips/${tripId}/expense`, } as const; export const NETWORK = { diff --git a/frontend/src/constants/path.ts b/frontend/src/constants/path.ts index 3ed5807d6..629ff0ec5 100644 --- a/frontend/src/constants/path.ts +++ b/frontend/src/constants/path.ts @@ -1,11 +1,11 @@ export const PATH = { ROOT: '/', CREATE_TRIP: '/trip-new', - EDIT_TRIP: (tripId: number | string) => `/trip/${tripId}/edit`, - TRIP: (tripId: number | string) => `/trip/${tripId}`, - EXPENSE: (tripId: number | string) => `/trip/${tripId}/expense`, - SHARE_TRIP: (shareCode: string | number) => `/trip/share/${shareCode}`, - SHARE_EXPENSE: (tripId: number | string) => `/trip/share/expense/${tripId}`, + EDIT_TRIP: (tripId: string) => `/trip/${tripId}/edit`, + TRIP: (tripId: string) => `/trip/${tripId}`, + EXPENSE: (tripId: string) => `/trip/${tripId}/expense`, + SHARE_TRIP: (tripId: string) => `/trip/share/${tripId}`, + SHARE_EXPENSE: (tripId: string) => `/trip/share/expense/${tripId}`, LOGIN: '/login', MY_PAGE: '/my-page', REDIRECT: '/auth/:provider', diff --git a/frontend/src/hooks/api/useExpenseQuery.ts b/frontend/src/hooks/api/useExpenseQuery.ts index d0cdd620a..a2d588a50 100644 --- a/frontend/src/hooks/api/useExpenseQuery.ts +++ b/frontend/src/hooks/api/useExpenseQuery.ts @@ -8,10 +8,10 @@ import { getExpense } from '@api/expense/getExpense'; import type { ExpenseData } from '@type/expense'; -export const useExpenseQuery = (tripId: number, isShared = false) => { +export const useExpenseQuery = (tripId: string, isShared = false) => { const { data } = useQuery( ['expense', tripId], - !isShared ? () => getExpense(tripId) : () => getSharedExpense(String(tripId)) + !isShared ? () => getExpense(tripId) : () => getSharedExpense(tripId) ); return { expenseData: data! }; diff --git a/frontend/src/hooks/api/useLogInMutation.ts b/frontend/src/hooks/api/useLogInMutation.ts index d83bb7e1b..ffd6792e1 100644 --- a/frontend/src/hooks/api/useLogInMutation.ts +++ b/frontend/src/hooks/api/useLogInMutation.ts @@ -27,12 +27,13 @@ export const useLogInMutation = () => { axiosInstance.defaults.headers.Authorization = `Bearer ${accessToken}`; setIsLoggedIn(true); - navigate(-2); }, onError: () => { setIsLoggedIn(false); createToast('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); + }, + onSettled: () => { navigate(PATH.ROOT); }, }); diff --git a/frontend/src/hooks/api/useSharedTripQuery.ts b/frontend/src/hooks/api/useSharedTripQuery.ts index fd2f69053..8e25ec0a1 100644 --- a/frontend/src/hooks/api/useSharedTripQuery.ts +++ b/frontend/src/hooks/api/useSharedTripQuery.ts @@ -7,9 +7,7 @@ import { getSharedTrip } from '@api/trip/getSharedTrip'; import type { TripData } from '@type/trip'; export const useSharedQuery = (code: string) => { - const { data } = useQuery(['trip', Number(code)], () => - getSharedTrip(code) - ); + const { data } = useQuery(['trip', code], () => getSharedTrip(code)); return { tripData: data! }; }; diff --git a/frontend/src/hooks/api/useTripEditPageQueries.ts b/frontend/src/hooks/api/useTripEditPageQueries.ts index cd5881f0a..ec1c3ba41 100644 --- a/frontend/src/hooks/api/useTripEditPageQueries.ts +++ b/frontend/src/hooks/api/useTripEditPageQueries.ts @@ -3,7 +3,7 @@ import { useQueries } from '@tanstack/react-query'; import { getExpenseCategory } from '@api/expense/getExpenseCategory'; import { getTrip } from '@api/trip/getTrip'; -export const useTripEditPageQueries = (tripId: number) => { +export const useTripEditPageQueries = (tripId: string) => { const [tripQuery, expenseCategoryQuery] = useQueries({ queries: [ { queryKey: ['trip', tripId], queryFn: () => getTrip(tripId) }, diff --git a/frontend/src/hooks/api/useTripQuery.ts b/frontend/src/hooks/api/useTripQuery.ts index d1412faa5..6b8ce94f9 100644 --- a/frontend/src/hooks/api/useTripQuery.ts +++ b/frontend/src/hooks/api/useTripQuery.ts @@ -1,3 +1,5 @@ +import { getSharedTrip } from '@/api/trip/getSharedTrip'; + import { useQuery } from '@tanstack/react-query'; import type { AxiosError } from 'axios'; @@ -6,8 +8,11 @@ import { getTrip } from '@api/trip/getTrip'; import type { TripData } from '@type/trip'; -export const useTripQuery = (tripId: number) => { - const { data } = useQuery(['trip', tripId], () => getTrip(tripId)); +export const useTripQuery = (tripId: string, isShared: boolean = false) => { + const { data } = useQuery( + ['trip', tripId], + isShared ? () => getSharedTrip(tripId) : () => getTrip(tripId) + ); return { tripData: data! }; }; diff --git a/frontend/src/hooks/expense/useExpense.ts b/frontend/src/hooks/expense/useExpense.ts index 636a8bd2e..78f761ac1 100644 --- a/frontend/src/hooks/expense/useExpense.ts +++ b/frontend/src/hooks/expense/useExpense.ts @@ -8,7 +8,7 @@ import type { ExpenseData, ExpenseItemData } from '@type/expense'; import { EXPENSE_CHART_COLORS } from '@constants/expense'; -export const useExpense = (tripId: number) => { +export const useExpense = (tripId: string) => { const queryClient = useQueryClient(); const expenseData = queryClient.getQueryData(['expense', tripId])!; diff --git a/frontend/src/hooks/trip/useAddTripItemForm.ts b/frontend/src/hooks/trip/useAddTripItemForm.ts index 434cb3f33..d43c31380 100644 --- a/frontend/src/hooks/trip/useAddTripItemForm.ts +++ b/frontend/src/hooks/trip/useAddTripItemForm.ts @@ -10,7 +10,7 @@ import { isEmptyString } from '@utils/validator'; import type { TripItemFormData } from '@type/tripItem'; interface UseAddTripItemFormParams { - tripId: number; + tripId: string; initialDayLogId: number; itemId?: number; initialData?: TripItemFormData; diff --git a/frontend/src/hooks/trip/useTrip.ts b/frontend/src/hooks/trip/useTrip.ts index b99522174..61b45216d 100644 --- a/frontend/src/hooks/trip/useTrip.ts +++ b/frontend/src/hooks/trip/useTrip.ts @@ -2,9 +2,8 @@ import { useQueryClient } from '@tanstack/react-query'; import type { TripData } from '@type/trip'; -export const useTrip = (tripId: number) => { +export const useTrip = (tripId: string) => { const queryClient = useQueryClient(); - const tripData = queryClient.getQueryData(['trip', tripId])!; const dates = tripData.dayLogs.map((data) => ({ diff --git a/frontend/src/hooks/trip/useTripEditForm.ts b/frontend/src/hooks/trip/useTripEditForm.ts index 5f57bcb14..4ab927b22 100644 --- a/frontend/src/hooks/trip/useTripEditForm.ts +++ b/frontend/src/hooks/trip/useTripEditForm.ts @@ -77,7 +77,7 @@ export const useTripEditForm = ( tripEditMutation.mutate( { ...tripInfo, - tripId, + tripId: String(tripId), startDate: tripInfo.startDate!, endDate: tripInfo.endDate!, }, diff --git a/frontend/src/pages/ExpensePage/ExpensePage.tsx b/frontend/src/pages/ExpensePage/ExpensePage.tsx index 6c2afab3d..59919ba6f 100644 --- a/frontend/src/pages/ExpensePage/ExpensePage.tsx +++ b/frontend/src/pages/ExpensePage/ExpensePage.tsx @@ -24,13 +24,13 @@ const ExpensePage = ({ isShared = false }: ExpensePageProps) => { const isMobile = useRecoilValue(mediaQueryMobileState); - const { expenseData } = useExpenseQuery(Number(tripId), isShared); + const { expenseData } = useExpenseQuery(tripId, isShared); return ( - + {isMobile && } - + ); }; diff --git a/frontend/src/pages/SharedPage/SharedTripPage.tsx b/frontend/src/pages/SharedPage/SharedTripPage.tsx index 86937e2eb..6c8fc33f9 100644 --- a/frontend/src/pages/SharedPage/SharedTripPage.tsx +++ b/frontend/src/pages/SharedPage/SharedTripPage.tsx @@ -1,3 +1,5 @@ +import { useTripQuery } from '@/hooks/api/useTripQuery'; + import { useMemo } from 'react'; import { useParams } from 'react-router-dom'; @@ -12,16 +14,14 @@ import GoogleMapWrapper from '@components/common/GoogleMapWrapper/GoogleMapWrapp import TripInformation from '@components/common/TripInformation/TripInformation'; import TripMap from '@components/common/TripMap/TripMap'; -import { useSharedQuery } from '@hooks/api/useSharedTripQuery'; - import { mediaQueryMobileState } from '@store/mediaQuery'; const SharedTripPage = () => { - const { code } = useParams(); + const { tripId } = useParams(); - if (!code) throw new Error('존재하지 않는 공유코드입니다.'); + if (!tripId) throw new Error('존재하지 않는 공유코드입니다.'); - const { tripData } = useSharedQuery(code); + const { tripData } = useTripQuery(tripId, true); const isMobile = useRecoilValue(mediaQueryMobileState); @@ -45,9 +45,9 @@ const SharedTripPage = () => { return (
- + { const isMobile = useRecoilValue(mediaQueryMobileState); - const { tripData } = useTripEditPageQueries(Number(tripId)); + const { tripData } = useTripEditPageQueries(tripId); const { isOpen: isAddModalOpen, open: openAddModal, close: closeAddModal } = useOverlay(); const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( @@ -51,9 +51,9 @@ const TripEditPage = () => { return (
- + { onClick={openAddModal} /> {isAddModalOpen && ( - + )}
{!isMobile && ( diff --git a/frontend/src/pages/TripPage/TripMobilePage.tsx b/frontend/src/pages/TripPage/TripMobilePage.tsx index bbe381bed..af1a654e3 100644 --- a/frontend/src/pages/TripPage/TripMobilePage.tsx +++ b/frontend/src/pages/TripPage/TripMobilePage.tsx @@ -1,3 +1,5 @@ +import { useTrip } from '@/hooks/trip/useTrip'; + import { useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -17,7 +19,6 @@ import TripInformation from '@components/common/TripInformation/TripInformation' import TripMap from '@components/common/TripMap/TripMap'; import { useTripQuery } from '@hooks/api/useTripQuery'; -import { useTrip } from '@hooks/trip/useTrip'; import { formatMonthDate } from '@utils/formatter'; @@ -29,13 +30,15 @@ const TripMobilePage = ({ isShared = false }: TripMobilePageProps) => { const [isDaylogShown, setIsDaylogShown] = useState(true); const { tripId } = useParams(); - const { tripData } = useTripQuery(Number(tripId)); + if (!tripId) throw new Error('존재하지 않는 tripId 입니다'); + + const { tripData } = useTripQuery(tripId, isShared); + const { dates } = useTrip(tripId); const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( tripData.dayLogs[0].id ); const selectedDayLog = tripData.dayLogs.find((log) => log.id === selectedDayLogId)!; - const { dates } = useTrip(Number(tripId)); const places = useMemo( () => @@ -52,7 +55,7 @@ const TripMobilePage = ({ isShared = false }: TripMobilePageProps) => { return (
- +
{dates.map((date, index) => { @@ -76,7 +79,7 @@ const TripMobilePage = ({ isShared = false }: TripMobilePageProps) => { {isDaylogShown && ( { if (!tripId) throw new Error('존재하지 않는 tripId 입니다.'); - const { tripData } = useTripQuery(Number(tripId)); + const { tripData } = useTripQuery(tripId); const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( tripData.dayLogs[0].id @@ -39,9 +39,9 @@ const TripPage = () => { return (
- + { ), }, { - path: PATH.SHARE_TRIP(':code'), + path: PATH.SHARE_TRIP(':tripId'), element: ( }> {isMobile ? : } diff --git a/frontend/src/stories/common/DayLogItem.stories.tsx b/frontend/src/stories/common/DayLogItem.stories.tsx index 114a82bd4..dc5ee68c6 100644 --- a/frontend/src/stories/common/DayLogItem.stories.tsx +++ b/frontend/src/stories/common/DayLogItem.stories.tsx @@ -11,7 +11,7 @@ const meta = { tripId: { control: false }, }, args: { - tripId: 1, + tripId: '1', ...trip.dayLogs[0], }, } satisfies Meta; diff --git a/frontend/src/stories/common/DayLogList.stories.tsx b/frontend/src/stories/common/DayLogList.stories.tsx index fb8378ecd..f18826403 100644 --- a/frontend/src/stories/common/DayLogList.stories.tsx +++ b/frontend/src/stories/common/DayLogList.stories.tsx @@ -22,13 +22,13 @@ type Story = StoryObj; export const Default: Story = { render: () => { - useTripQuery(1); + useTripQuery('1'); const { selected, handleSelectClick } = useSelect(trip.dayLogs[0].id); const selectedDayLog = trip.dayLogs.find((log) => log.id === selected)!; return ( {}} @@ -36,7 +36,7 @@ export const Default: Story = { ); }, args: { - tripId: 1, + tripId: '1', selectedDayLog: trip.dayLogs[0], onTabChange: () => {}, }, diff --git a/frontend/src/stories/common/TripInformation.stories.tsx b/frontend/src/stories/common/TripInformation.stories.tsx index e6666adb0..288dc53a0 100644 --- a/frontend/src/stories/common/TripInformation.stories.tsx +++ b/frontend/src/stories/common/TripInformation.stories.tsx @@ -7,10 +7,10 @@ import { useTripQuery } from '@hooks/api/useTripQuery'; const meta = { title: 'common/TripInformation', component: TripInformation, - args: { tripId: 1 }, + args: { tripId: '1' }, decorators: [ (Story) => { - useTripQuery(1); + useTripQuery('1'); return ; }, diff --git a/frontend/src/stories/common/TripItem.stories.tsx b/frontend/src/stories/common/TripItem.stories.tsx index be7633c4e..980a7e6f8 100644 --- a/frontend/src/stories/common/TripItem.stories.tsx +++ b/frontend/src/stories/common/TripItem.stories.tsx @@ -8,7 +8,7 @@ const meta = { title: 'common/TripItem', component: TripItem, args: { - tripId: 1, + tripId: '1', dayLogId: 1, }, } satisfies Meta; diff --git a/frontend/src/stories/common/TripItemList.stories.tsx b/frontend/src/stories/common/TripItemList.stories.tsx index 3b33aa7cb..d782d0ec6 100644 --- a/frontend/src/stories/common/TripItemList.stories.tsx +++ b/frontend/src/stories/common/TripItemList.stories.tsx @@ -12,7 +12,7 @@ const meta = { dayLogId: { control: false }, }, args: { - tripId: 1, + tripId: '1', dayLogId: 1, tripItems: [...trip.dayLogs[0].items], }, diff --git a/frontend/src/stories/expense/ExpenseCategories.stories.tsx b/frontend/src/stories/expense/ExpenseCategories.stories.tsx index 900ed7ae7..72b871302 100644 --- a/frontend/src/stories/expense/ExpenseCategories.stories.tsx +++ b/frontend/src/stories/expense/ExpenseCategories.stories.tsx @@ -8,11 +8,11 @@ const meta = { title: 'expense/ExpenseCategories', component: ExpenseCategories, args: { - tripId: 1, + tripId: '1', }, decorators: [ (Story) => { - useExpenseQuery(1); + useExpenseQuery('1'); return ; }, diff --git a/frontend/src/stories/expense/ExpenseCategoryInformation.stories.tsx b/frontend/src/stories/expense/ExpenseCategoryInformation.stories.tsx index 8e5d6da5c..55b1696a6 100644 --- a/frontend/src/stories/expense/ExpenseCategoryInformation.stories.tsx +++ b/frontend/src/stories/expense/ExpenseCategoryInformation.stories.tsx @@ -8,11 +8,11 @@ const meta = { title: 'expense/ExpenseCategoryInformation', component: ExpenseCategoryInformation, args: { - tripId: 1, + tripId: '1', }, decorators: [ (Story) => { - useExpenseQuery(1); + useExpenseQuery('1'); return ; }, diff --git a/frontend/src/stories/expense/ExpenseDates.stories.tsx b/frontend/src/stories/expense/ExpenseDates.stories.tsx index 1087403de..bddace64c 100644 --- a/frontend/src/stories/expense/ExpenseDates.stories.tsx +++ b/frontend/src/stories/expense/ExpenseDates.stories.tsx @@ -8,11 +8,11 @@ const meta = { title: 'expense/ExpenseDates', component: ExpenseDates, args: { - tripId: 1, + tripId: '1', }, decorators: [ (Story) => { - useExpenseQuery(1); + useExpenseQuery('1'); return ; }, diff --git a/frontend/src/stories/expense/ExpenseInformation.stories.tsx b/frontend/src/stories/expense/ExpenseInformation.stories.tsx index d6a482387..582484389 100644 --- a/frontend/src/stories/expense/ExpenseInformation.stories.tsx +++ b/frontend/src/stories/expense/ExpenseInformation.stories.tsx @@ -8,12 +8,12 @@ const meta = { title: 'expense/ExpenseInformation', component: ExpenseInformation, args: { - tripId: 1, + tripId: '1', isShared: false, }, decorators: [ (Story) => { - useExpenseQuery(1); + useExpenseQuery('1'); return ; }, diff --git a/frontend/src/stories/expense/ExpenseList.stories.tsx b/frontend/src/stories/expense/ExpenseList.stories.tsx index 6b4ce537e..f4aed79ef 100644 --- a/frontend/src/stories/expense/ExpenseList.stories.tsx +++ b/frontend/src/stories/expense/ExpenseList.stories.tsx @@ -18,5 +18,5 @@ type Story = StoryObj; export const Default: Story = {}; export const Empty: Story = { - render: () => , + render: () => , }; diff --git a/frontend/src/stories/expense/ExpenseListSection.stories.tsx b/frontend/src/stories/expense/ExpenseListSection.stories.tsx index 6725882ea..7fb8e0717 100644 --- a/frontend/src/stories/expense/ExpenseListSection.stories.tsx +++ b/frontend/src/stories/expense/ExpenseListSection.stories.tsx @@ -9,7 +9,7 @@ const meta = { tripId: { control: false }, }, args: { - tripId: 1, + tripId: '1', }, } satisfies Meta; diff --git a/frontend/src/stories/expense/TotalExpenseSection.stories.tsx b/frontend/src/stories/expense/TotalExpenseSection.stories.tsx index 2a8e43323..ffca88a5c 100644 --- a/frontend/src/stories/expense/TotalExpenseSection.stories.tsx +++ b/frontend/src/stories/expense/TotalExpenseSection.stories.tsx @@ -11,12 +11,12 @@ const meta = { tripId: { control: false }, }, args: { - tripId: 1, + tripId: '1', isShared: false, }, decorators: [ (Story) => { - useExpenseQuery(1); + useExpenseQuery('1'); return ; }, diff --git a/frontend/src/stories/trip/DateInput.stories.tsx b/frontend/src/stories/trip/DateInput.stories.tsx index a6746e73c..a279a7d77 100644 --- a/frontend/src/stories/trip/DateInput.stories.tsx +++ b/frontend/src/stories/trip/DateInput.stories.tsx @@ -13,12 +13,12 @@ const meta = { }, args: { currentCategory: true, - tripId: 1, + tripId: '1', dayLogId: 1, }, decorators: [ (Story) => { - useTripQuery(1); + useTripQuery('1'); return ; }, diff --git a/frontend/src/stories/trip/TripItemAddModal.stories.tsx b/frontend/src/stories/trip/TripItemAddModal.stories.tsx index 890f99727..f0737ac1c 100644 --- a/frontend/src/stories/trip/TripItemAddModal.stories.tsx +++ b/frontend/src/stories/trip/TripItemAddModal.stories.tsx @@ -11,13 +11,13 @@ const meta = { title: 'trip/TripItemAddModal', component: TripItemAddModal, args: { - tripId: 1, + tripId: '1', dayLogId: 1, onClose: () => {}, }, decorators: [ (Story) => { - useTripQuery(1); + useTripQuery('1'); useExpenseCategoryQuery(); return ;