Skip to content

feat: 마이페이지 UI 개선 - #22

Open
mingggg046779-rgb wants to merge 1 commit into
developfrom
feat/mypage-ui
Open

feat: 마이페이지 UI 개선#22
mingggg046779-rgb wants to merge 1 commit into
developfrom
feat/mypage-ui

Conversation

@mingggg046779-rgb

@mingggg046779-rgb mingggg046779-rgb commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

작업 내용

  • 마이페이지 전체 레이아웃 및 가독성 개선
  • 프로필 영역 디자인 정리
  • 이번 달 목표 카드 추가
  • 이번 달 러닝 요약 카드 정리
  • 최근 활동 기록 3개 미리보기 적용
  • 하단 CTA 버튼 제거
  • 우측 상단 더보기 메뉴 적용

확인 사항

  • /mypage 화면 정상 렌더링 확인
  • User API 연동 상태 유지 확인
  • 최근 활동 데이터 표시 확인
  • 기존 기능 로직 변경 없음

Note

Low Risk
Mostly presentational React/CSS; the only behavioral change is logout via existing clearAuthSession, with no API or auth logic changes described in the diff.

Overview
Redesigns the /mypage screen as a mobile-first profile view: sticky header with back navigation and a 더보기 overflow menu (profile edit, notifications, privacy placeholders; 로그아웃 clears the session and routes home).

The page still loads data via useMypageData and adds presentation-only pieces: a hero profile block (avatar with fallback image, run-status dot, monthly run count), an 이번 달 목표 card with km progress and a progress bar, an 이번 달 러닝 stats grid (distance, average pace with derived fallback, run count), and 최근 활동 limited to three items with optional deep links to /running-record/:id and an empty state when there is no real activity data.

Companion mypage.module.css defines the card layout, gradients, and max-width shell styling. 전체보기 is wired in the UI but its handler is still a no-op.

Reviewed by Cursor Bugbot for commit 45794d5. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Jun 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
runsync-fe Ready Ready Preview, Comment Jun 6, 2026 1:03pm

Request Review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 45794d5. Configure here.

? Math.min(100, Math.round((currentDistanceKm / monthlyGoalKm) * 100))
: 0;
const averagePaceLabel = stats.averagePaceLabel
|| getAveragePaceLabel(previewActivities, `6'20"`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monthly pace uses preview only

Medium Severity

When stats.averagePaceLabel is missing, 평균 페이스 in 이번 달 러닝 is derived via getAveragePaceLabel(previewActivities, …), so only the first three recent activities are included. That value can disagree with the month’s total distance and run count shown in the same card.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 45794d5. Configure here.

}
};

const handleViewMoreActivities = () => {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View all button does nothing

Medium Severity

The 최근 활동 header wires 전체보기 to handleViewMoreActivities, which is an empty function, so the control never navigates or opens a full activity list despite looking like an active link.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 45794d5. Configure here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Mypage component and its associated CSS module, which displays user profile information, monthly running goals, statistics, and recent activities. The feedback highlights two key improvement opportunities: first, implementing defensive programming (such as optional chaining and default values) when destructuring data from useMypageData to prevent potential runtime errors during loading states; second, implementing the routing logic within the currently empty handleViewMoreActivities handler to make the 'View More' button functional.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +108 to +124
const {
user,
stats,
activities,
isLoading,
isUsingMockData,
} = useMypageData();

const dotClass = getDotClassName(user.status);
const previewActivities = activities.slice(0, PREVIEW_ACTIVITY_COUNT);
const monthlyGoalKm = Number(stats.monthlyGoalKm) || MONTHLY_GOAL_KM;
const currentDistanceKm = Number(stats.totalDistanceKm) || 0;
const goalProgress = monthlyGoalKm > 0
? Math.min(100, Math.round((currentDistanceKm / monthlyGoalKm) * 100))
: 0;
const averagePaceLabel = stats.averagePaceLabel
|| getAveragePaceLabel(previewActivities, `6'20"`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

데이터를 불러오는 중(isLoading이 true인 경우)이나 API 응답이 지연될 때, useMypageData()에서 반환하는 user, stats, activities 객체가 undefined 또는 null일 가능성이 있습니다. 이 경우 user.status, activities.slice, stats.monthlyGoalKm 등을 직접 참조하면 런타임 에러(TypeError)가 발생하여 화면이 정상적으로 렌더링되지 않고 화이트스크린이 발생할 수 있습니다.

안전한 렌더링을 위해 구조 분해 할당 시 기본값을 지정하거나, 옵셔널 체이닝(?.) 및 널 병합 연산자(??)를 사용하여 방어적 코드(Defensive Programming)를 작성하는 것이 좋습니다.

Suggested change
const {
user,
stats,
activities,
isLoading,
isUsingMockData,
} = useMypageData();
const dotClass = getDotClassName(user.status);
const previewActivities = activities.slice(0, PREVIEW_ACTIVITY_COUNT);
const monthlyGoalKm = Number(stats.monthlyGoalKm) || MONTHLY_GOAL_KM;
const currentDistanceKm = Number(stats.totalDistanceKm) || 0;
const goalProgress = monthlyGoalKm > 0
? Math.min(100, Math.round((currentDistanceKm / monthlyGoalKm) * 100))
: 0;
const averagePaceLabel = stats.averagePaceLabel
|| getAveragePaceLabel(previewActivities, `6'20"`);
const {
user = {},
stats = {},
activities = [],
isLoading,
isUsingMockData,
} = useMypageData();
const dotClass = getDotClassName(user?.status);
const previewActivities = (activities || []).slice(0, PREVIEW_ACTIVITY_COUNT);
const monthlyGoalKm = Number(stats?.monthlyGoalKm) || MONTHLY_GOAL_KM;
const currentDistanceKm = Number(stats?.totalDistanceKm) || 0;
const goalProgress = monthlyGoalKm > 0
? Math.min(100, Math.round((currentDistanceKm / monthlyGoalKm) * 100))
: 0;
const averagePaceLabel = stats?.averagePaceLabel
|| getAveragePaceLabel(previewActivities, "6'20\"");

}
};

const handleViewMoreActivities = () => {};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

handleViewMoreActivities 함수가 빈 함수로 정의되어 있어, '최근 활동' 영역의 '전체보기' 버튼을 클릭해도 아무런 동작이 일어나지 않습니다. 전체 활동 페이지로 이동하는 라우팅 로직(예: navigate('/activities'))을 추가하거나, 아직 구현되지 않은 기능이라면 버튼을 비활성화하거나 적절한 안내 처리를 추가하는 것이 좋습니다.

  const handleViewMoreActivities = () => {
    navigate('/activities');
  };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant