-
Couldn't load subscription status.
- Fork 3
Qi1 221 프론트 최종본 #133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Qi1 221 프론트 최종본 #133
The head ref may contain hidden characters: "QI1-221-\uD504\uB860\uD2B8-\uCD5C\uC885\uBCF8"
Conversation
There was a problem hiding this 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-hiddenacross various components, includingAnimatedTabContent.tsx,trading-history-page.tsx,point/page.tsx, andreport-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.tsxcomponent. This involved defining a newNavItemtype to distinguish between navigation links and action items, updating theNAV_ITEMSarray, and implementing thehandleLogoutfunction 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.tsxtoDataUploadSection.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.tsxandpoint/page.tsx. This was achieved by refininguseEffectdependencies and usinguseRefforIntersection Observercallbacks, 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.tsxhas been significantly improved. The newLoadingStatecomponent 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
-
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. ↩
There was a problem hiding this 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 관련 버그 수정 등 전반적인 코드 품질과 사용자 경험을 개선하는 여러 중요한 변경 사항을 포함하고 있습니다. 특히, IntersectionObserver와 useEffect 의존성 문제를 해결하여 안정성을 높인 점이 인상적입니다.
다만, 몇몇 catch 블록이 비어있어 API 요청 실패 시 에러를 파악하기 어려운 부분이 있습니다. 이는 스타일 가이드에서 강조하는 우아한 에러 처리 및 로깅 원칙에 위배될 수 있으므로, 관련 코멘트를 참고하여 수정하는 것을 권장합니다.
전반적으로 코드의 안정성과 유지보수성을 크게 향상시키는 좋은 변경이라고 생각합니다.
| } catch { | ||
| setUploadMessage(UPLOAD_ERROR_MESSAGE.DEFAULT); | ||
| setUploadMessageType('error'); | ||
| setUploadedFile(null); | ||
| } finally { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
| try { | ||
| await logout(); | ||
| router.push('/'); | ||
| } catch {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handleLogout 함수의 catch 블록이 비어있어 로그아웃 API 호출 실패 시 에러를 인지할 수 없습니다. 1
logout 스토어 액션이 내부적으로 상태를 초기화하더라도, API 요청 실패는 사용자에게 알리거나 로깅하여 추적하는 것이 좋습니다. 예를 들어, 네트워크 문제로 로그아웃에 실패했지만 UI는 로그아웃된 것처럼 보일 수 있습니다.
} catch (error) {
// console.error('로그아웃 실패:', error);
// toast.error('로그아웃 중 문제가 발생했습니다.');
}Style Guide References
Footnotes
| // 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 재설정 방지 | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| isLoadingRef.current = false; | ||
| } | ||
| }, [activeTab, selectedYear, selectedMonth, balance.money]); | ||
| }, [activeTab, selectedYear, selectedMonth]); // balance.money 의존성 제거로 무한 observer 재설정 방지 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // 탭 변경 또는 포인트 월별 조회 변경 시 데이터 로드 (초기 중복 방지) | ||
| 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]); // 실제 변경되는 값들 의존성 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| url.searchParams.set('type', newTab); | ||
| window.history.pushState({}, '', url.toString()); | ||
| }, []); | ||
| }, []); // activeTab 의존성 제거로 무한 루프 방지 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
📝 변경 사항
🔍 변경 사항 세부 설명
🕵️♀️ 요청사항
📷 스크린샷 (선택)