Skip to content

Conversation

@seungwoo505
Copy link
Collaborator

📝 변경 사항

🔍 변경 사항 세부 설명

🕵️‍♀️ 요청사항

📷 스크린샷 (선택)

@github-actions github-actions bot enabled auto-merge August 7, 2025 02:30
Copy link

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

Choose a reason for hiding this comment

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

Summary of Changes

Hello @seungwoo505, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on enhancing the front-end user experience and improving code maintainability. I've made several UI/UX improvements by addressing layout issues with overflow-hidden properties. A new logout feature has been implemented in the header, providing a direct way for users to sign out. The data upload mechanism has been refactored for better modularity and more robust error handling. Additionally, I've optimized the infinite scroll functionality to prevent unnecessary data fetches and improved the visual feedback during loading states.

Highlights

  • UI/UX Enhancements: Overflow Handling: I've implemented overflow-hidden across various components, including AnimatedTabContent.tsx, trading-history-page.tsx, point/page.tsx, and report-history/page.tsx. This change ensures that content within these sections is properly clipped, preventing layout shifts and improving the overall visual consistency and user experience.
  • New Feature: Logout Functionality: I've added a new logout button to the Header.tsx component. This involved defining a new NavItem type to distinguish between navigation links and action items, updating the NAV_ITEMS array, and implementing the handleLogout function to manage the logout process and redirection. This provides a clear and functional way for users to log out.
  • Refactoring: Data Upload Logic: I've refactored the data upload logic by moving it from HistoryDetailModal.tsx to DataUploadSection.tsx. This change centralizes the upload functionality and includes enhanced error handling with specific messages based on API status codes (e.g., bad request, gateway timeout). This improves modularity and provides clearer feedback to the user during file uploads.
  • Performance Optimization: Infinite Scroll: I've addressed potential infinite loop issues in the infinite scroll implementation within PointContent.tsx and point/page.tsx. This was achieved by refining useEffect dependencies and using useRef for Intersection Observer callbacks, ensuring that data loading is triggered only when necessary and preventing redundant API calls.
  • User Experience: Enhanced Loading States: The loading state skeleton in point/page.tsx has been significantly improved. The new LoadingState component now more accurately reflects the layout of the actual content, providing a better visual experience for users while data is being fetched. This enhances perceived performance and user satisfaction.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@seungwoo505 seungwoo505 self-assigned this Aug 7, 2025
@seungwoo505 seungwoo505 added the FIX Something isn't working label Aug 7, 2025
Copy link

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

Choose a reason for hiding this comment

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

Code Review

이 PR은 로그아웃 기능 추가, 데이터 업로드 로직 리팩토링, 무한 스크롤 및 useEffect 관련 버그 수정 등 전반적인 코드 품질과 사용자 경험을 개선하는 여러 중요한 변경 사항을 포함하고 있습니다. 특히, IntersectionObserveruseEffect 의존성 문제를 해결하여 안정성을 높인 점이 인상적입니다.

다만, 몇몇 catch 블록이 비어있어 API 요청 실패 시 에러를 파악하기 어려운 부분이 있습니다. 이는 스타일 가이드에서 강조하는 우아한 에러 처리 및 로깅 원칙에 위배될 수 있으므로, 관련 코멘트를 참고하여 수정하는 것을 권장합니다.

전반적으로 코드의 안정성과 유지보수성을 크게 향상시키는 좋은 변경이라고 생각합니다.

Comment on lines +102 to 106
} catch {
setUploadMessage(UPLOAD_ERROR_MESSAGE.DEFAULT);
setUploadMessageType('error');
setUploadedFile(null);
} finally {

Choose a reason for hiding this comment

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

medium

catch 블록이 에러 객체를 받지 않고 있어 에러의 원인을 파악하기 어려워 디버깅이 힘들어질 수 있습니다. 1

catch (error)와 같이 에러 객체를 명시적으로 받아 로깅하는 것을 권장합니다. 2

또한, 네트워크 오류나 서버 오류 등 다양한 예외 상황을 고려하여 setUploadedFile(null) 호출이 항상 적절한지 검토해볼 필요가 있습니다. 예를 들어, 일시적인 네트워크 문제로 업로드에 실패했을 때 사용자가 파일을 다시 선택해야 하는 불편함이 있을 수 있습니다.

    } catch (error) {
      // console.error('데이터 전송 오류:', error); // 개발 중 디버깅을 위해 에러를 로깅하는 것이 좋습니다.
      setUploadMessage(UPLOAD_ERROR_MESSAGE.DEFAULT);
      setUploadMessageType('error');
      setUploadedFile(null);
    } finally {

Style Guide References

Footnotes

  1. 스타일 가이드에서는 우아한 에러 처리를 통해 사용자에게 의미 있는 에러 메시지를 제공하고 애플리케이션 크래시를 방지할 것을 권장합니다. 현재 구현은 모든 에러를 동일하게 처리하여 구체적인 원인을 파악하기 어렵습니다. (link)

  2. 스타일 가이드에서는 디버깅에 도움이 되는 관련 정보를 로그에 포함할 것을 권장합니다. 에러 객체를 로깅하면 문제 해결에 큰 도움이 됩니다. (link)

try {
await logout();
router.push('/');
} catch {}

Choose a reason for hiding this comment

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

medium

handleLogout 함수의 catch 블록이 비어있어 로그아웃 API 호출 실패 시 에러를 인지할 수 없습니다. 1

logout 스토어 액션이 내부적으로 상태를 초기화하더라도, API 요청 실패는 사용자에게 알리거나 로깅하여 추적하는 것이 좋습니다. 예를 들어, 네트워크 문제로 로그아웃에 실패했지만 UI는 로그아웃된 것처럼 보일 수 있습니다.

    } catch (error) {
      // console.error('로그아웃 실패:', error);
      // toast.error('로그아웃 중 문제가 발생했습니다.');
    }

Style Guide References

Footnotes

  1. 스타일 가이드에서는 예외가 발생할 수 있는 코드를 격리하고, 사용자에게 의미 있는 에러 메시지를 제공하여 우아하게 에러를 처리할 것을 권장합니다. 현재 구현은 로그아웃 실패를 조용히 무시하고 있습니다. (link)

Comment on lines +45 to 69
// Intersection Observer 콜백 (무한 호출 방지)
const onLoadMoreRef = useRef(onLoadMore);
const hasNextRef = useRef(hasNext);
const isLoadingMoreRef = useRef(isLoadingMore);

// 최신 값들을 ref에 저장
useEffect(() => {
onLoadMoreRef.current = onLoadMore;
hasNextRef.current = hasNext;
isLoadingMoreRef.current = isLoadingMore;
});

const handleObserver = useCallback(
(entries: IntersectionObserverEntry[]) => {
const target = entries[0];
if (target.isIntersecting && hasNext && !isLoadingMore) {
onLoadMore();
if (
target.isIntersecting &&
hasNextRef.current &&
!isLoadingMoreRef.current
) {
onLoadMoreRef.current();
}
},
[hasNext, isLoadingMore, onLoadMore]
[] // 의존성 제거로 observer 재설정 방지
);

Choose a reason for hiding this comment

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

medium

무한 스크롤 로직을 useRefuseEffect를 사용하여 개선한 점이 매우 좋습니다. handleObserver의 의존성 배열을 비워 IntersectionObserver가 불필요하게 재생성되는 것을 방지하고, ref를 통해 항상 최신 상태와 함수를 참조하도록 하여 안정성을 높였습니다. 이는 잠재적인 버그를 예방하고 성능을 최적화하는 좋은 리팩토링입니다.

isLoadingRef.current = false;
}
}, [activeTab, selectedYear, selectedMonth, balance.money]);
}, [activeTab, selectedYear, selectedMonth]); // balance.money 의존성 제거로 무한 observer 재설정 방지

Choose a reason for hiding this comment

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

medium

useEffect의 의존성 배열에서 balance.money를 제거하여 무한 루프를 방지한 것은 좋은 수정입니다. loadPointData 함수가 balance 상태를 변경할 수 있으므로, 의존성 배열에 포함되면 의도치 않은 재호출을 유발할 수 있습니다. 이 변경으로 컴포넌트의 안정성이 향상되었습니다.

Comment on lines +213 to +234
// 탭 변경 또는 포인트 월별 조회 변경 시 데이터 로드 (초기 중복 방지)
const prevValuesRef = useRef({ activeTab, selectedYear, selectedMonth });
useEffect(() => {
// 초기 로드가 완료된 후에만 탭/월 변경 시 데이터 로드
if (isInitialLoadRef.current) {
loadPointData();
const currentValues = { activeTab, selectedYear, selectedMonth };
const prevValues = prevValuesRef.current;

// 값이 실제로 변경되었고, 초기 로드가 완료된 경우에만 실행
const hasChanged =
prevValues.activeTab !== currentValues.activeTab ||
prevValues.selectedYear !== currentValues.selectedYear ||
prevValues.selectedMonth !== currentValues.selectedMonth;

if (!isInitialLoadRef.current || !hasChanged) {
prevValuesRef.current = currentValues; // 값 업데이트
return; // 초기 로드 미완료 또는 값 변경 없음
}
}, [loadPointData]); // loadPointData만 의존성으로 사용

loadPointData();

// 이전 값 업데이트
prevValuesRef.current = currentValues;
}, [activeTab, selectedYear, selectedMonth, loadPointData]); // 실제 변경되는 값들 의존성

Choose a reason for hiding this comment

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

medium

useEffect 내에서 prevValuesRef를 사용하여 실제 값의 변경 여부를 확인하고 API를 호출하도록 수정한 것은 매우 좋은 방법입니다. 이로써 불필요한 API 호출을 막고, 초기 렌더링 시 데이터 중복 로드를 방지하여 성능과 안정성을 모두 개선했습니다.

url.searchParams.set('type', newTab);
window.history.pushState({}, '', url.toString());
}, []);
}, []); // activeTab 의존성 제거로 무한 루프 방지

Choose a reason for hiding this comment

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

medium

handleTabChange 함수의 useCallback 의존성 배열에서 activeTab을 제거하여 무한 루프 발생 가능성을 차단한 것은 올바른 조치입니다. 이 함수는 activeTab 상태를 변경하지만 직접 사용하지는 않으므로, 의존성에서 제거하는 것이 맞습니다. 덕분에 코드의 안정성이 높아졌습니다.

Copy link
Contributor

@hyonun321 hyonun321 left a comment

Choose a reason for hiding this comment

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

LGTM

@github-actions github-actions bot merged commit 20ef18a into main Aug 7, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FIX Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants