-
Notifications
You must be signed in to change notification settings - Fork 1
Feat(Client): remind aticle list 수정 #284
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
20debad
b7f6278
e9e84a5
27dc685
4f265e6
c70c6f5
cd81fe4
84ba803
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 |
|---|---|---|
| @@ -1,36 +1,36 @@ | ||
| 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'; | ||
| 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); | ||
|
|
@@ -75,9 +75,7 @@ const Remind = () => { | |
| .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 +85,17 @@ const Remind = () => { | |
| const handleDeleteArticle = (id: number) => { | ||
| deleteArticle(id, { | ||
| onSuccess: () => { | ||
| queryClient.invalidateQueries({ queryKey: ['remindArticles'] }); | ||
| queryClient.invalidateQueries({ queryKey: ['arcons'] }); | ||
| queryClient.invalidateQueries({ | ||
| queryKey: ['remindArticles'], | ||
| }); | ||
| queryClient.invalidateQueries({ | ||
| queryKey: ['acorns'], | ||
| }); | ||
| setIsDeleteOpen(false); | ||
| setDeleteTargetId(null); | ||
| closeMenu(); | ||
| close(); | ||
| }, | ||
|
|
||
|
Comment on lines
94
to
98
Member
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. 공백 추가된건 prettier인가요? |
||
| onError: (error) => { | ||
| console.error('아티클 삭제 실패:', error); | ||
| }, | ||
|
|
@@ -106,6 +108,7 @@ const Remind = () => { | |
|
|
||
| const EmptyStateComponent = () => { | ||
| const firstPageData = data?.pages[0]; | ||
|
|
||
| if ( | ||
| firstPageData?.readArticleCount === 0 && | ||
| firstPageData?.unreadArticleCount === 0 | ||
|
|
@@ -116,67 +119,72 @@ const Remind = () => { | |
| return activeBadge === 'read' ? <NoReadArticles /> : <NoUnreadArticles />; | ||
| }; | ||
|
|
||
| // TODO: 로딩 상태 디자인 필요 | ||
| if (isPending) { | ||
| return <div>Loading...</div>; | ||
| } | ||
|
|
||
| // TODO: 임시 | ||
| // const unreadArticleCount = data?.pages[0]?.unreadArticleCount || 0; | ||
| // const readArticleCount = data?.pages[0]?.readArticleCount || 0; | ||
|
|
||
| return ( | ||
| <div className="flex h-screen flex-col pl-[8rem] pr-[5rem] pt-[5.2rem]"> | ||
| <p className="head3">리마인드</p> | ||
|
|
||
| <div className="mt-[3rem] flex gap-[2.4rem]"> | ||
| <Badge | ||
| text="안 읽음" | ||
| // countNum={unreadArticleCount} | ||
| onClick={() => handleBadgeClick('notRead')} | ||
| isActive={activeBadge === 'notRead'} | ||
| /> | ||
|
|
||
| <Badge | ||
| text="읽음" | ||
| // countNum={readArticleCount} | ||
| onClick={() => handleBadgeClick('read')} | ||
| isActive={activeBadge === 'read'} | ||
| /> | ||
| </div> | ||
|
|
||
| <TooltipCard /> | ||
|
|
||
| {articlesToDisplay.length > 0 ? ( | ||
| <div | ||
| ref={scrollContainerRef} | ||
| className="scrollbar-hide mt-[2.6rem] flex flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth" | ||
| > | ||
| {articlesToDisplay.map((article) => ( | ||
| <FetchCard | ||
| key={article.articleId} | ||
| article={article} | ||
| onClick={() => { | ||
| window.open(article.url, '_blank'); | ||
| {articlesToDisplay.map((article) => { | ||
| const displayTitle = article.title?.trim() | ||
| ? article.title | ||
| : '제목 없음'; | ||
|
|
||
| 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); | ||
| }} | ||
| /> | ||
| ))} | ||
| <div ref={observerRef} style={{ height: '1px', width: '100%' }} /> | ||
| const displayImageUrl = article.thumbnailUrl || undefined; | ||
|
Member
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. 이미지 없을때 fallback image 처리해야겠네요!
Collaborator
Author
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. card 컴포넌트에서 이미지 없을시 로고를 띄우고 있는걸로 아는데 따로 또 fallback 처리를 해야할까요? |
||
|
|
||
| return ( | ||
| <Card | ||
| key={article.articleId} | ||
| type="remind" | ||
| title={displayTitle} | ||
| imageUrl={displayImageUrl} | ||
| content={article.memo} | ||
| timeRemaining={article.remindAt} | ||
| category={article.category.categoryName} | ||
| categoryColor={article.category.categoryColor} | ||
| onClick={() => { | ||
| window.open(article.url, '_blank'); | ||
| updateToReadStatus(article.articleId); | ||
| }} | ||
| onOptionsClick={(e) => { | ||
| e.stopPropagation(); | ||
|
|
||
| openMenu(article.articleId, e.currentTarget); | ||
| }} | ||
| /> | ||
| ); | ||
| })} | ||
|
|
||
| <div | ||
| ref={observerRef} | ||
| style={{ | ||
| height: '1px', | ||
| width: '100%', | ||
| }} | ||
| /> | ||
| </div> | ||
| ) : ( | ||
| <EmptyStateComponent /> | ||
|
|
@@ -239,7 +247,7 @@ const Remind = () => { | |
| /> | ||
| <div className="absolute inset-0 flex items-center justify-center p-4"> | ||
| <CardEditModal | ||
| key={articleDetail.id} | ||
| key={articleDetail.articleId} | ||
| onClose={() => setIsEditOpen(false)} | ||
| prevData={articleDetail} | ||
| /> | ||
|
|
@@ -251,7 +259,6 @@ const Remind = () => { | |
| <div className="fixed inset-0 z-[2000] flex items-center justify-center bg-black/40 p-4"> | ||
| <JobSelectionFunnel | ||
| onComplete={() => { | ||
| // TODO: 관심 직무 핀 API 연동 필요 | ||
| setShowJobSelectionFunnel(false); | ||
| }} | ||
| /> | ||
|
|
||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
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.
🧩 Analysis chain
🏁 Script executed:
Repository: Pinback-Team/pinback-client
Length of output: 274
🏁 Script executed:
Repository: Pinback-Team/pinback-client
Length of output: 2574
🏁 Script executed:
Repository: Pinback-Team/pinback-client
Length of output: 787
쿼리 키 'arcons' 오타 수정 필요
'arcons'은'acorns'의 오타입니다. 쿼리 정의(useGetArcons), 반환 타입(AcornsResponse), 실제 함수 호출(getAcorns())은 모두 'acorns'를 사용하고 있어, 쿼리 키도 일관되게 'acorns'로 통일해야 합니다. 현재 다음 5개 위치에서 잘못된 쿼리 키를 사용하고 있습니다:apps/client/src/shared/apis/queries.ts(쿼리 정의)apps/client/src/pages/remind/Remind.tsx(2개 위치)apps/client/src/pages/myBookmark/MyBookmark.tsxapps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx✏️ 쿼리 키 수정 제안
queryClient.invalidateQueries({ - queryKey: ['arcons'], + queryKey: ['acorns'], });📝 Committable suggestion
🤖 Prompt for AI Agents
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.
@constantly-dev넵! 작은 오타지만 쿼리 캐싱에 영향을 줄 수 있어서 5개 위치 모두 수정해주시면 좋을 것 같아요 😊수정이 필요한 위치들:
apps/client/src/shared/apis/queries.ts(쿼리 정의)apps/client/src/pages/remind/Remind.tsx(2곳)apps/client/src/pages/myBookmark/MyBookmark.tsxapps/client/src/pages/myBookmark/components/myBookmarkContent/MyBookmarkContent.tsx🧠 Learnings used