Skip to content

Commit

Permalink
feat: created club page and implemented api endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
peageon committed Jul 17, 2024
1 parent 421bede commit a2f4b2d
Show file tree
Hide file tree
Showing 16 changed files with 651 additions and 10 deletions.
25 changes: 20 additions & 5 deletions src/main/java/com/runningmate/backend/club/Club.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package com.runningmate.backend.club;

import com.runningmate.backend.entity.BaseTimeEntity;
import com.runningmate.backend.member.Member;
import jakarta.persistence.*;
import lombok.*;
import org.locationtech.jts.geom.Point;

import java.util.*;

//게시판, 일정, 멤버(클럽장, 부클럽장등등 역할), 순위, 채팅방, 위치, 배경사진, 클럽 사진,
@Entity
@Getter
@Table(name = "club")
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Club {
public class Club extends BaseTimeEntity {
public static final String DEFAULT_BACKGROUND_PIC = "https://storage.googleapis.com/runningmate-bucket/Screenshot%202024-06-20%20at%203.46.14%E2%80%AFPM.png";

@Id
Expand All @@ -23,7 +23,8 @@ public class Club {
private UUID id;

private String title; //TODO: updateTitle method
private String detail; //TODO: updateDetail method

private String description; //TODO: updateDetail method

@Column(columnDefinition = "geography(Point, 4326)")
private Point location;
Expand All @@ -38,15 +39,15 @@ public class Club {

@OneToMany(mappedBy = "club", cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
private Set<ClubMemberEntity> members = new HashSet<>();
private List<ClubMemberEntity> members = new ArrayList<>();

// @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
// @Builder.Default
// private List<ClubPostEntity> posts = new ArrayList<>();

@OneToMany(mappedBy = "club", cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
private List<ClubScheduleEntity> clubs = new ArrayList<>();
private List<ClubScheduleEntity> schedules = new ArrayList<>();

public void updateProfilePic(String url) {
this.profile_pic = url;
Expand All @@ -55,4 +56,18 @@ public void updateProfilePic(String url) {
public void updateBackgroundPic(String url) {
this.background_pic = url;
}

public void addMember(ClubMemberEntity clubMemberEntity) {
this.members.add(clubMemberEntity);
}

public void removeMember(ClubMemberEntity clubMemberEntity) { this.members.remove(clubMemberEntity);}

public void addClubSchedule(ClubScheduleEntity clubScheduleEntity) { this.schedules.add(clubScheduleEntity);}

public void removeClubSchedule(ClubScheduleEntity clubScheduleEntity) { this.schedules.remove(clubScheduleEntity);}

public void updateTitle(String title) { this.title = title;}

public void updateDescription(String description) { this.description = description;}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class ClubMemberEntity {
@Builder.Default
private ClubRole role = ClubRole.MEMBER;


public void changeRole(ClubRole clubRole) {
this.role = clubRole;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.runningmate.backend.club;

import com.runningmate.backend.member.Member;
import com.runningmate.backend.club.dto.CreateOrUpdateClubScheduleRequestDto;
import com.runningmate.backend.schedule.Schedule;
import jakarta.persistence.*;
import lombok.*;
Expand All @@ -24,4 +24,8 @@ public class ClubScheduleEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "club_id")
private Club club;

public void update(CreateOrUpdateClubScheduleRequestDto updateDto) {
this.schedule.update(updateDto.getCreateOrUpdateScheduleRequestDto());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package com.runningmate.backend.club.controller;

import com.runningmate.backend.club.dto.*;
import com.runningmate.backend.club.service.ClubService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/club")
@RequiredArgsConstructor
public class ClubController {
/*TODO: join club(check already in), leave club(owner can't leave), delete club, change owner,
remove member, update title/description, get club info, create new schedule, update schedule
*/
private final ClubService clubService;

@PostMapping
@ResponseStatus(value = HttpStatus.CREATED)
public ClubResponseDto createNewClub(@RequestBody ClubRequestDto clubRequestDto,
@AuthenticationPrincipal UserDetails userDetails) {
ClubResponseDto clubResponseDto = clubService.createClub(clubRequestDto, userDetails.getUsername());
return clubResponseDto;
}

@GetMapping("/{clubId}")
@ResponseStatus(value = HttpStatus.OK)
public ClubResponseDto getClub(@PathVariable(name = "clubId") UUID clubId,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.getClub(clubId);
}

@GetMapping("/{clubId}/schedules")
@ResponseStatus(value = HttpStatus.OK)
public ListClubScheduleEntityResponseDto getClubSchedules(@PathVariable(name = "clubId") UUID clubId,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.getClubSchedules(clubId, userDetails.getUsername());
}

@PostMapping("/{clubId}/schedules")
@ResponseStatus(HttpStatus.OK)
public ClubScheduleEntityResponseDto createClubSchedule(@PathVariable(name = "clubId") UUID clubId,
@Valid @RequestBody CreateOrUpdateClubScheduleRequestDto requestDto,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.createClubSchedule(requestDto, clubId, userDetails.getUsername());
}

@PutMapping("/{clubId}/schedules/{scheduleId}")
@ResponseStatus(HttpStatus.OK)
public ClubScheduleEntityResponseDto updateClubSchedule(@PathVariable(name = "clubId") UUID clubId,
@Valid @RequestBody CreateOrUpdateClubScheduleRequestDto requestDto,
@PathVariable(name = "scheduleId") Long scheduleId,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.updateClubSchedule(requestDto, clubId, scheduleId, userDetails.getUsername());
}

@DeleteMapping("/{clubId}/schedules/{scheduleId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void removeClubSchedule(@PathVariable(name = "clubId") UUID clubId,
@PathVariable(name = "scheduleId") Long scheduleId,
@AuthenticationPrincipal UserDetails userDetails) {
clubService.removeClubSchedule(clubId, scheduleId, userDetails.getUsername());
}

@DeleteMapping("/{clubId}/delete")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void removeClub(@PathVariable(name = "clubId") UUID clubId,
@AuthenticationPrincipal UserDetails userDetails) {
clubService.removeClub(clubId, userDetails.getUsername());
}

@PutMapping("/{clubId}/members/{memberId}/role")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void changeMemberRole(@PathVariable(name = "clubId") UUID clubId,
@PathVariable(name = "memberId") Long memberId,
@Valid @RequestBody ChangeRoleRequestDto changeRoleDto,
@AuthenticationPrincipal UserDetails userDetails) {
clubService.changeMemberRole(changeRoleDto, clubId, memberId, userDetails.getUsername());
}

@DeleteMapping("/{clubId}/members/{membersId}")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void removeMemberFromClub(@PathVariable(name = "clubId") UUID clubId,
@PathVariable(name = "memberId") Long memberId,
@AuthenticationPrincipal UserDetails userDetails) {
clubService.removeMemberFromClub(clubId, memberId, userDetails.getUsername());
}

@PostMapping("/{clubId}/join")
@ResponseStatus(value = HttpStatus.CREATED)
public ClubResponseDto joinClub(@PathVariable(name = "clubId") UUID clubId,
@AuthenticationPrincipal UserDetails userDetails) {
ClubResponseDto clubResponseDto = clubService.addUserToClub(clubId, userDetails.getUsername());
return clubResponseDto;
}

@DeleteMapping("/{clubId}/leave")
@ResponseStatus(value = HttpStatus.OK)
public ClubResponseDto leaveClub(@PathVariable(name = "clubId") UUID clubId,
@AuthenticationPrincipal UserDetails userDetails) {
ClubResponseDto clubResponseDto = clubService.removeSelfFromClub(clubId, userDetails.getUsername());
return clubResponseDto;
}

@PutMapping("/{clubId}/title-description")
@ResponseStatus(HttpStatus.OK)
public ClubResponseDto updateTitleAndDescription(@PathVariable(name = "clubId") UUID clubId,
@Valid @RequestBody UpdateTitleDescriptionRequestDto updateDto,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.updateTitleAndDescription(clubId, updateDto, userDetails.getUsername());
}


@PutMapping("/{clubId}/profile-pic")
@ResponseStatus(HttpStatus.OK)
public ClubResponseDto updateProfilePic(@PathVariable(name = "clubId") UUID clubId,
@Valid @RequestBody UploadImageRequestDto newImageDto,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.updateProfilePic(clubId, newImageDto.getNewImageUrl(), userDetails.getUsername());
}

@PutMapping("/{clubId}/background-pic")
@ResponseStatus(HttpStatus.OK)
public ClubResponseDto updateBackgroundPic(@PathVariable(name = "clubId") UUID clubId,
@Valid @RequestBody UploadImageRequestDto newImageDto,
@AuthenticationPrincipal UserDetails userDetails) {
return clubService.updateBackgroundPic(clubId, newImageDto.getNewImageUrl(), userDetails.getUsername());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.runningmate.backend.club.dto;

import com.runningmate.backend.club.ClubRole;
import com.runningmate.backend.validation.ValidEnum;
import jakarta.validation.constraints.NotNull;
import lombok.*;

@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ChangeRoleRequestDto {
@NotNull(message = "New role must not be null")
@ValidEnum(enumClass = ClubRole.class, message = "Invalid role. Allowed roles are MEMBER, OWNER, MODERATOR.")
private ClubRole clubRole;
}
36 changes: 36 additions & 0 deletions src/main/java/com/runningmate/backend/club/dto/ClubRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.runningmate.backend.club.dto;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.runningmate.backend.club.Club;
import com.runningmate.backend.route.dto.CoordinateDto;
import com.runningmate.backend.utils.PointCreator;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.locationtech.jts.geom.Point;

@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ClubRequestDto {
@NotEmpty(message = "Title must not be empty or null")
@Size(max = 100, message = "Title must not exceed 100 characters")
private String title;

@NotEmpty(message = "Detail must not be empty or null")
@Size(max = 500, message = "Detail must not exceed 500 characters")
private String description;

@NotNull(message = "Location must not be null")
private CoordinateDto location;

public Club toEntity() {
return Club.builder()
.title(this.title)
.description(this.description)
.location(PointCreator.createPoint(this.location.getLongitude(), this.location.getLatitude()))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.runningmate.backend.club.dto;

import com.runningmate.backend.club.Club;
import com.runningmate.backend.club.ClubMemberEntity;
import com.runningmate.backend.member.dto.MemberDto;
import com.runningmate.backend.route.dto.CoordinateDto;
import com.runningmate.backend.schedule.Schedule;
import com.runningmate.backend.utils.PointCreator;
import lombok.*;
import org.locationtech.jts.geom.Point;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ClubResponseDto {
private UUID id;
private String title;
private String description;
private CoordinateDto location;
private String profilePic;
private String backgroundPic;
private List<MemberDto> clubMembers;
private List<ClubScheduleEntityResponseDto> schedules;

public static ClubResponseDto fromEntity(Club club) {
return ClubResponseDto.builder()
.id(club.getId())
.title(club.getTitle())
.description(club.getDescription())
.location(PointCreator.toCoordinateDto(club.getLocation()))
.profilePic(club.getProfile_pic())
.backgroundPic(club.getBackground_pic())
.clubMembers(club.getMembers().stream()
.map(ClubMemberEntity::getMember)
.map(MemberDto::fromEntity)
.collect(Collectors.toList()))
.schedules(club.getSchedules().stream()
.map(clubScheduleEntity -> ClubScheduleEntityResponseDto.fromEntity(clubScheduleEntity))
.collect(Collectors.toList()))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.runningmate.backend.club.dto;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.runningmate.backend.club.ClubScheduleEntity;
import com.runningmate.backend.schedule.dto.ScheduleResponseDto;
import lombok.*;

@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ClubScheduleEntityResponseDto {
private Long id;
@JsonUnwrapped
private ScheduleResponseDto schedule;

public static ClubScheduleEntityResponseDto fromEntity(ClubScheduleEntity clubScheduleEntity) {
return ClubScheduleEntityResponseDto.builder()
.id(clubScheduleEntity.getId())
.schedule(ScheduleResponseDto.fromEntity(clubScheduleEntity.getSchedule()))
.build();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.runningmate.backend.club.dto;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.runningmate.backend.schedule.dto.CreateOrUpdateScheduleRequestDto;
import lombok.*;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class CreateOrUpdateClubScheduleRequestDto{
@JsonUnwrapped
private CreateOrUpdateScheduleRequestDto createOrUpdateScheduleRequestDto;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.runningmate.backend.club.dto;

import lombok.*;

import java.util.List;

@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class ListClubScheduleEntityResponseDto {
private List<ClubScheduleEntityResponseDto> clubScheduleEntityResponseDtos;
}
Loading

0 comments on commit a2f4b2d

Please sign in to comment.