Skip to content

Commit b7f6278

Browse files
committed
Feat(client): 리마인드 목록 조회 api 변경에 따른 컴포넌트 수정
1 parent 20debad commit b7f6278

File tree

2 files changed

+85
-91
lines changed

2 files changed

+85
-91
lines changed

apps/client/src/pages/remind/Remind.tsx

Lines changed: 85 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
import { useMemo, useRef, useState, useEffect } from 'react';
1+
import { useGetRemindArticles } from '@pages/remind/apis/queries';
2+
import NoReadArticles from '@pages/remind/components/noReadArticles/NoReadArticles';
3+
import NoUnreadArticles from '@pages/remind/components/noUnreadArticles/NoUnreadArticles';
24
import {
35
Badge,
6+
Card,
47
PopupContainer,
58
trackPageView,
69
} from '@pinback/design-system/ui';
710
import CardEditModal from '@shared/components/cardEditModal/CardEditModal';
811
import OptionsMenuPortal from '@shared/components/sidebar/OptionsMenuPortal';
912
import { useAnchoredMenu } from '@shared/hooks/useAnchoredMenu';
1013
import { belowOf } from '@shared/utils/anchorPosition';
11-
import { REMIND_MOCK_DATA } from './constants';
12-
import { useGetRemindArticles } from '@pages/remind/apis/queries';
1314
import { formatLocalDateTime } from '@shared/utils/formatDateTime';
14-
import NoReadArticles from '@pages/remind/components/noReadArticles/NoReadArticles';
15-
import NoUnreadArticles from '@pages/remind/components/noUnreadArticles/NoUnreadArticles';
15+
import { useEffect, useMemo, useRef, useState } from 'react';
16+
import { REMIND_MOCK_DATA } from './constants';
17+
1618
import {
17-
usePutArticleReadStatus,
1819
useDeleteRemindArticle,
1920
useGetArticleDetail,
21+
usePutArticleReadStatus,
2022
} from '@shared/apis/queries';
21-
import { useQueryClient } from '@tanstack/react-query';
22-
import NoRemindArticles from './components/noRemindArticles/NoRemindArticles';
23-
import FetchCard from './components/fetchCard/FetchCard';
24-
import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll';
23+
import JobSelectionFunnel from '@shared/components/jobSelectionFunnel/JobSelectionFunnel';
2524
import TooltipCard from '@shared/components/tooltipCard/TooltipCard';
25+
import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll';
26+
import { useQueryClient } from '@tanstack/react-query';
2627
import Footer from './components/footer/Footer';
27-
import JobSelectionFunnel from '@shared/components/jobSelectionFunnel/JobSelectionFunnel';
28+
import NoRemindArticles from './components/noRemindArticles/NoRemindArticles';
2829

2930
const Remind = () => {
3031
useEffect(() => {
3132
trackPageView('대시보드 페이지 방문');
3233
}, []);
33-
3434
const [isEditOpen, setIsEditOpen] = useState(false);
3535
const [activeBadge, setActiveBadge] = useState<'read' | 'notRead'>('notRead');
3636
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
@@ -69,13 +69,18 @@ const Remind = () => {
6969
containerRef,
7070
} = useAnchoredMenu((anchor) => belowOf(anchor, 8));
7171

72+
/**
73+
* 24시간 유효한 리마인드만 표시
74+
*/
75+
7276
const articlesToDisplay =
7377
data?.pages
7478
.flatMap((page) => page.articles)
7579
.filter((article) => {
7680
const now = new Date().getTime();
81+
7782
const remindTime = new Date(article.remindAt).getTime();
78-
// 만료 시간 = 리마인드 시간 + 24시간
83+
7984
const expirationTime = remindTime + 24 * 60 * 60 * 1000;
8085

8186
return now >= remindTime && now < expirationTime;
@@ -87,13 +92,21 @@ const Remind = () => {
8792
const handleDeleteArticle = (id: number) => {
8893
deleteArticle(id, {
8994
onSuccess: () => {
90-
queryClient.invalidateQueries({ queryKey: ['remindArticles'] });
91-
queryClient.invalidateQueries({ queryKey: ['arcons'] });
95+
queryClient.invalidateQueries({
96+
queryKey: ['remindArticles'],
97+
});
98+
99+
queryClient.invalidateQueries({
100+
queryKey: ['arcons'],
101+
});
102+
92103
setIsDeleteOpen(false);
104+
93105
setDeleteTargetId(null);
106+
94107
closeMenu();
95-
close();
96108
},
109+
97110
onError: (error) => {
98111
console.error('아티클 삭제 실패:', error);
99112
},
@@ -106,6 +119,7 @@ const Remind = () => {
106119

107120
const EmptyStateComponent = () => {
108121
const firstPageData = data?.pages[0];
122+
109123
if (
110124
firstPageData?.readArticleCount === 0 &&
111125
firstPageData?.unreadArticleCount === 0
@@ -116,67 +130,87 @@ const Remind = () => {
116130
return activeBadge === 'read' ? <NoReadArticles /> : <NoUnreadArticles />;
117131
};
118132

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

124-
// TODO: 임시
125-
// const unreadArticleCount = data?.pages[0]?.unreadArticleCount || 0;
126-
// const readArticleCount = data?.pages[0]?.readArticleCount || 0;
127-
128137
return (
129138
<div className="flex h-screen flex-col pl-[8rem] pr-[5rem] pt-[5.2rem]">
130139
<p className="head3">리마인드</p>
140+
131141
<div className="mt-[3rem] flex gap-[2.4rem]">
132142
<Badge
133143
text="안 읽음"
134-
// countNum={unreadArticleCount}
135144
onClick={() => handleBadgeClick('notRead')}
136145
isActive={activeBadge === 'notRead'}
137146
/>
147+
138148
<Badge
139149
text="읽음"
140-
// countNum={readArticleCount}
141150
onClick={() => handleBadgeClick('read')}
142151
isActive={activeBadge === 'read'}
143152
/>
144153
</div>
154+
145155
<TooltipCard />
146156

147157
{articlesToDisplay.length > 0 ? (
148158
<div
149159
ref={scrollContainerRef}
150160
className="scrollbar-hide mt-[2.6rem] flex flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth"
151161
>
152-
{articlesToDisplay.map((article) => (
153-
<FetchCard
154-
key={article.articleId}
155-
article={article}
156-
onClick={() => {
157-
window.open(article.url, '_blank');
158-
159-
updateToReadStatus(article.articleId, {
160-
onSuccess: () => {
161-
queryClient.invalidateQueries({
162-
queryKey: ['remindArticles'],
163-
});
164-
queryClient.invalidateQueries({
165-
queryKey: ['arcons'],
166-
});
167-
},
168-
onError: (error) => {
169-
console.error(error);
170-
},
171-
});
172-
}}
173-
onOptionsClick={(e) => {
174-
e.stopPropagation();
175-
openMenu(article.articleId, e.currentTarget);
176-
}}
177-
/>
178-
))}
179-
<div ref={observerRef} style={{ height: '1px', width: '100%' }} />
162+
{articlesToDisplay.map((article) => {
163+
const displayTitle = article.title?.trim()
164+
? article.title
165+
: '제목 없음';
166+
167+
const displayImageUrl = article.thumbnailUrl || undefined;
168+
169+
return (
170+
<Card
171+
key={article.articleId}
172+
type="remind"
173+
title={displayTitle}
174+
imageUrl={displayImageUrl}
175+
content={article.memo}
176+
timeRemaining={article.remindAt}
177+
category={article.category.categoryName}
178+
categoryColor={article.category.categoryColor}
179+
onClick={() => {
180+
window.open(article.url, '_blank');
181+
182+
updateToReadStatus(article.articleId, {
183+
onSuccess: () => {
184+
queryClient.invalidateQueries({
185+
queryKey: ['remindArticles'],
186+
});
187+
188+
queryClient.invalidateQueries({
189+
queryKey: ['arcons'],
190+
});
191+
},
192+
193+
onError: (error) => {
194+
console.error(error);
195+
},
196+
});
197+
}}
198+
onOptionsClick={(e) => {
199+
e.stopPropagation();
200+
201+
openMenu(article.articleId, e.currentTarget);
202+
}}
203+
/>
204+
);
205+
})}
206+
207+
<div
208+
ref={observerRef}
209+
style={{
210+
height: '1px',
211+
width: '100%',
212+
}}
213+
/>
180214
</div>
181215
) : (
182216
<EmptyStateComponent />
@@ -251,7 +285,6 @@ const Remind = () => {
251285
<div className="fixed inset-0 z-[2000] flex items-center justify-center bg-black/40 p-4">
252286
<JobSelectionFunnel
253287
onComplete={() => {
254-
// TODO: 관심 직무 핀 API 연동 필요
255288
setShowJobSelectionFunnel(false);
256289
}}
257290
/>

apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)