Skip to content

Commit a15e29a

Browse files
authored
mypage 반영 (#148)
1 parent 0f0fa26 commit a15e29a

File tree

5 files changed

+166
-66
lines changed

5 files changed

+166
-66
lines changed

src/main/resources/static/css/test-mypage.css

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,12 @@ body {
6767
align-items: flex-start; /* 위쪽 정렬 (선택) */
6868
gap: 0px; /* 두 영역 사이 간격 */
6969
border-radius: 20px;
70-
border: 2px solid #6c6c6c;
7170
padding: 0px;
71+
background-color: #0B1C17;
7272
}
7373

7474
/* profile-section에 테두리와 배경, 패딩 등 원하는 스타일 추가 */
7575
.profile-section {
76-
background: #000;
7776
padding: 40px 60px;
7877
min-width: 350px; /* 적당한 최소 너비 (조절 가능) */
7978
display: flex;
@@ -129,10 +128,14 @@ body {
129128
}
130129

131130
/* info-row-2는 좌측정렬, 필요시 각 요소에 margin-right 부여 */
132-
.info-row-2 {
133-
justify-content: flex-start;
131+
.info-row-2 { display: flex;
132+
flex-direction: column;
133+
align-items: flex-start;
134134
gap: 36px;
135135
}
136+
.info-row-2-inner {
137+
display: flex;align-items: center;
138+
}
136139

137140
/* info-label, info-value 등 기존 스타일 유지 */
138141
.info-label {
@@ -148,58 +151,74 @@ body {
148151
font-weight: 700;
149152
min-width: 80px;
150153
}
151-
.info-label.email-verify {
152-
margin-left: 20px;
153-
color: #0a1d15;
154-
background: #00a141;
155-
border-radius: 3px;
156-
padding: 2px 10px;
157-
font-size: 10px;
158-
font-weight: 700;
159-
}
154+
155+
160156
.github-btns {
161157
display: flex;
162158
gap: 10px;
163159
align-items: center;
164160
margin-left: 40px;
165161
}
166162
.github-btn, .blog-btn {
167-
background: #222;
168-
color: #fff;
163+
background: transparent;
169164
border: none;
170165
border-radius: 10px;
171166
padding: 8px 20px;
172167
font-size: 12px;
173168
font-weight: 800;
174169
cursor: pointer;
175170
transition: background 0.2s;
171+
flex-direction: column;
172+
align-items: center;
173+
justify-content: center;
174+
display: flex;
175+
color: white;
176176
}
177-
.github-btn:hover, .blog-btn:hover {
178-
background: #00a141;
179-
color: #0a1d15;
177+
178+
.github-btn-img{
179+
width: 40px;
180+
height: 40px;
180181
}
181182

182183
.github-heatmap-section {
183-
background: #fff;
184184
border-radius: 10px;
185185
min-height: 200px;
186186
padding: 20px;
187187
margin-top: 30px;
188188
}
189189
.heatmap-placeholder {
190-
color: #6c6c6c;
191190
text-align: center;
192191
font-size: 18px;
193192
padding: 60px 0;
194193
}
195-
.email-verify .checkmark {
196-
display: inline-block;
197-
width: 18px;
198-
height: 18px;
199-
vertical-align: middle;
194+
/* 이메일 인증 전 텍스트 버튼처럼 보이게 */
195+
.email-verify .email-verify {
196+
height: 25px;
197+
border-radius: 6px;
198+
padding: 2px;
199+
box-sizing: border-box;
200+
margin-left: 10px;
201+
/* 마우스 올릴 때 */
202+
cursor: pointer;
203+
transition: box-shadow 0.3s ease;
200204
}
201-
.email-verify .checkmark svg {
202-
width: 100%;
203-
height: 100%;
204-
display: block;
205+
206+
.email-verify .email-verify:hover {
207+
box-shadow: 0 0 8px rgba(0, 123, 255, 0.7); /* 파란빛 그림자 예시 */
208+
}
209+
210+
.email-verify .check-image {
211+
width: 24px;
212+
height: 24px;
213+
border-radius: 6px;
214+
padding: 2px;
215+
box-sizing: border-box;
216+
margin-left: 10px;
217+
/* 아무 액션 안함 */
218+
cursor: default;
219+
pointer-events: none; /* 클릭, 호버 무시 */
220+
}
221+
222+
.social-row {
223+
display: flex;
205224
}
1.04 KB
Loading
3.18 KB
Loading

src/main/resources/static/js/test-mypage.js

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@ function fetchUserData() {
1515
const accessToken = sessionStorage.getItem('accessToken');
1616
if (!accessToken) return;
1717

18+
// 1. 리뷰 토큰 조회
19+
fetch('/api/users/review-token', {
20+
method: 'GET',
21+
headers: {
22+
'Accept': 'application/json',
23+
'Authorization': accessToken
24+
},
25+
credentials: 'include'
26+
})
27+
.then(response => {
28+
if (!response.ok) throw new Error('유저 정보를 불러오지 못했습니다.');
29+
return response.json();
30+
})
31+
.then((res) => {
32+
// 응답 구조에 따라 아래 코드 수정
33+
const user = res.result || res;
34+
const aiReviewElem = document.getElementById('aiReview');
35+
if (aiReviewElem) aiReviewElem.textContent = user.reviewToken || '-';
36+
})
37+
.catch(err => {
38+
console.error(err);
39+
});
40+
41+
1842
// 1. 내 정보 조회 API 호출 (토큰을 Authorization 헤더에 넣기)
1943
fetch('/api/users', {
2044
method: 'GET',
@@ -37,8 +61,7 @@ function fetchUserData() {
3761
document.getElementById('email').textContent = user.email || '';
3862
document.getElementById('tier').textContent = user.tier || '';
3963
document.getElementById('ranking').textContent = user.ranking || '-';
40-
document.getElementById('solvedCount').textContent = user.solvedCount || '-';
41-
document.getElementById('aiReview').textContent = user.aiReview || '-';
64+
document.getElementById('solvedCount').textContent = user.totalSolvedCount || '-';
4265
setEmailVerify(!!user.verified);
4366

4467
// 블로그, 깃허브 버튼 링크 처리
@@ -61,14 +84,61 @@ function fetchUserData() {
6184
console.error(err);
6285
// 필요시 에러 안내
6386
});
87+
6488
}
6589

66-
// 이메일 인증 상태 표시 함수
6790
function setEmailVerify(isVerified) {
6891
const emailVerify = document.getElementById('emailVerify');
6992
if (isVerified) {
70-
emailVerify.innerHTML = `<span class="checkmark"><svg viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="10" fill="#00a141"/><path d="M6 10.5L9 13.5L14 8.5" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>`;
93+
emailVerify.innerHTML = `
94+
<img src="/images/check.png" alt="인증 완료" class="check-image" />
95+
`;
7196
} else {
72-
emailVerify.textContent = '-';
97+
emailVerify.innerHTML = `
98+
<img src="/images/email-verify.png"
99+
alt="이메일 인증하기"
100+
class="email-verify clickable"
101+
id="emailVerifyButton" />
102+
`;
103+
104+
// 이미지 삽입 후 클릭 이벤트 바인딩
105+
const emailVerifyButton = document.getElementById('emailVerifyButton');
106+
emailVerifyButton.addEventListener('click', sendEmailVerification);
107+
}
108+
}
109+
110+
//이메일 전송
111+
async function sendEmailVerification() {
112+
const accessToken = sessionStorage.getItem('accessToken');
113+
114+
if (!accessToken) {
115+
alert('로그인이 필요합니다.');
116+
return;
117+
}
118+
119+
try {
120+
const response = await fetch('/api/email/send', {
121+
method: 'POST',
122+
headers: {
123+
'Content-Type': 'application/json',
124+
'Authorization': accessToken
125+
},
126+
body: JSON.stringify({
127+
redirectUrl: 'http://localhost:8080'
128+
})
129+
});
130+
131+
if (response.ok) {
132+
const result = await response.json();
133+
alert('인증 메일이 발송되었습니다.');
134+
console.log(result);
135+
} else {
136+
const error = await response.json();
137+
alert(`오류: ${error.message || '인증 요청 실패'}`);
138+
}
139+
} catch (err) {
140+
console.error('이메일 인증 오류:', err);
141+
alert('서버 오류가 발생했습니다.');
73142
}
74143
}
144+

src/main/resources/templates/test-mypage.html

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,51 @@
2222
</aside>
2323
<main class="main-content">
2424
<section class="user-infos">
25-
<section class="profile-section">
26-
<div class="profile-img">
27-
<!-- 프로필 이미지: DB에 없으면 기본 이미지로 대체 -->
28-
<img src="/images/logo.png" alt="프로필 이미지" id="profileImage">
29-
</div>
30-
<div class="nickname" id="nickname">ezcode</div>
31-
</section>
32-
<section class="info-section">
33-
<div class="info-row info-row-1">
34-
<div class="info-label">랭킹</div>
35-
<div class="info-value" id="ranking">7th</div>
36-
<div class="info-label">푼 문제 수</div>
37-
<div class="info-value" id="solvedCount">134,452,565 문제</div>
38-
<div class="info-label">남은 AI 리뷰 횟수</div>
39-
<div class="info-value" id="aiReview">5번</div>
40-
</div>
41-
<div class="info-row info-row-2">
42-
<div class="info-label">티어</div>
43-
<div class="info-value" id="tier">-</div>
44-
<div class="info-label">아이디</div>
45-
<div class="info-value" id="userId">-</div>
46-
<div class="info-label">이메일</div>
47-
<div class="info-value" id="email">-</div>
48-
<div class="info-label email-verify">
49-
<span id="emailVerify">이메일 인증</span>
25+
<section class="profile-section">
26+
<div class="profile-img">
27+
<!-- 프로필 이미지: DB에 없으면 기본 이미지로 대체 -->
28+
<img src="/images/logo.png" alt="프로필 이미지" id="profileImage">
5029
</div>
51-
</div>
52-
<div class="info-row github-row">
53-
<div class="github-btns">
54-
<button class="github-btn">github</button>
55-
<button class="blog-btn">blog</button>
30+
<div class="info-value" id="nickname">닉네임</div>
31+
</section>
32+
<section class="info-section">
33+
<div class="info-row info-row-1">
34+
<div class="info-label">랭킹</div>
35+
<div class="info-value" id="ranking">7th</div>
36+
<div class="info-label" >푼 문제 수</div>
37+
<div class="info-value" id="solvedCount">문제</div>
38+
<div class="info-label">남은 AI 리뷰 횟수</div>
39+
<div class="info-value" id="aiReview">-</div>
5640
</div>
57-
</div>
58-
</section>
41+
<div class="info-row info-row-2">
42+
<div class="info-row-2-inner">
43+
<div class="info-label">티어</div>
44+
<div class="info-value" id="tier">-</div>
45+
</div>
46+
<div class="info-row-2-inner">
47+
<div class="info-label">아이디</div>
48+
<div class="info-value" id="userId">-</div>
49+
</div>
50+
<div class="info-row-2-inner">
51+
<div class="info-label">이메일</div>
52+
<div class="info-value" id="email">-</div>
53+
<div class="info-label email-verify">
54+
<span id="emailVerify" class="verify-text">이메일 인증</span>
55+
</div>
56+
</div>
57+
58+
59+
</div>
60+
<div class="social-row">
61+
<div class="github-btns">
62+
<button class="github-btn">
63+
<img src="/images/githubIcon.png" class = "github-btn-img" alt="github 이미지"/>
64+
github
65+
</button>
66+
<button class="blog-btn">blog</button>
67+
</div>
68+
</div>
69+
</section>
5970
</section>
6071
<section class="github-heatmap-section">
6172
<!-- 깃허브 히트맵: DB 연동시 색상 하이라이트 처리 -->

0 commit comments

Comments
 (0)