Skip to content

Commit a5e3ac6

Browse files
Merge pull request #136 from prgrms-aibe-devcourse/feat/#134-profile-image-view
[feat] 멘토링 후기, 채팅방에 프로필 이미지 뜨도록 변경, redirect 경로 수정
2 parents 2a4bd3d + ae25f0a commit a5e3ac6

9 files changed

Lines changed: 79 additions & 10 deletions

File tree

src/main/java/com/knoc/reviewFeedback/dto/ReviewPageDto.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ public class ReviewPageDto {
1818
public static class ReviewCardDto {
1919
private final Long seniorProfileId;
2020
private final String juniorName;
21+
private final String juniorProfileImageUrl;
2122
private final String seniorName;
23+
private final String seniorProfileImageUrl;
2224
private final String mentoringType;
2325
private final String timeAgo;
2426
private final byte rating;
@@ -31,6 +33,7 @@ public static class ReviewCardDto {
3133
public static class TopSeniorDto {
3234
private final Long seniorProfileId;
3335
private final String name;
36+
private final String profileImageUrl;
3437
private final BigDecimal rating;
3538
}
3639
}

src/main/java/com/knoc/reviewFeedback/service/ReviewFeedbackService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ private List<ReviewPageDto.ReviewCardDto> mapToCards(List<ReviewFeedback> feedba
102102
return feedbacks.stream().map(r -> ReviewPageDto.ReviewCardDto.builder()
103103
.seniorProfileId(r.getSeniorProfile().getId())
104104
.juniorName(r.getJunior().getNickname())
105+
.juniorProfileImageUrl(r.getJunior().getProfileImageUrl())
105106
.seniorName(r.getSeniorProfile().getMember().getNickname())
107+
.seniorProfileImageUrl(r.getSeniorProfile().getMember().getProfileImageUrl())
106108
.mentoringType(r.getSeniorProfile().getPosition())
107109
.timeAgo(timeAgo(r.getCreatedAt()))
108110
.rating(r.getRating())
@@ -116,6 +118,7 @@ private List<ReviewPageDto.TopSeniorDto> mapToTopSeniors(List<SeniorProfile> sen
116118
return seniors.stream().map(s -> ReviewPageDto.TopSeniorDto.builder()
117119
.seniorProfileId(s.getId())
118120
.name(s.getMember().getNickname())
121+
.profileImageUrl(s.getMember().getProfileImageUrl())
119122
.rating(s.getAvgRating())
120123
.build()
121124
).toList();

src/main/java/com/knoc/senior/controller/SeniorApplyController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ public String updateProfile(@AuthenticationPrincipal UserDetails userDetails,
106106
RedirectAttributes redirectAttributes) {
107107
Long memberId = getMemberId(userDetails);
108108
seniorProfileService.updateProfile(memberId, dto);
109-
redirectAttributes.addFlashAttribute("successMessage", "시니어 프로필이 수정되었습니다.");
110-
return "redirect:/senior/profile-update";
109+
return "redirect:/my/dashboard?seniorProfileUpdated=true";
111110
}
112111

113112
@Operation(summary = "이메일 인증 번호 발송",description = "기업 이메일로 인증번호를 발송합니다.")

src/main/resources/static/css/chatrooms.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@
100100
align-items: center;
101101
justify-content: center;
102102
flex-shrink: 0;
103+
overflow: hidden;
104+
}
105+
.room-avatar img {
106+
width: 100%;
107+
height: 100%;
108+
object-fit: cover;
109+
display: block;
103110
}
104111

105112
.room-info { flex: 1; overflow: hidden; }
@@ -174,6 +181,13 @@
174181
display: flex;
175182
align-items: center;
176183
justify-content: center;
184+
overflow: hidden;
185+
}
186+
.chat-header-avatar img {
187+
width: 100%;
188+
height: 100%;
189+
object-fit: cover;
190+
display: block;
177191
}
178192

179193
.chat-header-name {

src/main/resources/templates/chat/chatrooms.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@
3838
th:attr="data-room-id=${room.id}"
3939
class="room-item">
4040

41-
<div class="room-avatar" th:text="${#strings.substring(opponent.nickname, 0, 1)}"></div>
41+
<div class="room-avatar" th:with="avatarUrl=${opponent.profileImageUrl}">
42+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}" th:src="${avatarUrl}" alt="프로필 이미지"/>
43+
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}"
44+
th:text="${#strings.substring(opponent.nickname, 0, 1)}"></span>
45+
</div>
4246

4347
<div class="room-info">
4448
<div class="room-name" th:text="${opponent.nickname}"></div>
@@ -76,7 +80,11 @@
7680
<path stroke-linecap="round" stroke-linejoin="round" d="M13 5l7 7-7 7M5 5l7 7-7 7"/>
7781
</svg>
7882
</button>
79-
<div class="chat-header-avatar" th:text="${#strings.substring(opponent.nickname, 0, 1)}"></div>
83+
<div class="chat-header-avatar" th:with="avatarUrl=${opponent.profileImageUrl}">
84+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}" th:src="${avatarUrl}" alt="프로필 이미지"/>
85+
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}"
86+
th:text="${#strings.substring(opponent.nickname, 0, 1)}"></span>
87+
</div>
8088
<div class="chat-header-name" th:text="${opponent.nickname}"></div>
8189
<span id="connectionStatus" class="connection-status status-disconnected">종료됨</span>
8290

src/main/resources/templates/chat/rooms.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@
5757
align-items: center;
5858
justify-content: center;
5959
flex-shrink: 0;
60+
overflow: hidden;
61+
}
62+
.room-avatar img {
63+
width: 100%;
64+
height: 100%;
65+
object-fit: cover;
66+
display: block;
6067
}
6168

6269
.room-info {
@@ -134,8 +141,10 @@
134141

135142
<!-- 아바타: 상대방 닉네임 첫 글자 -->
136143
<div class="room-avatar"
137-
th:with="opponent=${#authentication.name == room.junior.email ? room.senior : room.junior}"
138-
th:text="${#strings.substring(opponent.nickname, 0, 1)}">
144+
th:with="opponent=${#authentication.name == room.junior.email ? room.senior : room.junior}, avatarUrl=${opponent.profileImageUrl}">
145+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}" th:src="${avatarUrl}" alt="프로필 이미지"/>
146+
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}"
147+
th:text="${#strings.substring(opponent.nickname, 0, 1)}"></span>
139148
</div>
140149

141150
<!-- 채팅방 정보 -->

src/main/resources/templates/my/dashboard/senior.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@
354354
style="background-color: rgba(74,222,128,0.1); border: 1px solid rgba(74,222,128,0.35); color: #4ade80; border-radius: 0.9rem; padding: 0.75rem 1.25rem;">
355355
프로필이 업데이트되었습니다.
356356
</div>
357+
<div th:if="${param.seniorProfileUpdated}" class="alert mb-3"
358+
style="background-color: rgba(74,222,128,0.1); border: 1px solid rgba(74,222,128,0.35); color: #4ade80; border-radius: 0.9rem; padding: 0.75rem 1.25rem;">
359+
전문성 정보가 업데이트되었습니다.
360+
</div>
357361
<div th:if="${param.profileError}" class="alert mb-3"
358362
style="background-color: rgba(248,113,113,0.1); border: 1px solid rgba(248,113,113,0.35); color: #f87171; border-radius: 0.9rem; padding: 0.75rem 1.25rem;">
359363
이미 사용 중인 닉네임입니다.

src/main/resources/templates/review/posts.html

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@
8484
font-size: 0.9rem;
8585
color: #fff;
8686
flex-shrink: 0;
87+
overflow: hidden;
88+
}
89+
.reviewer-avatar img {
90+
width: 100%;
91+
height: 100%;
92+
object-fit: cover;
93+
display: block;
8794
}
8895
.av-blue { background: linear-gradient(135deg, #3b82f6, #1d4ed8); }
8996
.av-green { background: linear-gradient(135deg, #10b981, #059669); }
@@ -162,6 +169,13 @@
162169
color: #fff;
163170
flex-shrink: 0;
164171
border: 1px solid rgba(255,255,255,0.06);
172+
overflow: hidden;
173+
}
174+
.senior-avatar img {
175+
width: 100%;
176+
height: 100%;
177+
object-fit: cover;
178+
display: block;
165179
}
166180
.sa-0 { background: linear-gradient(135deg, #1a3350, #1a7a8a); }
167181
.sa-1 { background: linear-gradient(135deg, #2a1a50, #4a3080); }
@@ -254,7 +268,12 @@ <h2 class="fw-bold text-white mb-2">성장의 기록이 모이는 곳</h2>
254268
<div class="d-flex align-items-start justify-content-between mb-3">
255269
<div class="d-flex align-items-center gap-3">
256270
<div class="reviewer-avatar"
257-
th:text="${#strings.substring(review.juniorName, 0, 1)}">J</div>
271+
th:with="avatarUrl=${review.juniorProfileImageUrl}">
272+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}"
273+
th:src="${avatarUrl}" alt="프로필 이미지"/>
274+
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}"
275+
th:text="${#strings.substring(review.juniorName, 0, 1)}">J</span>
276+
</div>
258277
<div>
259278
<div class="reviewer-name" th:text="${review.juniorName}">주OO 개발자</div>
260279
<div class="reviewer-meta">
@@ -399,7 +418,12 @@ <h2 class="fw-bold text-white mb-2">성장의 기록이 모이는 곳</h2>
399418
<span class="senior-rank" th:text="${stat.index + 1}">1</span>
400419
<div class="senior-avatar"
401420
th:classappend="'sa-' + ${stat.index % 3}"
402-
th:text="${#strings.substring(senior.name, 0, 1)}">K</div>
421+
th:with="avatarUrl=${senior.profileImageUrl}">
422+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}"
423+
th:src="${avatarUrl}" alt="프로필 이미지"/>
424+
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}"
425+
th:text="${#strings.substring(senior.name, 0, 1)}">K</span>
426+
</div>
403427
<div class="senior-info">
404428
<span class="senior-name" th:text="${senior.name}">김훈식 시니어</span>
405429
<div class="senior-rating">
@@ -501,6 +525,7 @@ <h2 class="fw-bold text-white mb-2">성장의 기록이 모이는 곳</h2>
501525

502526
reviewList.innerHTML = myReviews.map(function (review) {
503527
const juniorName = escapeHtml(review.juniorName || '');
528+
const juniorProfileImageUrl = escapeHtml(review.juniorProfileImageUrl || '');
504529
const seniorName = escapeHtml(review.seniorName || '');
505530
const mentoringType = escapeHtml(review.mentoringType || '');
506531
const timeAgo = escapeHtml(review.timeAgo || '');
@@ -512,7 +537,11 @@ <h2 class="fw-bold text-white mb-2">성장의 기록이 모이는 곳</h2>
512537
<div class="review-card">
513538
<div class="d-flex align-items-start justify-content-between mb-3">
514539
<div class="d-flex align-items-center gap-3">
515-
<div class="reviewer-avatar">${juniorName ? juniorName.substring(0, 1) : '나'}</div>
540+
<div class="reviewer-avatar">
541+
${juniorProfileImageUrl
542+
? `<img src="${juniorProfileImageUrl}" alt="프로필 이미지"/>`
543+
: `<span>${juniorName ? juniorName.substring(0, 1) : '나'}</span>`}
544+
</div>
516545
<div>
517546
<div class="reviewer-name">${juniorName || '나의 후기'}</div>
518547
<div class="reviewer-meta">

src/main/resources/templates/workspace/workspace.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@
466466
<div class="chat-pane">
467467
<div class="chat-header">
468468
<div class="chat-header-avatar" th:with="avatarUrl=${workspace.opponentAvatarUrl}">
469-
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}" th:src="${avatarUrl}" alt="avatar"/>
469+
<img th:if="${avatarUrl != null and !#strings.isEmpty(avatarUrl)}" th:src="${avatarUrl}" alt="프로필 이미지"/>
470470
<span th:if="${avatarUrl == null or #strings.isEmpty(avatarUrl)}" th:text="${#strings.substring(workspace.opponentNickname, 0, 1)}"></span>
471471
</div>
472472
<div class="chat-header-name" th:text="${workspace.opponentNickname}"></div>

0 commit comments

Comments
 (0)