-
Notifications
You must be signed in to change notification settings - Fork 1
feat(client): 사이드바 유저 정보 모달 및 api 작업 #219
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||||||||||||||
| import { Icon } from '@pinback/design-system/icons'; | ||||||||||||||||||||||||||||||||||||
| const SideInfoPop = () => { | ||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||
| <div className="bg-white-bg common-shadow absolute left-[19.6rem] top-[6.8rem] z-10 flex h-[32rem] w-[26rem] flex-col items-center justify-center rounded-[12px] py-[2.4rem]"> | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Portal을 사용하여 팝업을 렌더링하세요. PR 목표에 "Portal 처리"가 명시되어 있지만, 현재 팝업이 일반 DOM 구조로 렌더링되고 있습니다. 🔎 제안하는 수정 방법React의 import { createPortal } from 'react-dom';
const SideInfoPop = ({ sideInfo, onClose, onLogout }: SideInfoPopProps) => {
if (!sideInfo) return null;
return createPortal(
<>
<div
className="fixed inset-0 bg-black/20 z-40"
onClick={onClose}
/>
<div className="bg-white-bg common-shadow fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-50 flex h-[32rem] w-[26rem] flex-col items-center justify-center rounded-[12px] py-[2.4rem]">
{/* 기존 내용 */}
</div>
</>,
document.body
);
};참고: 기존 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| <img | ||||||||||||||||||||||||||||||||||||
| src="https://blog.kakaocdn.net/dna/kXF6L/btrt5yaCuuH/AAAAAAAAAAAAAAAAAAAAAEC2uoT7qWaQUOtDL18xi3PXMOakg5-QzqBlHNEzXJJv/%EC%B9%B4%ED%86%A1%20%EA%B8%B0%EB%B3%B8%ED%94%84%EB%A1%9C%ED%95%84%20%EC%82%AC%EC%A7%84(%EC%97%B0%EC%97%B0%EB%91%90ver).jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1767193199&allow_ip=&allow_referer=&signature=nnJLy%2F48M51zZd6WvzDD0VJiMZA%3D&attach=1&knm=img.jpg" | ||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 어떤 url인가요? |
||||||||||||||||||||||||||||||||||||
| className="my-[0.8rem] h-[13.2rem] w-[13.2rem] rounded-full" | ||||||||||||||||||||||||||||||||||||
| alt="유저 프로필 이미지" | ||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+6
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 외부 이미지 URL을 안전한 방식으로 변경하세요. 카카오 CDN의 임시 자격 증명이 포함된 외부 URL을 하드코딩하는 것은 보안 위험이 있습니다. 자격 증명이 만료되면 이미지가 로드되지 않을 수 있습니다. 🔎 제안하는 수정 방법 <img
- src="https://blog.kakaocdn.net/dna/kXF6L/btrt5yaCuuH/AAAAAAAAAAAAAAAAAAAAAEC2uoT7qWaQUOtDL18xi3PXMOakg5-QzqBlHNEzXJJv/%EC%B9%B4%ED%86%A1%20%EA%B8%B0%EB%B3%B8%ED%94%84%EB%A1%9C%ED%95%84%20%EC%82%AC%EC%A7%84(%EC%97%B0%EC%97%B0%EB%91%90ver).jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1767193199&allow_ip=&allow_referer=&signature=nnJLy%2F48M51zZd6WvzDD0VJiMZA%3D&attach=1&knm=img.jpg"
+ src={sideInfo?.profileImage || '/default-profile.png'}
className="my-[0.8rem] h-[13.2rem] w-[13.2rem] rounded-full"
alt="유저 프로필 이미지"
/>참고: 기본 프로필 이미지를 프로젝트 assets에 추가하세요.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| <p className="sub1-sb text-font-black-1 mb-[0.4rem]">이름</p> | ||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col items-center justify-center gap-[0.2rem]"> | ||||||||||||||||||||||||||||||||||||
| <p className="body4-r text-font-gray-3">이메일</p> | ||||||||||||||||||||||||||||||||||||
| <div className="mb-[1.86em] flex justify-between gap-[0.4rem]"> | ||||||||||||||||||||||||||||||||||||
| <Icon name="ic_clock_active" width={16} height={16} /> | ||||||||||||||||||||||||||||||||||||
| <p className="caption2-m text-font-gray-3">리마인드 알람</p> | ||||||||||||||||||||||||||||||||||||
| <p className="caption2-m text-font-gray-3">AM 09:00</p> | ||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 하드코딩된 데이터를 동적 데이터로 교체하세요. "이름", "이메일", "AM 09:00" 등의 텍스트가 하드코딩되어 있습니다. API에서 받아온 실제 사용자 데이터를 표시해야 합니다. Based on learnings, 하드코딩된 값은 임시 테스트 데이터로 실제 기능 구현 시 동적 데이터로 교체되어야 합니다. 🔎 제안하는 수정 방법- <p className="sub1-sb text-font-black-1 mb-[0.4rem]">이름</p>
+ <p className="sub1-sb text-font-black-1 mb-[0.4rem]">{sideInfo?.name}</p>
<div className="flex flex-col items-center justify-center gap-[0.2rem]">
- <p className="body4-r text-font-gray-3">이메일</p>
+ <p className="body4-r text-font-gray-3">{sideInfo?.email}</p>
<div className="mb-[1.86em] flex justify-between gap-[0.4rem]">
<Icon name="ic_clock_active" width={16} height={16} />
<p className="caption2-m text-font-gray-3">리마인드 알람</p>
- <p className="caption2-m text-font-gray-3">AM 09:00</p>
+ <p className="caption2-m text-font-gray-3">{sideInfo?.remindTime || 'AM 09:00'}</p>
</div>
</div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||
| type="button" | ||||||||||||||||||||||||||||||||||||
| className="sub5-sb text-font-black-1 border-gray200 h-[3.6rem] w-[10.8rem] rounded-[4px] border py-[0.8rem] text-center" | ||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||
| 로그아웃 | ||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+19
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로그아웃 버튼에 핸들러를 추가하세요. PR 목표에 "로그아웃 처리"가 명시되어 있지만, 로그아웃 버튼에 클릭 핸들러가 구현되지 않았습니다. 🔎 제안하는 수정 방법 <button
type="button"
className="sub5-sb text-font-black-1 border-gray200 h-[3.6rem] w-[10.8rem] rounded-[4px] border py-[0.8rem] text-center"
+ onClick={onLogout}
>
로그아웃
</button>그리고 부모 컴포넌트(Sidebar.tsx)에서 로그아웃 로직을 구현하세요: const handleLogout = () => {
localStorage.removeItem('token');
// 추가 로그아웃 처리 (예: 쿼리 캐시 초기화, 리다이렉트 등)
navigate('/login');
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||
| export default SideInfoPop; | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -10,12 +10,14 @@ import { useSidebarNav } from '@shared/hooks/useSidebarNav'; | |||||
| import { useCategoryPopups } from '@shared/hooks/useCategoryPopups'; | ||||||
| import OptionsMenuPortal from './OptionsMenuPortal'; | ||||||
| import PopupPortal from './PopupPortal'; | ||||||
| import SideInfoPop from './SideInfoPop'; | ||||||
| import { | ||||||
| useGetDashboardCategories, | ||||||
| usePostCategory, | ||||||
| useGetArcons, | ||||||
| usePutCategory, | ||||||
| useDeleteCategory, | ||||||
| useGetSideInfo, | ||||||
| } from '@shared/apis/queries'; | ||||||
| import { useEffect, useState } from 'react'; | ||||||
| import { useQueryClient } from '@tanstack/react-query'; | ||||||
|
|
@@ -33,7 +35,9 @@ export function Sidebar() { | |||||
| const { mutate: createCategory } = usePostCategory(); | ||||||
| const { data, isPending } = useGetArcons(); | ||||||
| const { mutate: deleteCategory } = useDeleteCategory(); | ||||||
| const { data: sideInfo } = useGetSideInfo(); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터 연동이 완료되지 않았습니다.
🔎 제안하는 수정 방법- const { data: sideInfo } = useGetSideInfo();
+ const { data: sideInfo, isLoading: isSideInfoLoading, isError: isSideInfoError } = useGetSideInfo();그리고 Line 134에서 SideInfoPop에 데이터를 전달하세요: - <SideInfoPop />
+ <SideInfoPop
+ sideInfo={sideInfo}
+ isLoading={isSideInfoLoading}
+ isError={isSideInfoError}
+ />📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| console.log('여기', sideInfo); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 디버그용 console.log를 제거하세요. 프로덕션 코드에 디버그용 console.log가 남아있습니다. 🔎 제안하는 수정 방법- console.log('여기', sideInfo);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| const { | ||||||
| activeTab, | ||||||
| selectedCategoryId, | ||||||
|
|
@@ -126,7 +130,9 @@ export function Sidebar() { | |||||
| const canCreateMore = categoryCount < MAX_CATEGORIES; | ||||||
|
|
||||||
| return ( | ||||||
| <aside className="bg-white-bg sticky top-0 h-screen w-[24rem] border-r border-gray-300"> | ||||||
| <aside className="bg-white-bg relative sticky top-0 h-screen w-[24rem] border-r border-gray-300"> | ||||||
| <SideInfoPop /> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 팝업 표시/숨김 로직이 구현되지 않았습니다.
🔎 제안하는 수정 방법상태를 추가하여 팝업의 표시 여부를 제어하세요: + const [isSideInfoOpen, setIsSideInfoOpen] = useState(false);
return (
<aside className="bg-white-bg relative sticky top-0 h-screen w-[24rem] border-r border-gray-300">
- <SideInfoPop />
+ {isSideInfoOpen && (
+ <SideInfoPop
+ sideInfo={sideInfo}
+ onClose={() => setIsSideInfoOpen(false)}
+ />
+ )}그리고 프로필 이미지나 버튼을 추가하여 팝업을 열 수 있도록 하세요.
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| <div className="flex h-full flex-col px-[0.8rem]"> | ||||||
| <header className="px-[0.8rem] py-[2.8rem]"> | ||||||
| <Icon | ||||||
|
|
||||||
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.
컴포넌트에 props 인터페이스를 추가하세요.
컴포넌트가 props를 받지 않아 동적 데이터를 표시할 수 없습니다. 유저 정보와 이벤트 핸들러를 받을 수 있도록 props 인터페이스를 정의해야 합니다.
🔎 제안하는 수정 방법
🤖 Prompt for AI Agents