Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/api/user/level.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import api from '@/api/api';
import type { UserGradeResponse } from '@/types/level';

export const getUserGrade = async (): Promise<UserGradeResponse> => {
try {
const response = await api.get<{ data: UserGradeResponse }>('/profile');
return response.data.data; // ✅ 두 번 접근
} catch (err) {
console.error('레벨 정보 로딩 에러:', err);
throw err;
}
};
6 changes: 3 additions & 3 deletions src/components/common/LevelCard/MyLevelCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ const MyLevelCard: React.FC<MyLevelCardProps> = ({
<div className="w-[335px] h-[320px] bg-[#4242424D] rounded-lg p-4 flex flex-col items-center justify-around mt-4 mx-auto">
<CharacterComponent className="w-[150px] h-[150px]" />

<p className="text-center">
<div className="flex items-center justify-center gap-x-2">
<span className="text-title-1 text-red-400">Lv.{userLevel}</span>
<span className="text-title-4 text-white"> {levelTitle}</span>
</p>
<span className="text-title-4 text-white">{levelTitle}</span>
</div>

<div className="w-[295px] h-[12px] bg-gray-950 rounded-full">
<div className="h-full bg-red-300 rounded-full" style={{ width: `${userProgress}%` }} />
Expand Down
8 changes: 4 additions & 4 deletions src/constants/levelcondition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ export interface Level {
export const LEVELS_DATA: Level[] = [
{
level: 1,
title: '레벨 1 이름',
title: '옥수수 인턴 코니',
condition: 'seeat 가입하기',
Icon: LevelCharacter1,
},
{
level: 2,
title: '레벨 2 이름',
title: '영화관 탐험가 코니',
condition: '후기 2개 작성하기\n좋아요 5개 누르기',
Icon: LevelCharacter2,
},
{
level: 3,
title: '레벨 3 이름',
title: '영화관 평론가 코니',
condition: '후기 10개 작성하기\n좋아요 25개 누르기',
Icon: LevelCharacter3,
},
{
level: 4,
title: '레벨 4 이름',
title: '전설의 팝콘 코니',
condition: '후기 40개 작성하기\n좋아요 100개 누르기',
Icon: LevelCharacter4,
},
Expand Down
55 changes: 34 additions & 21 deletions src/pages/my/Level.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
// import { HeaderBasic } from '@/components';
import { LevelInfoCard, MyLevelCard } from '@/components';
import { useQuery } from '@tanstack/react-query';
import { Header } from '@/components';
import { LevelInfoCard, MyLevelCard } from '@/components';
import { LEVELS_DATA } from '@/constants/levelcondition';
import type { UserGradeResponse } from '@/types/level';
import { getUserGrade } from '@/api/user/level.api';

const gradeToLevelMap: { [key: string]: number } = {
BRONZE: 1,
SILVER: 2,
GOLD: 3,
PLATINUM: 4,
};

export default function LevelPage() {
// 나중에 API
const currentUser = {
level: 3,
progress: 45,
};
const currentUserStatus = {
reviewCount: 5,
likeCount: 12,
};
const { data, isLoading, error } = useQuery<UserGradeResponse>({
queryKey: ['userGrade'],
queryFn: getUserGrade,
});

if (isLoading) return <div className="text-center mt-10">로딩 중...</div>;
if (error || !data || !data.grade) return <div className="text-center mt-10 text-red-400">데이터를 불러오지 못했습니다.</div>;

const userLevelNumber = gradeToLevelMap[data.grade];

if (userLevelNumber === undefined) {
return <div className="text-center mt-10 text-red-400">알 수 없는 레벨입니다.</div>;
}

return (
<div className="px-4 py-3 text-white min-h-screen font-suit">
{/* <HeaderBasic>{null}</HeaderBasic> */}
<Header leftSection="BACK" rightSection="NONE"> </Header>

{/* 현재 레벨 박스 */}
<MyLevelCard
userLevel={currentUser.level}
userProgress={currentUser.progress}
currentReviewCount={currentUserStatus.reviewCount}
currentLikeCount={currentUserStatus.likeCount}
/>
<div className="pt-[44px]">
<MyLevelCard
userLevel={userLevelNumber}
userProgress={data.levelExp || 0}
currentReviewCount={data.reviewCount || 0}
currentLikeCount={data.likeCount || 0}
/>
</div>

{/* 구분선 */}
<div className="w-[335px] h-[1px] bg-[#424242] mt-6 mb-6 mx-auto" />

{/* 레벨 리스트 */}
<div className="space-y-4">
{LEVELS_DATA.map((levelData) => (
<LevelInfoCard
Expand Down
16 changes: 11 additions & 5 deletions src/pages/my/MyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const MyPage: React.FC = () => {
navigate('/my/settings');
};

const handleLevelCardClick = () => {
navigate('/my/level'); // 경로를 '/my/level'로 수정했습니다.
};

if (isLoading) {
return <div>프로필 불러오는 중</div>;
}
Expand Down Expand Up @@ -127,11 +131,13 @@ const MyPage: React.FC = () => {
</div>
</section>

<LevelCard
userProgress={user.levelExp}
currentReviewCount={user.reviewCount}
currentLikeCount={user.likeCount}
/>
<div onClick={handleLevelCardClick} className="cursor-pointer">
<LevelCard
userProgress={user.levelExp}
currentReviewCount={user.reviewCount}
currentLikeCount={user.likeCount}
/>
</div>

{/* 메뉴 리스트 */}
<section>
Expand Down
1 change: 0 additions & 1 deletion src/pages/search/ReviewSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,3 @@ export default function ReviewSearchPage() {
}



2 changes: 1 addition & 1 deletion src/pages/search/ReviewSearchResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export default function ReviewSearchResultPage() {
</div>
</div>
);
}
}
15 changes: 15 additions & 0 deletions src/types/level.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface UserGradeResponse {
id: number;
email: string;
socialId: string;
username: string;
nickname: string;
imageUrl: string | null;
grade: number;
genres: string[];
social: 'KAKAO' | 'NAVER';
auditoriums: string[];
reviewCount: number;
likeCount: number;
levelExp: number;
}