Skip to content

Commit afbec94

Browse files
committed
Fix: Pet 디자인 수정
1 parent eb4ebe6 commit afbec94

File tree

2 files changed

+433
-82
lines changed

2 files changed

+433
-82
lines changed

src/pages/Profile.jsx

Lines changed: 163 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
import React, { useState, useEffect } from "react";
1+
import React, { useState, useEffect, useRef } from "react";
22
import SockJS from "sockjs-client";
33
import Stomp from "stompjs";
44

55
const Profile = ({ userInfo }) => {
6-
const [seasonCommitCount, setSeasonCommitCount] = useState(userInfo.seasonCommitCount);
7-
const [petExp, setPetExp] = useState(userInfo.petExp);
6+
const [seasonCommitCount, setSeasonCommitCount] = useState(userInfo.seasonCommitCount || 0);
7+
const [petExp, setPetExp] = useState(userInfo.petExp || 0);
88
const [commitCount, setCommitCount] = useState(0);
99
const [client, setClient] = useState(null); // WebSocket 클라이언트 상태
10+
const [lastRefreshTime, setLastRefreshTime] = useState(new Date());
11+
const [isRefreshing, setIsRefreshing] = useState(false);
12+
const refreshTimerRef = useRef(null);
1013

1114
const maxExp = userInfo.petGrow === "EGG" ? 150 : userInfo.petGrow === "HATCH" ? 300 : 300;
15+
16+
// 티어 아이콘 매핑
1217
const tierEmojis = {
1318
SEED: "🌱",
1419
SPROUT: "🌿",
@@ -17,15 +22,83 @@ const Profile = ({ userInfo }) => {
1722
TREE: "🌳",
1823
};
1924

25+
// 펫 성장 단계 한글화
26+
const petGrowthStages = {
27+
EGG: "알",
28+
HATCH: "부화",
29+
BABY: "아기",
30+
ADULT: "성체",
31+
};
32+
2033
// 경험치 바 계산
2134
const progress = (petExp / maxExp) * 100;
2235

36+
// 프로필 정보 자동 새로고침 함수
37+
const refreshProfileData = async () => {
38+
setIsRefreshing(true);
39+
try {
40+
// 실제로는 여기서 API 호출을 통해 최신 데이터를 가져옵니다
41+
const response = await fetch("/api/user/info", {
42+
credentials: 'include',
43+
headers: {
44+
'Cache-Control': 'no-cache'
45+
}
46+
});
47+
48+
if (response.ok) {
49+
const data = await response.json();
50+
// 새로운 데이터로 상태 업데이트
51+
setSeasonCommitCount(data.data.seasonCommitCount || 0);
52+
setPetExp(data.data.petExp || 0);
53+
// 마지막 갱신 시간 업데이트
54+
setLastRefreshTime(new Date());
55+
}
56+
} catch (error) {
57+
console.error("프로필 데이터 새로고침 오류:", error);
58+
} finally {
59+
setIsRefreshing(false);
60+
}
61+
};
62+
63+
// 자동 새로고침 설정 (30초마다)
64+
useEffect(() => {
65+
refreshTimerRef.current = setInterval(refreshProfileData, 30000);
66+
67+
// 컴포넌트 언마운트 시 타이머 정리
68+
return () => {
69+
if (refreshTimerRef.current) {
70+
clearInterval(refreshTimerRef.current);
71+
}
72+
};
73+
}, []);
74+
2375
// userInfo가 변경되면 값 업데이트
2476
useEffect(() => {
25-
setSeasonCommitCount(userInfo.seasonCommitCount);
26-
setPetExp(userInfo.petExp);
77+
setSeasonCommitCount(userInfo.seasonCommitCount || 0);
78+
setPetExp(userInfo.petExp || 0);
79+
setLastRefreshTime(new Date());
2780
}, [userInfo]);
2881

82+
// 날짜 포맷팅 함수
83+
const formatDate = (dateString) => {
84+
if (!dateString) return "없음";
85+
const date = new Date(dateString);
86+
return date.toLocaleDateString('ko-KR', {
87+
year: 'numeric',
88+
month: 'long',
89+
day: 'numeric'
90+
});
91+
};
92+
93+
// 새로고침 시간 포맷팅 함수
94+
const formatRefreshTime = (date) => {
95+
return date.toLocaleTimeString('ko-KR', {
96+
hour: '2-digit',
97+
minute: '2-digit',
98+
second: '2-digit'
99+
});
100+
};
101+
29102
useEffect(() => {
30103
// userInfo.username이 없으면 WebSocket 연결 안 함
31104
if (!userInfo.username) {
@@ -75,46 +148,100 @@ const Profile = ({ userInfo }) => {
75148
}, [userInfo.username]); // username이 변경될 때마다 WebSocket 연결
76149

77150
return (
78-
<div className="flex-box">
79-
<div className="profile-container">
80-
{/* 왼쪽: 펫 이미지 */}
81-
<div className="pet-box">
82-
<img src={`/pets/${userInfo.petGrow}_0_128.png`} alt="Pet" className="animated-pet" />
151+
<div className="profile-container">
152+
{/* 왼쪽: 펫 이미지 */}
153+
<div className="pet-section">
154+
<div className="pet-frame">
155+
<img
156+
src={`/pets/${userInfo.petGrow}_0_128.png`}
157+
alt="Pet"
158+
className={`pet-image animated-pet ${isRefreshing ? 'refreshing' : ''}`}
159+
/>
160+
</div>
161+
<div className="pet-stage">
162+
{petGrowthStages[userInfo.petGrow] || userInfo.petGrow}
163+
</div>
164+
{isRefreshing && <div className="refreshing-indicator"></div>}
165+
</div>
166+
167+
{/* 오른쪽: 사용자 정보 및 펫 정보 */}
168+
<div className="user-info">
169+
{/* 유저 이름과 아바타 */}
170+
<div className="user-header">
171+
<div className="avatar-container">
172+
<img src={userInfo.avatarUrl} alt="User Avatar" />
173+
</div>
174+
<span className="username">{userInfo.username || "사용자"}</span>
83175
</div>
84176

85-
{/* 오른쪽: 사용자 정보 및 펫 정보 */}
86-
<div className="info-box">
87-
<div>
88-
<img src={userInfo.avatarUrl} alt="User Avatar" className="avatar" /> {userInfo.username}
177+
{/* 유저 세부 정보 */}
178+
<div className="user-details">
179+
<div className="detail-item">
180+
<span className="detail-icon">📊</span>
181+
<span className="detail-text">
182+
이번 시즌 커밋: <span className="detail-value">{seasonCommitCount}</span>
183+
</span>
184+
</div>
185+
186+
<div className="detail-item">
187+
<span className="detail-icon">🔄</span>
188+
<span className="detail-text">
189+
업데이트 커밋: <span className="detail-value">{commitCount}</span>
190+
</span>
89191
</div>
90-
<div>이번 시즌 커밋 수: {seasonCommitCount}</div>
91-
<div>업데이트 커밋 수: {commitCount}</div>
92-
<div>티어: {tierEmojis[userInfo.tier] || userInfo.tier} / 마지막 커밋 날짜: {new Date(userInfo.lastCommitted).toLocaleDateString()}</div>
93-
94-
{/* 펫 정보 */}
95-
<div>🐾 펫 정보</div>
96-
<div className="exp-bar">
97-
<div className="bar">
98-
<div style={{ width: "100%", height: "5px", backgroundColor: "#F3F3F3", borderRadius: "2px" }}>
99-
<div
100-
style={{
101-
width: `${progress}%`, // 경험치 비율 적용
102-
height: "100%",
103-
backgroundColor: "#FF69B4",
104-
borderRadius: "2px",
105-
}}
106-
/>
107-
</div>
192+
193+
<div className="detail-item">
194+
<span className="detail-icon">🏆</span>
195+
<span className="detail-text">
196+
티어: <span className="tier-badge">
197+
{tierEmojis[userInfo.tier] || ""} {userInfo.tier || "없음"}
198+
</span>
199+
</span>
200+
</div>
201+
202+
<div className="detail-item">
203+
<span className="detail-icon">📅</span>
204+
<span className="detail-text">
205+
마지막 커밋: <span className="detail-value">{formatDate(userInfo.lastCommitted)}</span>
206+
</span>
207+
</div>
208+
</div>
209+
210+
{/* 펫 정보 */}
211+
<div className="pet-info">
212+
<div className="pet-title">
213+
<span>🐾</span> 펫 정보
214+
</div>
215+
216+
<div className="exp-bar-container">
217+
<div className="exp-bar">
218+
<div
219+
className="exp-progress"
220+
style={{ width: `${progress}%` }}
221+
></div>
108222
</div>
109-
<div>
223+
<span className="exp-text">
110224
{petExp} / {maxExp}
111-
</div>
225+
</span>
226+
</div>
227+
228+
{/* 새로고침 버튼 및 마지막 새로고침 시간 표시 */}
229+
<div className="refresh-info">
230+
<button
231+
className="refresh-button"
232+
onClick={refreshProfileData}
233+
disabled={isRefreshing}
234+
>
235+
<span className={`refresh-icon ${isRefreshing ? 'rotating' : ''}`}>🔄</span>
236+
</button>
237+
<span className="last-refresh-time">
238+
{isRefreshing ? '새로고침 중...' : `마지막 업데이트: ${formatRefreshTime(lastRefreshTime)}`}
239+
</span>
112240
</div>
113-
<div>성장 단계: {userInfo.petGrow}</div>
114241
</div>
115242
</div>
116243
</div>
117244
);
118245
};
119246

120-
export default Profile;
247+
export default Profile;

0 commit comments

Comments
 (0)