From 20debad68c4add3d7c6d098ec2064715744a6aa5 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 16:05:26 +0900 Subject: [PATCH 1/7] =?UTF-8?q?Feat(client):=20=EB=A6=AC=EB=A7=88=EC=9D=B8?= =?UTF-8?q?=EB=93=9C=20API=20=EB=B2=84=EC=A0=84=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=ED=83=80=EC=9E=85=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/remind/apis/axios.ts | 2 +- apps/client/src/pages/remind/types/api.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/client/src/pages/remind/apis/axios.ts b/apps/client/src/pages/remind/apis/axios.ts index ad899020..5efd68a3 100644 --- a/apps/client/src/pages/remind/apis/axios.ts +++ b/apps/client/src/pages/remind/apis/axios.ts @@ -6,7 +6,7 @@ export const getRemindArticles = async ( page: number, size: number ) => { - const { data } = await apiRequest.get(`/api/v2/articles/remind`, { + const { data } = await apiRequest.get(`/api/v3/articles/remind`, { params: { now: nowDate, 'read-status': readStatus, diff --git a/apps/client/src/pages/remind/types/api.ts b/apps/client/src/pages/remind/types/api.ts index 20d93911..eee763fa 100644 --- a/apps/client/src/pages/remind/types/api.ts +++ b/apps/client/src/pages/remind/types/api.ts @@ -1,4 +1,4 @@ -// 리마인드 전체 조회 +// 리마인드 전체 조회 (v3) interface Category { categoryId: number; categoryName: string; @@ -8,14 +8,19 @@ interface Category { export interface ArticleWithCategory { articleId: number; url: string; + title: string; + thumbnailUrl: string; memo: string; createdAt: string; isRead: boolean; + isReadAfterRemind: boolean; remindAt: string; category: Category; } export interface ArticleListResponse { + hasNext: boolean; + totalArticleCount: number; readArticleCount: number; unreadArticleCount: number; articles: ArticleWithCategory[]; From b7f6278d549e2e94e4b431b4a02eec2f50bec2f2 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 16:18:07 +0900 Subject: [PATCH 2/7] =?UTF-8?q?Feat(client):=20=EB=A6=AC=EB=A7=88=EC=9D=B8?= =?UTF-8?q?=EB=93=9C=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/remind/Remind.tsx | 137 +++++++++++------- .../remind/components/fetchCard/FetchCard.tsx | 39 ----- 2 files changed, 85 insertions(+), 91 deletions(-) delete mode 100644 apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx diff --git a/apps/client/src/pages/remind/Remind.tsx b/apps/client/src/pages/remind/Remind.tsx index 73880f62..db2fbf1d 100644 --- a/apps/client/src/pages/remind/Remind.tsx +++ b/apps/client/src/pages/remind/Remind.tsx @@ -1,6 +1,9 @@ -import { useMemo, useRef, useState, useEffect } from 'react'; +import { useGetRemindArticles } from '@pages/remind/apis/queries'; +import NoReadArticles from '@pages/remind/components/noReadArticles/NoReadArticles'; +import NoUnreadArticles from '@pages/remind/components/noUnreadArticles/NoUnreadArticles'; import { Badge, + Card, PopupContainer, trackPageView, } from '@pinback/design-system/ui'; @@ -8,29 +11,26 @@ import CardEditModal from '@shared/components/cardEditModal/CardEditModal'; import OptionsMenuPortal from '@shared/components/sidebar/OptionsMenuPortal'; import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu'; import { belowOf } from '@shared/utils/anchorPosition'; -import { REMIND_MOCK_DATA } from './constants'; -import { useGetRemindArticles } from '@pages/remind/apis/queries'; import { formatLocalDateTime } from '@shared/utils/formatDateTime'; -import NoReadArticles from '@pages/remind/components/noReadArticles/NoReadArticles'; -import NoUnreadArticles from '@pages/remind/components/noUnreadArticles/NoUnreadArticles'; +import { useEffect, useMemo, useRef, useState } from 'react'; +import { REMIND_MOCK_DATA } from './constants'; + import { - usePutArticleReadStatus, useDeleteRemindArticle, useGetArticleDetail, + usePutArticleReadStatus, } from '@shared/apis/queries'; -import { useQueryClient } from '@tanstack/react-query'; -import NoRemindArticles from './components/noRemindArticles/NoRemindArticles'; -import FetchCard from './components/fetchCard/FetchCard'; -import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll'; +import JobSelectionFunnel from '@shared/components/jobSelectionFunnel/JobSelectionFunnel'; import TooltipCard from '@shared/components/tooltipCard/TooltipCard'; +import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll'; +import { useQueryClient } from '@tanstack/react-query'; import Footer from './components/footer/Footer'; -import JobSelectionFunnel from '@shared/components/jobSelectionFunnel/JobSelectionFunnel'; +import NoRemindArticles from './components/noRemindArticles/NoRemindArticles'; const Remind = () => { useEffect(() => { trackPageView('대시보드 페이지 방문'); }, []); - const [isEditOpen, setIsEditOpen] = useState(false); const [activeBadge, setActiveBadge] = useState<'read' | 'notRead'>('notRead'); const [isDeleteOpen, setIsDeleteOpen] = useState(false); @@ -69,13 +69,18 @@ const Remind = () => { containerRef, } = useAnchoredMenu((anchor) => belowOf(anchor, 8)); + /** + * 24시간 유효한 리마인드만 표시 + */ + const articlesToDisplay = data?.pages .flatMap((page) => page.articles) .filter((article) => { const now = new Date().getTime(); + const remindTime = new Date(article.remindAt).getTime(); - // 만료 시간 = 리마인드 시간 + 24시간 + const expirationTime = remindTime + 24 * 60 * 60 * 1000; return now >= remindTime && now < expirationTime; @@ -87,13 +92,21 @@ const Remind = () => { const handleDeleteArticle = (id: number) => { deleteArticle(id, { onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['remindArticles'] }); - queryClient.invalidateQueries({ queryKey: ['arcons'] }); + queryClient.invalidateQueries({ + queryKey: ['remindArticles'], + }); + + queryClient.invalidateQueries({ + queryKey: ['arcons'], + }); + setIsDeleteOpen(false); + setDeleteTargetId(null); + closeMenu(); - close(); }, + onError: (error) => { console.error('아티클 삭제 실패:', error); }, @@ -106,6 +119,7 @@ const Remind = () => { const EmptyStateComponent = () => { const firstPageData = data?.pages[0]; + if ( firstPageData?.readArticleCount === 0 && firstPageData?.unreadArticleCount === 0 @@ -116,32 +130,28 @@ const Remind = () => { return activeBadge === 'read' ? : ; }; - // TODO: 로딩 상태 디자인 필요 if (isPending) { return
Loading...
; } - // TODO: 임시 - // const unreadArticleCount = data?.pages[0]?.unreadArticleCount || 0; - // const readArticleCount = data?.pages[0]?.readArticleCount || 0; - return (

리마인드

+
handleBadgeClick('notRead')} isActive={activeBadge === 'notRead'} /> + handleBadgeClick('read')} isActive={activeBadge === 'read'} />
+ {articlesToDisplay.length > 0 ? ( @@ -149,34 +159,58 @@ const Remind = () => { ref={scrollContainerRef} className="scrollbar-hide mt-[2.6rem] flex flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth" > - {articlesToDisplay.map((article) => ( - { - window.open(article.url, '_blank'); - - updateToReadStatus(article.articleId, { - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: ['remindArticles'], - }); - queryClient.invalidateQueries({ - queryKey: ['arcons'], - }); - }, - onError: (error) => { - console.error(error); - }, - }); - }} - onOptionsClick={(e) => { - e.stopPropagation(); - openMenu(article.articleId, e.currentTarget); - }} - /> - ))} -
+ {articlesToDisplay.map((article) => { + const displayTitle = article.title?.trim() + ? article.title + : '제목 없음'; + + const displayImageUrl = article.thumbnailUrl || undefined; + + return ( + { + window.open(article.url, '_blank'); + + updateToReadStatus(article.articleId, { + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: ['remindArticles'], + }); + + queryClient.invalidateQueries({ + queryKey: ['arcons'], + }); + }, + + onError: (error) => { + console.error(error); + }, + }); + }} + onOptionsClick={(e) => { + e.stopPropagation(); + + openMenu(article.articleId, e.currentTarget); + }} + /> + ); + })} + +
) : ( @@ -251,7 +285,6 @@ const Remind = () => {
{ - // TODO: 관심 직무 핀 API 연동 필요 setShowJobSelectionFunnel(false); }} /> diff --git a/apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx b/apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx deleted file mode 100644 index 5b7f0fb8..00000000 --- a/apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { ArticleWithCategory } from '@pages/remind/types/api'; -import { Card } from '@pinback/design-system/ui'; -import { useGetPageMeta } from '@shared/apis/queries'; -import React from 'react'; - -interface FetchCardProps { - article: ArticleWithCategory; - onClick: () => void; - onOptionsClick?: (e: React.MouseEvent) => void; -} - -const FetchCard = ({ article, onClick, onOptionsClick }: FetchCardProps) => { - const { data: meta, isPending, isError: error } = useGetPageMeta(article.url); - - if (isPending) { - return ( -
- ); - } - - const displayTitle = !error && meta.title ? meta.title : '제목 없음'; - const displayImageUrl = !error ? meta.image : undefined; - - return ( - - ); -}; - -export default FetchCard; From e9e84a50b75c38355868189687afcd7fca297744 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 17:36:43 +0900 Subject: [PATCH 3/7] =?UTF-8?q?Feat(client):=20API=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/shared/apis/axios.ts | 3 ++- apps/client/src/shared/types/api.ts | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/client/src/shared/apis/axios.ts b/apps/client/src/shared/apis/axios.ts index ee4edaca..efec01f4 100644 --- a/apps/client/src/shared/apis/axios.ts +++ b/apps/client/src/shared/apis/axios.ts @@ -48,8 +48,9 @@ export const putArticleReadStatus = async (articleId: number) => { return data; }; +// 이거 업데이트 export const getArticleDetail = async (articleId: number) => { - const { data } = await apiRequest.get(`/api/v1/articles/${articleId}`); + const { data } = await apiRequest.get(`/api/v3/articles/${articleId}`); return data.data; }; diff --git a/apps/client/src/shared/types/api.ts b/apps/client/src/shared/types/api.ts index e95fd1a8..0356454f 100644 --- a/apps/client/src/shared/types/api.ts +++ b/apps/client/src/shared/types/api.ts @@ -34,8 +34,10 @@ interface CategoryResponse { export interface ArticleDetailResponse { id: number; url: string; - memo: string; - remindAt: string; + title: string; + thumbnailUrl: string; + memo: string | null; + remindAt: string | null; createdAt: string; categoryResponse: CategoryResponse; } From 27dc685ccecb25b83f84075f5431bea9dfc65120 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 18:07:29 +0900 Subject: [PATCH 4/7] =?UTF-8?q?Feat(client):=20=20CardEditModal=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=95=B4=EB=8B=B9=20=EC=88=98=EC=A0=95=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/remind/Remind.tsx | 2 +- .../cardEditModal/CardEditModal.tsx | 22 +++++++------------ apps/client/src/shared/types/api.ts | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/apps/client/src/pages/remind/Remind.tsx b/apps/client/src/pages/remind/Remind.tsx index db2fbf1d..3f75b85f 100644 --- a/apps/client/src/pages/remind/Remind.tsx +++ b/apps/client/src/pages/remind/Remind.tsx @@ -273,7 +273,7 @@ const Remind = () => { />
setIsEditOpen(false)} prevData={articleDetail} /> diff --git a/apps/client/src/shared/components/cardEditModal/CardEditModal.tsx b/apps/client/src/shared/components/cardEditModal/CardEditModal.tsx index d2e6de21..c3395410 100644 --- a/apps/client/src/shared/components/cardEditModal/CardEditModal.tsx +++ b/apps/client/src/shared/components/cardEditModal/CardEditModal.tsx @@ -1,3 +1,4 @@ +import noImage from '@assets/client_thumb.svg'; import { Icon } from '@pinback/design-system/icons'; import { AutoDismissToast, @@ -17,13 +18,11 @@ import { useGetDashboardCategories, usePutEditArticle, } from '@shared/apis/queries'; -import { usePageMeta } from '@shared/hooks/usePageMeta'; import { ArticleDetailResponse, EditArticleRequest } from '@shared/types/api'; import { combineDateTime } from '@shared/utils/datetime'; import { updateDate, updateTime } from '@shared/utils/formatDateTime'; import { useQueryClient } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; -import noImage from '@assets/client_thumb.svg'; export interface CardEditModalProps { onClose: () => void; @@ -34,7 +33,6 @@ export default function CardEditModal({ onClose, prevData, }: CardEditModalProps) { - const { meta, loading } = usePageMeta(prevData.url); const { data: category } = useGetDashboardCategories(); const { mutate: editArticle } = usePutEditArticle(); const queryClient = useQueryClient(); @@ -86,7 +84,7 @@ export default function CardEditModal({ } const saveData = () => { - if (!prevData?.id) { + if (!prevData?.articleId) { console.error('Article ID is missing, cannot save.'); setToastIsOpen(true); return; @@ -106,7 +104,7 @@ export default function CardEditModal({ editArticle( { - articleId: prevData?.id, + articleId: prevData?.articleId, editArticleData, }, { @@ -185,15 +183,11 @@ export default function CardEditModal({ - {loading ? ( -
- ) : ( - - )} +

카테고리

diff --git a/apps/client/src/shared/types/api.ts b/apps/client/src/shared/types/api.ts index 0356454f..340b7add 100644 --- a/apps/client/src/shared/types/api.ts +++ b/apps/client/src/shared/types/api.ts @@ -32,7 +32,7 @@ interface CategoryResponse { } export interface ArticleDetailResponse { - id: number; + articleId: number; url: string; title: string; thumbnailUrl: string; From c70c6f5f3e18865e4140d778b2f28d805446adb9 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 18:09:22 +0900 Subject: [PATCH 5/7] =?UTF-8?q?Feat(client):=20MyBookmark=EC=9D=98CardEdit?= =?UTF-8?q?Modal=EC=9D=98=20key=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/myBookmark/MyBookmark.tsx | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/client/src/pages/myBookmark/MyBookmark.tsx b/apps/client/src/pages/myBookmark/MyBookmark.tsx index b92d1b92..213ae067 100644 --- a/apps/client/src/pages/myBookmark/MyBookmark.tsx +++ b/apps/client/src/pages/myBookmark/MyBookmark.tsx @@ -1,23 +1,23 @@ -import { PopupContainer } from '@pinback/design-system/ui'; -import { useState, useRef, Suspense } from 'react'; -import { useSearchParams } from 'react-router-dom'; +import MyBookmarkContent from '@pages/myBookmark/components/myBookmarkContent/MyBookmarkContent'; import { REMIND_MOCK_DATA } from '@pages/remind/constants'; -import CardEditModal from '@shared/components/cardEditModal/CardEditModal'; -import OptionsMenuPortal from '@shared/components/sidebar/OptionsMenuPortal'; -import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu'; -import { belowOf } from '@shared/utils/anchorPosition'; import { Icon } from '@pinback/design-system/icons'; -import { useQueryClient } from '@tanstack/react-query'; +import { PopupContainer } from '@pinback/design-system/ui'; import { - useGetArticleDetail, useDeleteRemindArticle, + useGetArticleDetail, usePutArticleReadStatus, } from '@shared/apis/queries'; -import TooltipCard from '@shared/components/tooltipCard/TooltipCard'; -import ArticlesLoadingBoundary from '@shared/components/articlesLoadingBoundary/ArticlesLoadingBoundary'; import ArticlesErrorBoundary from '@shared/components/articlesErrorBoundary/ArticlesErrorBoundary'; +import ArticlesLoadingBoundary from '@shared/components/articlesLoadingBoundary/ArticlesLoadingBoundary'; +import CardEditModal from '@shared/components/cardEditModal/CardEditModal'; +import OptionsMenuPortal from '@shared/components/sidebar/OptionsMenuPortal'; +import TooltipCard from '@shared/components/tooltipCard/TooltipCard'; +import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu'; +import { belowOf } from '@shared/utils/anchorPosition'; +import { useQueryClient } from '@tanstack/react-query'; +import { Suspense, useRef, useState } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; -import MyBookmarkContent from '@pages/myBookmark/components/myBookmarkContent/MyBookmarkContent'; +import { useSearchParams } from 'react-router-dom'; import Footer from './components/footer/Footer'; const MyBookmark = () => { @@ -163,7 +163,7 @@ const MyBookmark = () => { />
setIsEditOpen(false)} prevData={articleDetail} /> From cd81fe40f47d66a0b06194d1caab45fe1d030636 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 18:34:52 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/level/Level.tsx | 12 ++--- .../src/pages/myBookmark/MyBookmark.tsx | 2 +- .../myBookmarkContent/MyBookmarkContent.tsx | 17 +++---- apps/client/src/pages/remind/Remind.tsx | 4 +- apps/client/src/shared/apis/queries.ts | 46 +++++++++---------- .../src/shared/components/sidebar/Sidebar.tsx | 34 +++++++------- 6 files changed, 56 insertions(+), 59 deletions(-) diff --git a/apps/client/src/pages/level/Level.tsx b/apps/client/src/pages/level/Level.tsx index 1985bbf8..e33a9628 100644 --- a/apps/client/src/pages/level/Level.tsx +++ b/apps/client/src/pages/level/Level.tsx @@ -1,12 +1,12 @@ -import { Icon } from '@pinback/design-system/icons'; -import { cn } from '@pinback/design-system/utils'; import LevelScene from '@pages/level/components/LevelScene'; -import { getTreeLevel } from '@shared/utils/treeLevel'; import { TreeLevel } from '@pages/level/types/treeLevelType'; +import { Icon } from '@pinback/design-system/icons'; import { Badge } from '@pinback/design-system/ui'; -import { useGetArcons } from '@shared/apis/queries'; -import { lazy, Suspense } from 'react'; +import { cn } from '@pinback/design-system/utils'; +import { useGetAcorns } from '@shared/apis/queries'; import { Balloon } from '@shared/components/balloon/Balloon'; +import { getTreeLevel } from '@shared/utils/treeLevel'; +import { lazy, Suspense } from 'react'; const LevelInfoCard = lazy( () => import('@pages/level/components/LevelInfoCard') @@ -14,7 +14,7 @@ const LevelInfoCard = lazy( const NextAcornTime = lazy(() => import('./components/NextAcornTime')); export default function Level() { - const { data, isPending, isError } = useGetArcons(); + const { data, isPending, isError } = useGetAcorns(); if (isPending) return
; if (isError) return
; diff --git a/apps/client/src/pages/myBookmark/MyBookmark.tsx b/apps/client/src/pages/myBookmark/MyBookmark.tsx index 213ae067..f32efbc6 100644 --- a/apps/client/src/pages/myBookmark/MyBookmark.tsx +++ b/apps/client/src/pages/myBookmark/MyBookmark.tsx @@ -58,7 +58,7 @@ const MyBookmark = () => { queryClient.invalidateQueries({ queryKey: ['categoryBookmarkArticles'], }); - queryClient.invalidateQueries({ queryKey: ['arcons'] }); + queryClient.invalidateQueries({ queryKey: ['acorns'] }); setIsDeleteOpen(false); setDeleteTargetId(null); closeMenu(); diff --git a/apps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx b/apps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx index 64c752da..6725cc17 100644 --- a/apps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx +++ b/apps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx @@ -1,8 +1,8 @@ -import { useMyBookmarkContentData } from '@pages/myBookmark/hooks/useMyBookmarkContentData'; import NoArticles from '@pages/myBookmark/components/NoArticles/NoArticles'; import NoUnreadArticles from '@pages/myBookmark/components/noUnreadArticles/NoUnreadArticles'; -import { MutableRefObject } from 'react'; +import { useMyBookmarkContentData } from '@pages/myBookmark/hooks/useMyBookmarkContentData'; import { Badge, Card } from '@pinback/design-system/ui'; +import { MutableRefObject } from 'react'; interface MyBookmarkContentProps { activeBadge: 'all' | 'notRead'; @@ -25,12 +25,7 @@ const MyBookmarkContent = ({ queryClient, scrollContainerRef, }: MyBookmarkContentProps) => { - const { - view, - list, - counts, - pagination, - } = useMyBookmarkContentData({ + const { view, list, counts, pagination } = useMyBookmarkContentData({ activeBadge, category, categoryId, @@ -82,7 +77,9 @@ const MyBookmarkContent = ({ : article.category?.categoryName } categoryColor={ - view.isCategoryView ? undefined : article.category?.categoryColor + view.isCategoryView + ? undefined + : article.category?.categoryColor } date={new Date(article.createdAt).toLocaleDateString('ko-KR')} onClick={() => { @@ -101,7 +98,7 @@ const MyBookmarkContent = ({ queryClient.invalidateQueries({ queryKey: ['categoryBookmarkArticles'], }); - queryClient.invalidateQueries({ queryKey: ['arcons'] }); + queryClient.invalidateQueries({ queryKey: ['acorns'] }); }, onError: (error: any) => { console.error(error); diff --git a/apps/client/src/pages/remind/Remind.tsx b/apps/client/src/pages/remind/Remind.tsx index 3f75b85f..fe0c373a 100644 --- a/apps/client/src/pages/remind/Remind.tsx +++ b/apps/client/src/pages/remind/Remind.tsx @@ -97,7 +97,7 @@ const Remind = () => { }); queryClient.invalidateQueries({ - queryKey: ['arcons'], + queryKey: ['acorns'], }); setIsDeleteOpen(false); @@ -186,7 +186,7 @@ const Remind = () => { }); queryClient.invalidateQueries({ - queryKey: ['arcons'], + queryKey: ['acorns'], }); }, diff --git a/apps/client/src/shared/apis/queries.ts b/apps/client/src/shared/apis/queries.ts index 35a9fd9a..aebbde56 100644 --- a/apps/client/src/shared/apis/queries.ts +++ b/apps/client/src/shared/apis/queries.ts @@ -1,38 +1,38 @@ -import { - useMutation, - UseMutationResult, - useQuery, - UseQueryResult, - useSuspenseQuery, -} from '@tanstack/react-query'; import { deleteCategory, - getDashboardCategories, - postCategory, - postSignUp, - postSignUpRequest, - putEditArticle, - putCategory, - putArticleReadStatus, - getArticleDetail, - getAcorns, deleteRemindArticle, + getAcorns, + getArticleDetail, + getDashboardCategories, getGoogleProfile, - getMyProfile, getJobs, + getMyProfile, patchUserJob, patchUserJobRequest, + postCategory, + postSignUp, + postSignUpRequest, + putArticleReadStatus, + putCategory, + putEditArticle, } from '@shared/apis/axios'; -import { AxiosError } from 'axios'; import { - DashboardCategoriesResponse, AcornsResponse, - EditArticleRequest, - ArticleReadStatusResponse, ArticleDetailResponse, + ArticleReadStatusResponse, + DashboardCategoriesResponse, + EditArticleRequest, JobsResponse, } from '@shared/types/api'; import { fetchOGData } from '@shared/utils/fetchOgData'; +import { + useMutation, + UseMutationResult, + useQuery, + UseQueryResult, + useSuspenseQuery, +} from '@tanstack/react-query'; +import { AxiosError } from 'axios'; export const useGetDashboardCategories = (): UseQueryResult< DashboardCategoriesResponse, @@ -62,9 +62,9 @@ export const useDeleteCategory = () => { }); }; -export const useGetArcons = (): UseQueryResult => { +export const useGetAcorns = (): UseQueryResult => { return useQuery({ - queryKey: ['arcons'], + queryKey: ['acorns'], queryFn: () => getAcorns(), }); }; diff --git a/apps/client/src/shared/components/sidebar/Sidebar.tsx b/apps/client/src/shared/components/sidebar/Sidebar.tsx index fa36a62b..70de0def 100644 --- a/apps/client/src/shared/components/sidebar/Sidebar.tsx +++ b/apps/client/src/shared/components/sidebar/Sidebar.tsx @@ -1,29 +1,29 @@ -import Lottie from 'lottie-react'; import Chippiface from '@assets/5_chippiface.json'; import { Icon } from '@pinback/design-system/icons'; -import SideItem from './SideItem'; -import AccordionItem from './AccordionItem'; -import CategoryItem from './CategoryItem'; -import CreateItem from './CreateItem'; -import MyLevelItem from './MyLevelItem'; -import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu'; -import { rightOf } from '@shared/utils/anchorPosition'; -import { useSidebarNav } from '@shared/hooks/useSidebarNav'; -import { useCategoryPopups } from '@shared/hooks/useCategoryPopups'; -import OptionsMenuPortal from './OptionsMenuPortal'; -import PopupPortal from './PopupPortal'; -import ProfilePopupPortal from '../profilePopup/ProfilePopupPortal'; +import { AutoDismissToast } from '@pinback/design-system/ui'; import { + useGetAcorns, useGetDashboardCategories, - useGetArcons, useGetGoogleProfile, useGetMyProfile, } from '@shared/apis/queries'; -import { useEffect, useRef, useState } from 'react'; -import { AutoDismissToast } from '@pinback/design-system/ui'; import { Balloon } from '@shared/components/balloon/Balloon'; +import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu'; +import { useCategoryPopups } from '@shared/hooks/useCategoryPopups'; +import { useSidebarNav } from '@shared/hooks/useSidebarNav'; +import { rightOf } from '@shared/utils/anchorPosition'; +import Lottie from 'lottie-react'; +import { useEffect, useRef, useState } from 'react'; +import ProfilePopupPortal from '../profilePopup/ProfilePopupPortal'; +import AccordionItem from './AccordionItem'; +import CategoryItem from './CategoryItem'; +import CreateItem from './CreateItem'; import { useCategoryActions } from './hooks/useCategoryActions'; import JobPinGuidePortal from './JobPinGuidePortal'; +import MyLevelItem from './MyLevelItem'; +import OptionsMenuPortal from './OptionsMenuPortal'; +import PopupPortal from './PopupPortal'; +import SideItem from './SideItem'; export function Sidebar() { const [profileOpen, setProfileOpen] = useState(false); @@ -35,7 +35,7 @@ export function Sidebar() { const [guideOpen, setGuideOpen] = useState(false); const { data: categories } = useGetDashboardCategories(); - const { data, isPending: isAcornPending } = useGetArcons(); + const { data, isPending: isAcornPending } = useGetAcorns(); const { data: googleProfileData } = useGetGoogleProfile(); const { data: myProfile } = useGetMyProfile(); From 84ba8035b7d97d3be2c8ff739f622f1d7bfd41e9 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Thu, 26 Feb 2026 18:44:20 +0900 Subject: [PATCH 7/7] =?UTF-8?q?Feat:=20=EB=A6=AC=EB=A7=88=EC=9D=B8?= =?UTF-8?q?=EB=93=9C=20=EC=95=84=ED=8B=B0=ED=81=B4=20=EC=9D=BD=EC=9D=8C=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=ED=9B=84=20=EC=BF=BC=EB=A6=AC=20=EB=AC=B4=ED=9A=A8=ED=99=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/remind/Remind.tsx | 28 +------------------------ apps/client/src/shared/apis/queries.ts | 24 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/apps/client/src/pages/remind/Remind.tsx b/apps/client/src/pages/remind/Remind.tsx index fe0c373a..e14703c5 100644 --- a/apps/client/src/pages/remind/Remind.tsx +++ b/apps/client/src/pages/remind/Remind.tsx @@ -69,20 +69,13 @@ const Remind = () => { containerRef, } = useAnchoredMenu((anchor) => belowOf(anchor, 8)); - /** - * 24시간 유효한 리마인드만 표시 - */ - const articlesToDisplay = data?.pages .flatMap((page) => page.articles) .filter((article) => { const now = new Date().getTime(); - const remindTime = new Date(article.remindAt).getTime(); - const expirationTime = remindTime + 24 * 60 * 60 * 1000; - return now >= remindTime && now < expirationTime; }) ?? []; @@ -95,15 +88,11 @@ const Remind = () => { queryClient.invalidateQueries({ queryKey: ['remindArticles'], }); - queryClient.invalidateQueries({ queryKey: ['acorns'], }); - setIsDeleteOpen(false); - setDeleteTargetId(null); - closeMenu(); }, @@ -178,22 +167,7 @@ const Remind = () => { categoryColor={article.category.categoryColor} onClick={() => { window.open(article.url, '_blank'); - - updateToReadStatus(article.articleId, { - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: ['remindArticles'], - }); - - queryClient.invalidateQueries({ - queryKey: ['acorns'], - }); - }, - - onError: (error) => { - console.error(error); - }, - }); + updateToReadStatus(article.articleId); }} onOptionsClick={(e) => { e.stopPropagation(); diff --git a/apps/client/src/shared/apis/queries.ts b/apps/client/src/shared/apis/queries.ts index aebbde56..47481dfa 100644 --- a/apps/client/src/shared/apis/queries.ts +++ b/apps/client/src/shared/apis/queries.ts @@ -29,6 +29,7 @@ import { useMutation, UseMutationResult, useQuery, + useQueryClient, UseQueryResult, useSuspenseQuery, } from '@tanstack/react-query'; @@ -100,8 +101,31 @@ export const usePutArticleReadStatus = (): UseMutationResult< AxiosError, number > => { + const queryClient = useQueryClient(); + return useMutation({ mutationFn: (articleId: number) => putArticleReadStatus(articleId), + + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: ['remindArticles'], + }); + queryClient.invalidateQueries({ + queryKey: ['acorns'], + }); + queryClient.invalidateQueries({ + queryKey: ['bookmarkReadArticles'], + }); + queryClient.invalidateQueries({ + queryKey: ['bookmarkUnreadArticles'], + }); + queryClient.invalidateQueries({ + queryKey: ['categoryBookmarkArticles'], + }); + }, + onError: (error) => { + console.error('읽음 처리 실패:', error); + }, }); };