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
31 changes: 23 additions & 8 deletions apps/client/src/pages/myBookmark/MyBookmark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@ const MyBookmark = () => {

const { mutate: updateToReadStatus } = usePutArticleReadStatus();
const { mutate: deleteArticle } = useDeleteRemindArticle();
const { data: articles } = useGetBookmarkArticles(0, 20);
const { data: articles, isPending } = useGetBookmarkArticles(0, 20);
const { data: unreadArticles } = useGetBookmarkUnreadArticles(0, 20);
const { data: categoryArticles } = useGetCategoryBookmarkArticles(
categoryId,
activeBadge === 'all',
1,
0,
10
);
Comment on lines 40 to 45
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

카테고리별 읽음 필터 캐시 키 누락 가능성 안내(별도 파일 패치)

useGetCategoryBookmarkArticles는 readStatus로 결과가 달라지지만 queryKey에 포함되어 있지 않아 배지 전환 시 캐시 재조회가 되지 않을 수 있습니다.

아래 패치를 별도 파일에 적용해 주세요.

파일: apps/client/src/pages/myBookmark/apis/queries.ts

 export const useGetCategoryBookmarkArticles = (
   categoryId: string | null,
   readStatus: boolean,
   page: number,
   size: number
 ): UseQueryResult<CategoryBookmarkArticleResponse, AxiosError> => {
   return useQuery({
-    queryKey: ['categoryBookmarkArticles', categoryId, page, size],
+    queryKey: ['categoryBookmarkArticles', categoryId, readStatus, page, size],
     queryFn: () =>
       getCategoryBookmarkArticles(categoryId, readStatus, page, size),
     enabled: !!categoryId,
   });
 };

검증 스크립트(키에 readStatus 누락된 다른 훅도 있는지 확인):


🏁 Script executed:

#!/bin/bash
# categoryBookmarkArticles 관련 queryKey에서 readStatus 포함 여부 점검
rg -nP "queryKey:\s*\[\s*'categoryBookmarkArticles'[^]]*\]" apps/client -C2

Length of output: 1836


쿼리 키에 readStatus 누락 — 수정 필요

useGetCategoryBookmarkArticles의 queryKey에 readStatus가 빠져 있어 배지(읽음/전체) 전환 시 캐시가 재조회되지 않습니다. 아래 패치를 apps/client/src/pages/myBookmark/apis/queries.ts에 적용하세요.

파일: apps/client/src/pages/myBookmark/apis/queries.ts

 export const useGetCategoryBookmarkArticles = (
   categoryId: string | null,
   readStatus: boolean,
   page: number,
   size: number
 ): UseQueryResult<CategoryBookmarkArticleResponse, AxiosError> => {
   return useQuery({
-    queryKey: ['categoryBookmarkArticles', categoryId, page, size],
+    queryKey: ['categoryBookmarkArticles', categoryId, readStatus, page, size],
     queryFn: () =>
       getCategoryBookmarkArticles(categoryId, readStatus, page, size),
     enabled: !!categoryId,
   });
 };

검증 결과:

  • 누락 위치: apps/client/src/pages/myBookmark/apis/queries.ts (queryKey — 줄 41).
  • invalidateQueries 호출 위치(참고): apps/client/src/shared/components/cardEditModal/CardEditModal.tsx (줄 112), apps/client/src/pages/myBookmark/MyBookmark.tsx (줄 71, 164). 이 호출들은 상위 키로 광범위 무효화하므로 우선 queries.ts 수정만으로 문제 해결됨. 필요하면 invalidateQueries에 readStatus를 포함해 더 좁게 무효화하세요.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data: categoryArticles } = useGetCategoryBookmarkArticles(
categoryId,
activeBadge === 'all',
1,
0,
10
);
export const useGetCategoryBookmarkArticles = (
categoryId: string | null,
readStatus: boolean,
page: number,
size: number
): UseQueryResult<CategoryBookmarkArticleResponse, AxiosError> => {
return useQuery({
queryKey: ['categoryBookmarkArticles', categoryId, readStatus, page, size],
queryFn: () =>
getCategoryBookmarkArticles(categoryId, readStatus, page, size),
enabled: !!categoryId,
});
};
🤖 Prompt for AI Agents
In apps/client/src/pages/myBookmark/apis/queries.ts around line 41, the queryKey
for useGetCategoryBookmarkArticles is missing the readStatus value so toggling
the read/all badge doesn't change the cache key; include the readStatus
parameter as an element in the queryKey array (alongside categoryId, offset,
limit) so the key differs when readStatus changes, leaving the rest of the hook
logic intact and then verify badge switches trigger a refetch.

console.log('categoryArticles', categoryArticles);

const { mutate: getArticleDetail, data: articleDetail } =
useGetArticleDetail();
Expand All @@ -56,8 +55,11 @@ const MyBookmark = () => {
containerRef,
} = useAnchoredMenu((anchor) => belowOf(anchor, 8));

const articlesToDisplay =
activeBadge === 'all' ? articles?.articles : unreadArticles?.articles;
const articlesToDisplay = category
? categoryArticles?.articles
: activeBadge === 'all'
? articles?.articles
: unreadArticles?.articles;

const handleDeleteArticle = (id: number) => {
deleteArticle(id, {
Expand Down Expand Up @@ -93,6 +95,11 @@ const MyBookmark = () => {
return <NoUnreadArticles />;
};

// TODO: 로딩 상태 디자인 필요
if (isPending) {
return <div>Loading...</div>;
}

return (
<div className="flex h-screen flex-col py-[5.2rem] pl-[8rem] pr-[5rem]">
<div className="flex items-center gap-[0.4rem]">
Expand All @@ -114,13 +121,21 @@ const MyBookmark = () => {
<div className="mt-[3rem] flex gap-[2.4rem]">
<Badge
text="전체보기"
countNum={articles?.totalArticle || 0}
countNum={
category
? categoryArticles?.totalArticle
: articles?.totalArticle || 0
}
onClick={() => handleBadgeClick('all')}
isActive={activeBadge === 'all'}
/>
<Badge
text="안 읽음"
countNum={articles?.totalUnreadArticle || 0}
countNum={
category
? categoryArticles?.totalUnreadArticle
: articles?.totalUnreadArticle || 0
}
onClick={() => handleBadgeClick('notRead')}
isActive={activeBadge === 'notRead'}
/>
Expand Down Expand Up @@ -220,7 +235,7 @@ const MyBookmark = () => {
)}

{/* 편집 모달 */}
{isEditOpen && (
{isEditOpen && articleDetail && (
<div className="fixed inset-0 z-[1000]" aria-modal="true" role="dialog">
<div
className="absolute inset-0 bg-black/60"
Expand Down
26 changes: 14 additions & 12 deletions apps/client/src/pages/remind/Remind.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { Badge, Card, PopupContainer } from '@pinback/design-system/ui';
import CardEditModal from '@shared/components/cardEditModal/CardEditModal';
import OptionsMenuPortal from '@shared/components/sidebar/OptionsMenuPortal';
Expand All @@ -23,16 +23,18 @@ const Remind = () => {
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
const [deleteTargetId, setDeleteTargetId] = useState<number | null>(null);

const formattedDate = formatLocalDateTime();
const formattedDate = useMemo(() => {
return formatLocalDateTime();
}, [activeBadge]);

const queryClient = useQueryClient();

const { mutate: updateToReadStatus } = usePutArticleReadStatus();
const { mutate: deleteArticle } = useDeleteRemindArticle();
const { data, isPending } = useGetRemindArticles(
const { data } = useGetRemindArticles(
formattedDate,
activeBadge === 'read',
1,
0,
10
);

Expand Down Expand Up @@ -78,9 +80,9 @@ const Remind = () => {
};

// TODO: 로딩 상태 디자인 필요
if (isPending) {
return <div>Loading...</div>;
}
// if (isPending) {
// return <div>Loading...</div>;
// }

return (
<div className="flex flex-col py-[5.2rem] pl-[8rem] pr-[5rem]">
Expand Down Expand Up @@ -110,10 +112,6 @@ const Remind = () => {
content={article.memo}
timeRemaining={article.remindAt}
category={article.category.categoryName}
{...(activeBadge === 'notRead' && {
onOptionsClick: (e) =>
openMenu(article.category.categoryId, e.currentTarget),
})}
onClick={() => {
window.open(article.url, '_blank');

Expand All @@ -131,6 +129,10 @@ const Remind = () => {
},
});
}}
onOptionsClick={(e) => {
e.stopPropagation();
openMenu(article.category.categoryId, e.currentTarget);
}}
/>
))}
</div>
Expand Down Expand Up @@ -185,7 +187,7 @@ const Remind = () => {
</div>
)}

{isEditOpen && (
{isEditOpen && articleDetail && (
<div className="fixed inset-0 z-[1000]" aria-modal="true" role="dialog">
<div
className="absolute inset-0 bg-black/60 backdrop-blur-[2px]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ import { useEffect, useState } from 'react';

export interface CardEditModalProps {
onClose: () => void;
prevData: ArticleDetailResponse | undefined;
prevData: ArticleDetailResponse;
}

export default function CardEditModal({
onClose,
prevData,
}: CardEditModalProps) {
const { meta } = usePageMeta(
'https://www.notion.so/PinBack-23927450eb1c8080a5a1f84a9d483aa9'
);
const { meta } = usePageMeta(prevData.url);
const { data: category } = useGetDashboardCategories();
const { mutate: editArticle } = usePutEditArticle();
const queryClient = useQueryClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ const MyBookmarkCard = ({
type="button"
aria-label="카테고리 상세"
className="cursor-pointer self-start"
onClick={(e) => onOptionsClick?.(e)}
onClick={(e) => {
e.stopPropagation();
onOptionsClick?.(e);
}}
>
<Icon name="ic_details_category" />
</button>
Expand Down
9 changes: 6 additions & 3 deletions packages/design-system/src/components/card/RemindCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const RemindCard = ({
content,
category,
imageUrl,
timeRemaining,
// timeRemaining,
onClick,
onOptionsClick,
}: RemindCardProps) => {
Expand All @@ -26,7 +26,7 @@ const RemindCard = ({
<div className="bg-gray900 flex items-center gap-[0.4rem] py-[1.2rem] pl-[1.6rem] text-sm text-white">
<Icon name="ic_clock_active" />
<span className="body2-m text-main400 mr-[0.2rem]">
{timeRemaining || '-'}
{/* {timeRemaining || '-'} */}-
</span>
<span className="body2-m text-white-bg">이후에 사라져요</span>
</div>
Expand All @@ -50,7 +50,10 @@ const RemindCard = ({
type="button"
aria-label="카테고리 상세"
className="cursor-pointer self-start"
onClick={(e) => onOptionsClick?.(e)}
onClick={(e) => {
e.stopPropagation();
onOptionsClick?.(e);
}}
>
<Icon name="ic_details_category" />
</button>
Expand Down
Loading