-
Notifications
You must be signed in to change notification settings - Fork 1
Api(client): 카테고리별 아티클 조회 API 연결 & 아티클 없는 경우 UI 분기 추가 #91
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
f88311e
beeb7da
eba18bd
4e82165
64ab2c4
1a5214d
3dd3f6c
9abeea9
1c6943a
08d37d8
63b8050
633efc1
317454f
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,15 +3,22 @@ import { useState } from 'react'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useGetBookmarkArticles, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useGetBookmarkUnreadArticles, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from './apis/queries'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useGetCategoryBookmarkArticles, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from '@pages/myBookmark/apis/queries'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useSearchParams } from 'react-router-dom'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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 NoArticles from '@pages/myBookmark/components/NoArticles/NoArticles'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Icon } from '@pinback/design-system/icons'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const MyBookmark = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [activeBadge, setActiveBadge] = useState<'all' | 'notRead'>('all'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [searchParams] = useSearchParams(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const category = searchParams.get('category'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const categoryId = searchParams.get('id'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isEditOpen, setIsEditOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -25,83 +32,94 @@ const MyBookmark = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const getBookmarkTitle = (id: number | null) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id == null ? '' : (REMIND_MOCK_DATA.find((d) => d.id === id)?.title ?? ''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: readArticles } = useGetBookmarkArticles(1, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: unreadArticles } = useGetBookmarkUnreadArticles(1, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: articles } = useGetBookmarkArticles(0, 20); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: unreadArticles } = useGetBookmarkUnreadArticles(0, 20); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: categoryArticles } = useGetCategoryBookmarkArticles( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const articlesToDisplay = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeBadge === 'all' ? articles?.articles : unreadArticles?.articles; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 임시 콘솔 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('categoryArticles', categoryArticles); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleBadgeClick = (badgeType: 'all' | 'notRead') => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setActiveBadge(badgeType); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col py-[5.2rem] pl-[8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="head3">나의 북마크</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex h-screen flex-col py-[5.2rem] pl-[8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center gap-[0.4rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center gap-[0.4rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="head3">나의 북마크</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {category && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Icon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name="ic_arrow_down_disable" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width={24} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height={24} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rotate={270} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color="black" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="head3 text-main500">{category || ''}</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="mt-[3rem] flex gap-[2.4rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Badge | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text="전체보기" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| countNum={readArticles?.totalArticle || 0} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| countNum={articles?.totalArticle || 0} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => handleBadgeClick('all')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isActive={activeBadge === 'all'} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Badge | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text="안 읽음" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| countNum={readArticles?.totalUnreadArticle || 0} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| countNum={articles?.totalUnreadArticle || 0} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => handleBadgeClick('notRead')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isActive={activeBadge === 'notRead'} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
71
to
84
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. 뱃지 카운트 소스 잘못 지정 및 카테고리 연동 필요
-<Badge
- text="전체보기"
- countNum={articles?.totalArticle || 0}
+<Badge
+ text="전체보기"
+ countNum={(categoryId ? categoryArticles?.totalArticle : articles?.totalArticle) || 0}
onClick={() => handleBadgeClick('all')}
isActive={activeBadge === 'all')}
/>
<Badge
text="안 읽음"
- countNum={articles?.totalUnreadArticle || 0}
+ countNum={unreadArticles?.totalArticle || 0}
onClick={() => handleBadgeClick('notRead')}
isActive={activeBadge === 'notRead')}
/>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="scrollbar-hide mt-[2.6rem] flex max-w-[104rem] flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* TODO: API 연결 후 수정 */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {activeBadge === 'all' && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readArticles?.articles.map((article) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {articlesToDisplay && articlesToDisplay.length > 0 ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="scrollbar-hide mt-[2.6rem] flex h-screen max-w-[104rem] flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {articlesToDisplay.map((article) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Card | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={article.articleId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="bookmark" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={article.url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={article.memo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // category={article.category.categoryName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date={new Date(article.createdAt).toLocaleDateString('ko-KR')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => {}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOptionsClick={(e) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openMenu(article.articleId, e.currentTarget) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {activeBadge === 'notRead' && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| unreadArticles?.articles.map((article) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Card | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={article.articleId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="bookmark" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={article.url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={article.memo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // category={article.} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category={article.category.categoryName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date={new Date(article.createdAt).toLocaleDateString('ko-KR')} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => {}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOptionsClick={(e) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openMenu(article.articleId, e.currentTarget) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <NoArticles /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OptionsMenuPortal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| open={menu.open} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style={style ?? undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| containerRef={containerRef} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId={menu.categoryId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getCategoryName={getBookmarkTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onEdit={() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsEditOpen(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDelete={(id) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('delete', id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={closeMenu} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OptionsMenuPortal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| open={menu.open} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style={style ?? undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| containerRef={containerRef} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId={menu.categoryId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getCategoryName={getBookmarkTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onEdit={() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsEditOpen(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDelete={(id) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('delete', id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={closeMenu} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isEditOpen && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="fixed inset-0 z-[1000]" aria-modal="true" role="dialog"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -110,7 +128,6 @@ const MyBookmark = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={() => setIsEditOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 flex items-center justify-center p-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* 필요하면 menu.categoryId를 모달에 전달 */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <CardEditModal onClose={() => setIsEditOpen(false)} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,3 +13,14 @@ export const getBookmarkUnreadArticles = async (page: number, size: number) => { | |||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return data.data; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export const getCategoryBookmarkArticles = async ( | ||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId: string | null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| page: number, | ||||||||||||||||||||||||||||||||||||||||||||||||
| size: number | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { data } = await apiRequest.get( | ||||||||||||||||||||||||||||||||||||||||||||||||
| `/api/v1/articles/category?categoryId=${categoryId}&page=${page}&size=${size}` | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return data.data; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+17
to
+26
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. 🛠️ Refactor suggestion null 카테고리 방지 및 쿼리스트링 조합 방식 개선 제안
다음 diff 적용 제안: export const getCategoryBookmarkArticles = async (
categoryId: string | null,
page: number,
size: number
) => {
- const { data } = await apiRequest.get(
- `/api/v1/articles/category?categoryId=${categoryId}&page=${page}&size=${size}`
- );
+ if (!categoryId) {
+ throw new Error('categoryId is required');
+ }
+ const { data } = await apiRequest.get('/api/v1/articles/category', {
+ params: { categoryId, page, size },
+ });
return data.data;
};추가로, 반환 타입을 명확히 하려면 API envelope 타입을 도입하거나 캐스팅을 통해 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents💡 Verification agent 🧩 Analysis chainURL 파라미터 네이밍 일관성 확인 필요 (id vs categoryId) 라우팅에서는 다음 스크립트로 사용처를 빠르게 확인할 수 있습니다: 🏁 Script executed: #!/bin/bash
# id / categoryId 파라미터 사용 현황 점검
rg -n --type ts --type tsx -C2 '\bcreateSearchParams\(|useSearchParams\(|categoryId\b|\bid='Length of output: 27 🏁 Script executed: #!/bin/bash
set -euo pipefail
# TS/TSX 파일에서 createSearchParams, useSearchParams, categoryId, id= 사용 현황 재검색
echo "검색 시작: createSearchParams, useSearchParams, categoryId, id= (ts/tsx/js/jsx)..."
rg -n -C2 -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' '\b(createSearchParams\(|useSearchParams\(|categoryId\b|\bid=)' || true
# 문자열로 포함된 쿼리 파라미터도 확인
echo "검색 추가: 파일 전체에서 '?id=' 포함 여부 확인..."
rg -n -C2 -g '!**/node_modules/**' '\?id=' || trueLength of output: 9237 쿼리 파라미터 키 불일치 — 긴급 수정 필요 라우팅은 id 및 category(name)을 쿼리로 보내는데, MyBookmark는 'category'를 categoryId로 사용하고 API는 'categoryId'를 기대합니다. 이로 인해 올바른 카테고리 ID가 API에 전달되지 않습니다.
|
||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import chippiNoArticles from '@assets/chippi_x.svg'; | ||
| import { Icon } from '@pinback/design-system/icons'; | ||
|
|
||
| const NoArticles = () => { | ||
| return ( | ||
| <div className="mx-auto mt-[14rem] flex flex-col items-center"> | ||
| <img src={chippiNoArticles} alt="No Articles" /> | ||
|
|
||
| <p className="head2 mt-[1.6rem]">첫 북마크가 저장되면 여기에 모여요 ✨</p> | ||
| <div className="mt-[0.8rem] flex items-center"> | ||
| <p className="body1-m text-font-gray-3 gap-[0.4rem]"> | ||
| 원하는 페이지에서 | ||
| </p> | ||
| <div className="flex items-center text-center"> | ||
| <Icon name="ic_extension" width={28} height={28} /> | ||
| <p className="body1-m text-font-gray-3">아이콘을 눌러주세요.</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default NoArticles; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,31 @@ | ||
| interface Category { | ||
| categoryId: number; | ||
| categoryName: string; | ||
| categoryColor: string; | ||
| } | ||
|
|
||
| interface BookmarkArticle { | ||
| articleId: number; | ||
| url: string; | ||
| memo: string; | ||
| createdAt: string; | ||
| isRead: boolean; | ||
| category: Category; | ||
| } | ||
|
|
||
| // 북마크 전체 조회 | ||
| export interface BookmarkArticleResponse { | ||
| totalArticle: number; | ||
| totalUnreadArticle: number; | ||
| isNewUser: boolean; | ||
| articles: BookmarkArticle[]; | ||
| } | ||
|
|
||
| // 북마크 안 읽음 조회 | ||
| export interface UnreadBookmarkArticleResponse { | ||
| totalArticle: number; | ||
| totalUnreadArticle: number; | ||
| articles: BookmarkArticle[]; | ||
| } | ||
|
|
||
| export type CategoryBookmarkArticleResponse = UnreadBookmarkArticleResponse; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,8 +5,10 @@ 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 './apis/queries'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const Remind = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isEditOpen, setIsEditOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -21,7 +23,7 @@ const Remind = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const getItemTitle = (id: number | null) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id == null ? '' : (REMIND_MOCK_DATA.find((d) => d.id === id)?.title ?? ''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [activeBadge, setActiveBadge] = useState('notRead'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [activeBadge, setActiveBadge] = useState<'read' | 'notRead'>('notRead'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
24
to
+26
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. 카테고리명 조회가 목데이터에 의존 — 실제 API 데이터로 교체 필요
적용 예시: - const getItemTitle = (id: number | null) =>
- id == null ? '' : (REMIND_MOCK_DATA.find((d) => d.id === id)?.title ?? '');
+ const getCategoryName = (id: number | null) =>
+ id == null
+ ? ''
+ : data?.articles?.find((a) => a.category.categoryId === id)?.category
+ .categoryName ?? '';추가로, 상단의
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const formattedDate = formatLocalDateTime(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data } = useGetRemindArticles( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -31,10 +33,13 @@ const Remind = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleBadgeClick = (badgeType: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleBadgeClick = (badgeType: 'read' | 'notRead') => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setActiveBadge(badgeType); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const EmptyStateComponent = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeBadge === 'read' ? <NoReadArticles /> : <NoUnreadArticles />; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col py-[5.2rem] pl-[8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="head3">리마인드</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -53,39 +58,43 @@ const Remind = () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="scrollbar-hide mt-[2.6rem] flex max-w-[104rem] flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* TODO: API 연결 후 수정 */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {data?.articles?.map((article) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Card | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={article.articleId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="remind" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={article.url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={article.memo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeRemaining={article.remindAt} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category={article.category.categoryName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOptionsClick={(e) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openMenu(article.category.categoryId, e.currentTarget) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {data?.articles && data.articles.length > 0 ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="scrollbar-hide mt-[2.6rem] flex max-w-[104rem] flex-wrap gap-[1.6rem] overflow-y-auto scroll-smooth"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {data.articles.map((article) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Card | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={article.articleId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="remind" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={article.url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content={article.memo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeRemaining={article.remindAt} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category={article.category.categoryName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...(activeBadge === 'notRead' && { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onOptionsClick: (e) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openMenu(article.category.categoryId, e.currentTarget), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EmptyStateComponent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OptionsMenuPortal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| open={menu.open} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style={style ?? undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| containerRef={containerRef} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId={menu.categoryId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getCategoryName={getItemTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onEdit={() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsEditOpen(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDelete={(id) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('delete', id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={closeMenu} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <OptionsMenuPortal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| open={menu.open} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style={style ?? undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| containerRef={containerRef} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| categoryId={menu.categoryId} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getCategoryName={getItemTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onEdit={() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsEditOpen(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDelete={(id) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('delete', id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| closeMenu(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={closeMenu} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+82
to
+97
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. 🛠️ Refactor suggestion 옵션 메뉴에 실제 카테고리명 전달 + style 전달 단순화 상단 수정에 맞춰 - <OptionsMenuPortal
- open={menu.open}
- style={style ?? undefined}
+ <OptionsMenuPortal
+ open={menu.open}
+ style={style}
containerRef={containerRef}
categoryId={menu.categoryId}
- getCategoryName={getItemTitle}
+ getCategoryName={getCategoryName}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isEditOpen && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="fixed inset-0 z-[1000]" aria-modal="true" role="dialog"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
🛠️ Refactor suggestion
헤더 카테고리 표시 변수 교체
표시용은
categoryName으로 교체해 의미를 명확히 하세요.📝 Committable suggestion
🤖 Prompt for AI Agents