-
Notifications
You must be signed in to change notification settings - Fork 2
Api(extension): 익스텐션 북마크 아티클 저장 API 연결 #107
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
Conversation
Walkthrough이 PR은 익스텐션의 카테고리 및 북마크 저장 기능을 API와 연동하고, React Query 기반의 비동기 데이터 흐름을 도입합니다. 카테고리 목록 및 리마인드 시간 API 호출, 메모 입력, 동적 카테고리 선택, 북마크 저장 및 아티클 등록까지 전반적인 저장 로직이 개선되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant ModalPop
participant API
participant ChromeStorage
participant Background
ModalPop->>API: useGetCategoriesDash()로 카테고리 목록 fetch
ModalPop->>API: useGetRemindTime()로 리마인드 시간 fetch
ModalPop->>ChromeStorage: chrome.storage.local.set(title)
ModalPop->>Background: SAVE_BOOKMARK 메시지 전송
ModalPop->>API: postArticles({ url, categoryId, memo, remindTime })
Possibly related PRsSuggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: .coderabbit.yaml ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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.
Actionable comments posted: 8
🔭 Outside diff range comments (3)
packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx (1)
28-37: 중복된 인터페이스 정의 제거 필요동일한
CategoryDropDownProps인터페이스가 두 번 정의되어 있습니다. 첫 번째 정의를 제거해야 합니다.다음 수정을 적용하세요:
-interface CategoryDropDownProps { - size?: 'large' | 'medium'; - categories: string[]; -} - interface CategoryDropDownProps { size?: 'large' | 'medium'; categories: string[]; onSelect?: (value: string) => void; }apps/extension/src/components/modalPop/ModalPop.tsx (2)
62-96: handleSave 함수 개선 필요여러 개선사항이 필요합니다:
- 하드코딩된 remindTime 값을 동적으로 변경
- 프로덕션 환경을 위해 console.log 제거
- matchId가 null일 경우 처리
- runtime message의 하드코딩된 title 수정
const handleSave = () => { - console.log('📝 메모 내용:', memo); + if (!matchId) { + console.error('카테고리를 선택해주세요'); + return; + } + chrome.storage.local.set({ savedTitle: titleInfo }, () => { - console.log('📦 storage 저장 완료:', titleInfo); }); + chrome.runtime.sendMessage( { type: 'SAVE_BOOKMARK', payload: { url: urlInfo, - title: '저장할 페이지 이름', + title: titleInfo || '제목 없음', }, }, - (response) => { - console.log('✅ 응답 받음:', response); - } + (response) => {} ); + + // formState에서 날짜와 시간을 조합하여 remindTime 생성 + const remindTime = formState.date && formState.time + ? `${formState.date}T${formState.time}:00` + : undefined; + postArticle( { url: urlInfo, categoryId: matchId, memo: memo, - remindTime: '2025-07-10T08:00:00', + remindTime: remindTime, }, { onSuccess: (data) => { - console.log('✅ 저장 성공:', data); - // window.close(); + window.close(); }, onError: (error) => { console.error('❌ 저장 실패:', error); }, } ); };
216-222: 기본 카테고리 삭제 방지 필요"안 읽은 정보" 카테고리는 삭제할 수 없도록 보호해야 합니다.
onDelete={() => { + // 기본 카테고리는 삭제 불가 + if (selectedCategory === '안 읽은 정보') { + alert('기본 카테고리는 삭제할 수 없습니다.'); + return; + } setCategories((prev) => prev.filter((cat) => cat !== selectedCategory) ); setSelectedCategory(''); handlePopupClose(); }}
♻️ Duplicate comments (1)
apps/extension/src/api/apiFetch.ts (1)
22-25: 오류 메시지 수정 필요오류 메시지가 "signup error"로 되어 있지만, 이는 카테고리 생성 기능입니다. 더 적절한 메시지로 변경해야 합니다.
위의 이전 코멘트에서 제안한 수정사항을 참고하세요.
🧹 Nitpick comments (3)
apps/extension/src/api/queries.ts (2)
3-8: React Query 훅에 에러 핸들링과 추가 옵션을 고려해주세요.
useGetCategoriesDash훅이 기본 구현으로 되어 있지만, 더 나은 사용자 경험을 위해 추가적인 옵션들을 고려해볼 수 있습니다.다음과 같은 개선사항을 제안합니다:
export const useGetCategoriesDash = () => { return useQuery({ queryKey: ['categoriesDash'], queryFn: getCategoriesDash, + staleTime: 5 * 60 * 1000, // 5분간 데이터를 신선하게 유지 + cacheTime: 10 * 60 * 1000, // 10분간 캐시 유지 + retry: 2, // 실패 시 2번 재시도 }); };
10-14: useMutation 훅에 성공/실패 콜백 추가를 고려해주세요.
usePostArticles훅에 성공 및 실패 처리 콜백을 추가하면 더 나은 사용자 피드백을 제공할 수 있습니다.다음과 같은 개선사항을 제안합니다:
export const usePostArticles = () => { return useMutation({ mutationFn: postArticles, + onSuccess: (data) => { + console.log('Article saved successfully:', data); + }, + onError: (error) => { + console.error('Failed to save article:', error); + }, }); };또는 컴포넌트 레벨에서 이러한 콜백들을 정의할 수 있도록 옵션을 매개변수로 받는 방식도 고려해볼 수 있습니다.
apps/extension/src/components/modalPop/ModalPop.tsx (1)
117-117: 디버깅용 console.log 제거 필요프로덕션 코드에서는 console.log를 제거해야 합니다.
setSelectedCategory(value); - console.log(value); setCategoryPopupMode('');
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (17)
apps/client/index.html(0 hunks)apps/extension/package.json(1 hunks)apps/extension/src/App.tsx(1 hunks)apps/extension/src/api/apiFetch.ts(1 hunks)apps/extension/src/api/axios.ts(1 hunks)apps/extension/src/api/axiosInstance.ts(2 hunks)apps/extension/src/api/index.ts(1 hunks)apps/extension/src/api/queries.ts(1 hunks)apps/extension/src/background.ts(2 hunks)apps/extension/src/components/modalPop/ModalPop.tsx(6 hunks)apps/extension/src/popup.tsx(1 hunks)apps/extension/src/utils/index.ts(1 hunks)apps/extension/src/utils/queryClient.ts(1 hunks)apps/extension/vite.config.ts(1 hunks)packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx(2 hunks)packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx(1 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (1)
- apps/client/index.html
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.720Z
Learning: In apps/client/src/shared/components/ui/modalPop/ModalPop.tsx, the InfoBox component uses hardcoded values for title, location, and icon URL as temporary test data. These should be replaced with dynamic data from props when implementing actual functionality and should be marked with TODO comments for future changes.
apps/extension/vite.config.ts (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the @import "tailwindcss"; syntax is the new recommended approach that replaces the three separate @tailwind directives (@tailwind base;, @tailwind components;, @tailwind utilities;). This is used with the @tailwindcss/vite plugin.
apps/extension/src/popup.tsx (2)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.720Z
Learning: In apps/client/src/shared/components/ui/modalPop/ModalPop.tsx, the InfoBox component uses hardcoded values for title, location, and icon URL as temporary test data. These should be replaced with dynamic data from props when implementing actual functionality and should be marked with TODO comments for future changes.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/App.tsx:10-21
Timestamp: 2025-07-08T11:47:10.642Z
Learning: In apps/extension/src/App.tsx, the InfoBox component currently uses a hardcoded external URL for the icon prop as a temporary static placeholder. The plan is to replace this with dynamic favicon extraction from bookmarked websites in future iterations.
apps/extension/src/App.tsx (2)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/App.tsx:10-21
Timestamp: 2025-07-08T11:47:10.642Z
Learning: In apps/extension/src/App.tsx, the InfoBox component currently uses a hardcoded external URL for the icon prop as a temporary static placeholder. The plan is to replace this with dynamic favicon extraction from bookmarked websites in future iterations.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.720Z
Learning: In apps/client/src/shared/components/ui/modalPop/ModalPop.tsx, the InfoBox component uses hardcoded values for title, location, and icon URL as temporary test data. These should be replaced with dynamic data from props when implementing actual functionality and should be marked with TODO comments for future changes.
apps/extension/src/api/queries.ts (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
apps/extension/src/background.ts (2)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/App.tsx:10-21
Timestamp: 2025-07-08T11:47:10.642Z
Learning: In apps/extension/src/App.tsx, the InfoBox component currently uses a hardcoded external URL for the icon prop as a temporary static placeholder. The plan is to replace this with dynamic favicon extraction from bookmarked websites in future iterations.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
apps/extension/src/api/apiFetch.ts (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx (2)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/components/InfoBox/InfoBox.tsx:10-11
Timestamp: 2025-07-08T11:47:27.279Z
Learning: In React TypeScript components, prefer semantic prop names with union types over abstract version numbers. For example, use `size: 'small' | 'large'` instead of `version: 1 | 2` for better code readability, type safety, and extensibility.
apps/extension/src/api/axios.ts (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
apps/extension/src/api/axiosInstance.ts (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/App.tsx:10-21
Timestamp: 2025-07-08T11:47:10.642Z
Learning: In apps/extension/src/App.tsx, the InfoBox component currently uses a hardcoded external URL for the icon prop as a temporary static placeholder. The plan is to replace this with dynamic favicon extraction from bookmarked websites in future iterations.
tsconfig.json (1)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/components/InfoBox/InfoBox.tsx:10-11
Timestamp: 2025-07-08T11:47:27.279Z
Learning: In React TypeScript components, prefer semantic prop names with union types over abstract version numbers. For example, use `size: 'small' | 'large'` instead of `version: 1 | 2` for better code readability, type safety, and extensibility.
apps/extension/package.json (2)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the @import "tailwindcss"; syntax is the new recommended approach that replaces the three separate @tailwind directives (@tailwind base;, @tailwind components;, @tailwind utilities;). This is used with the @tailwindcss/vite plugin.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#10
File: apps/landing/src/index.css:1-1
Timestamp: 2025-07-04T10:12:01.690Z
Learning: In TailwindCSS v4, the @import "tailwindcss"; syntax is the new recommended approach that replaces the three separate @tailwind directives (@tailwind base;, @tailwind components;, @tailwind utilities;). This single import pulls in all of Tailwind's preflight, components, and utilities in one step and is used with the @tailwindcss/vite plugin.
apps/extension/src/components/modalPop/ModalPop.tsx (3)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.720Z
Learning: In apps/client/src/shared/components/ui/modalPop/ModalPop.tsx, the InfoBox component uses hardcoded values for title, location, and icon URL as temporary test data. These should be replaced with dynamic data from props when implementing actual functionality and should be marked with TODO comments for future changes.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/components/InfoBox/InfoBox.tsx:10-11
Timestamp: 2025-07-08T11:47:27.279Z
Learning: In React TypeScript components, prefer semantic prop names with union types over abstract version numbers. For example, use `size: 'small' | 'large'` instead of `version: 1 | 2` for better code readability, type safety, and extensibility.
🧬 Code Graph Analysis (1)
apps/extension/src/components/modalPop/ModalPop.tsx (1)
apps/extension/src/api/queries.ts (2)
usePostArticles(10-14)useGetCategoriesDash(3-8)
🪛 Gitleaks (8.27.2)
apps/extension/src/api/axiosInstance.ts
30-30: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.
(jwt)
🔇 Additional comments (19)
apps/extension/src/utils/queryClient.ts (1)
3-11: React Query 클라이언트 구성이 적절합니다.익스텐션 환경에 맞는 설정입니다:
retry: false: 익스텐션에서 자동 재시도는 일반적으로 불필요refetchOnWindowFocus: false: 익스텐션의 포커스 동작과 웹 애플리케이션이 다르므로 적절throwOnError: true: 명시적인 에러 핸들링을 위해 좋은 선택apps/extension/vite.config.ts (1)
44-44: API 별칭 경로 업데이트가 적절합니다.새로운 API 폴더 구조(
src/api)에 맞춰 별칭 경로를 올바르게 수정했습니다.packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx (1)
162-162: 팝업 오버레이 스타일링 개선이 적절합니다.
fixed에서absolute포지셔닝으로 변경하고 반투명 배경(bg-[#00000063])을 추가한 것은 팝업의 시각적 레이어링을 개선하는 좋은 변경사항입니다.apps/extension/package.json (2)
18-18: React Query 의존성 추가가 적절합니다.새로운 API 통합을 위해
@tanstack/react-query를 추가하는 것은 PR 목표와 일치합니다.
23-23: ‘i’ 패키지 사용 여부 최종 확인 필요
코드베이스 전체에서i패키지에 대한 import/require 검색 결과 사용 흔적이 발견되지 않았습니다. 불필요하다면 의존성에서 제거하는 것을 권장드립니다.
- 파일: apps/extension/package.json
위치: 23번 줄 ("i": "^0.3.7")최종적으로 수동 확인 후 제거 여부를 결정해주세요.
apps/extension/src/utils/index.ts (1)
1-1: queryClient 재수출이 적절합니다.깔끔한 barrel export 패턴으로 queryClient에 대한 중앙집중식 접근을 제공합니다.
apps/extension/src/api/index.ts (1)
1-1: API 인스턴스 명명 및 중앙화가 잘 구현되었습니다.
axiosInstance를apiRequest로 재명명하여 더 명확한 의미를 제공하고, API 관련 코드의 중앙화된 접근점을 제공하는 좋은 구조입니다.packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx (4)
1-1: 적절한 import 추가useEffect가 새로운 기능을 위해 올바르게 추가되었습니다.
45-45: 상태 초기화 개선
selectedCategory를 빈 문자열로 초기화하고 useEffect에서 설정하는 방식이 더 명확하고 안전합니다.
47-51: 동적 카테고리 선택 처리 개선useEffect를 사용하여 카테고리가 변경될 때 첫 번째 카테고리를 선택하는 로직이 잘 구현되었습니다.
학습된 내용에 따르면 "안 읽은 정보" 카테고리가 기본 카테고리로 사용되어야 합니다. 이 컴포넌트가 해당 요구사항을 충족하는지 확인해 주세요.
56-56: 콜백 호출 활성화
onSelect콜백이 활성화되어 부모 컴포넌트가 카테고리 선택 변경에 대응할 수 있습니다. 이는 동적 카테고리 관리에 필수적인 기능입니다.apps/extension/src/api/axios.ts (2)
3-6: 카테고리 대시보드 API 호출 구현 양호간단하고 명확한 GET 요청 구현입니다.
8-16: 아티클 저장 API 호출 구현 양호타입 정의가 적절하고 null 값 처리가 올바르게 구현되어 있습니다.
tsconfig.json (1)
1-26: TypeScript 설정 구성 양호모던한 TypeScript 프로젝트에 적합한 설정으로 구성되어 있습니다:
- ES2020 타겟과 strict 모드 활성화
- 모노레포 구조를 위한 프로젝트 참조 설정
- 번들러 기반 모듈 해석 사용
apps/extension/src/api/axiosInstance.ts (2)
18-21: Chrome 스토리지 API 사용 개선localStorage에서 Chrome storage API로 변경한 것은 확장 프로그램에 적합한 개선사항입니다.
25-25: API 엔드포인트 변경 확인인증이 필요하지 않은 엔드포인트 목록이
/api/v1/auth/signin에서/api/v1/auth/signup으로 변경되었습니다. 이 변경이 의도된 것인지 확인해 주세요.Also applies to: 44-44
apps/extension/src/components/modalPop/ModalPop.tsx (3)
21-25: 인터페이스 정의가 적절합니다!Category 인터페이스가 API 응답 구조와 일치하도록 잘 정의되었습니다.
53-60: 카테고리 ID 매칭 로직이 잘 구현되었습니다!선택된 카테고리 이름으로 ID를 찾는 로직이 안전하게 구현되었습니다.
169-170: 텍스트 영역이 제어 컴포넌트로 적절히 변환되었습니다!memo 상태와 onChange 핸들러가 올바르게 연결되었습니다.
| import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; | ||
|
|
||
| const queryClient = new QueryClient(); |
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
중앙화된 QueryClient 인스턴스 사용을 권장합니다.
AI 요약에 따르면 apps/extension/src/utils/queryClient.ts에서 특정 설정(재시도 비활성화, 윈도우 포커스 시 재가져오기 비활성화 등)이 포함된 중앙화된 queryClient 인스턴스가 있다고 언급되어 있습니다. 일관성과 설정 관리를 위해 해당 인스턴스를 사용하는 것이 좋겠습니다.
다음과 같이 수정하는 것을 제안합니다:
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { QueryClientProvider } from '@tanstack/react-query';
+import { queryClient } from '@utils/queryClient';
-const queryClient = new QueryClient();📝 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.
| import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; | |
| const queryClient = new QueryClient(); | |
| import { QueryClientProvider } from '@tanstack/react-query'; | |
| import { queryClient } from '@utils/queryClient'; |
🤖 Prompt for AI Agents
In apps/extension/src/popup.tsx around lines 6 to 8, instead of creating a new
QueryClient instance locally, import and use the centralized queryClient
instance from apps/extension/src/utils/queryClient.ts that includes specific
configurations like retry and refetch settings. Replace the local QueryClient
creation with an import of the shared queryClient to ensure consistent settings
across the app.
| chrome.bookmarks.create( | ||
| { | ||
| title: localStorage.getItem('titleSave') ?? '핀백 저장소', | ||
| title: '핀백 저장소', |
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
하드코딩된 북마크 제목 사용을 재검토해주세요.
북마크 제목이 고정된 문자열 '핀백 저장소'로 하드코딩되어 있습니다. 이는 사용자 경험을 해칠 수 있으며, 실제 페이지 제목이나 사용자가 설정한 제목을 사용하는 것이 더 적절할 것 같습니다.
메시지 페이로드에서 제목을 받아서 사용하는 것을 제안합니다:
- title: '핀백 저장소',
+ title: title || '핀백 저장소',또는 Chrome 저장소에서 저장된 제목을 가져와서 사용하는 방법도 고려해볼 수 있습니다.
📝 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.
| title: '핀백 저장소', | |
| title: title || '핀백 저장소', |
🤖 Prompt for AI Agents
In apps/extension/src/background.ts at line 31, the bookmark title is hardcoded
as '핀백 저장소', which reduces flexibility and user experience. Modify the code to
dynamically obtain the bookmark title either from the message payload or by
retrieving a stored title from Chrome storage, and use that value instead of the
fixed string.
| chrome.storage.local.set({ titleSave: title }, () => { | ||
| console.log('Title saved to chrome storage'); | ||
| }); |
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
title 상태 업데이트 타이밍 문제를 확인해주세요.
chrome.storage.local.set에서 title 상태 변수를 저장하고 있지만, 이 시점에서 title 상태가 아직 업데이트되지 않았을 수 있습니다. setTitle이 38번째 줄에서 호출되고 바로 41번째 줄에서 title 상태를 사용하고 있는데, React 상태 업데이트는 비동기적으로 처리됩니다.
다음과 같이 수정하는 것을 제안합니다:
setTitle(imageUrl?.title ?? '');
setDescription(imageUrl?.description ?? '');
setImgUrl(imageUrl?.image ?? '');
- chrome.storage.local.set({ titleSave: title }, () => {
+ chrome.storage.local.set({ titleSave: imageUrl?.title ?? '' }, () => {
console.log('Title saved to chrome storage');
});또는 별도의 useEffect를 사용하여 title이 변경될 때 저장하는 방법도 고려해볼 수 있습니다.
📝 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.
| chrome.storage.local.set({ titleSave: title }, () => { | |
| console.log('Title saved to chrome storage'); | |
| }); | |
| setTitle(imageUrl?.title ?? ''); | |
| setDescription(imageUrl?.description ?? ''); | |
| setImgUrl(imageUrl?.image ?? ''); | |
| chrome.storage.local.set({ titleSave: imageUrl?.title ?? '' }, () => { | |
| console.log('Title saved to chrome storage'); | |
| }); |
🤖 Prompt for AI Agents
In apps/extension/src/App.tsx around lines 41 to 43, the issue is that the title
state may not be updated yet when calling chrome.storage.local.set, because
React state updates are asynchronous. To fix this, avoid using the possibly
stale title state immediately after setTitle. Instead, either pass the new title
value directly to chrome.storage.local.set or move the storage call into a
useEffect hook that triggers whenever title changes, ensuring the stored value
is always up to date.
| import { getCategoriesDash, postArticles } from './axios'; | ||
| import { useQuery, useMutation } from '@tanstack/react-query'; | ||
| export const useGetCategoriesDash = () => { | ||
| return useQuery({ | ||
| queryKey: ['categoriesDash'], | ||
| queryFn: getCategoriesDash, | ||
| }); | ||
| }; | ||
|
|
||
| export const usePostArticles = () => { | ||
| return useMutation({ | ||
| mutationFn: postArticles, | ||
| }); | ||
| }; |
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
TypeScript 타입 정의 추가를 권장합니다.
API 응답과 요청에 대한 TypeScript 타입을 정의하면 타입 안정성을 높일 수 있습니다.
다음과 같이 타입을 정의하는 것을 제안합니다:
interface Category {
id: string;
name: string;
// 기타 카테고리 속성들
}
interface PostArticleRequest {
url: string;
categoryId: string;
memo?: string;
remindTime?: string;
}
export const useGetCategoriesDash = (): UseQueryResult<Category[]> => {
return useQuery({
queryKey: ['categoriesDash'],
queryFn: getCategoriesDash,
});
};
export const usePostArticles = (): UseMutationResult<any, Error, PostArticleRequest> => {
return useMutation({
mutationFn: postArticles,
});
};🤖 Prompt for AI Agents
In apps/extension/src/api/queries.ts lines 1 to 14, add TypeScript type
definitions for API request and response data to improve type safety. Define
interfaces for Category and PostArticleRequest reflecting the expected data
structure. Then, update the return types of useGetCategoriesDash and
usePostArticles hooks to UseQueryResult<Category[]> and UseMutationResult<any,
Error, PostArticleRequest> respectively, ensuring the hooks are strongly typed.
apps/extension/src/api/apiFetch.ts
Outdated
| export const makeCategories = async () => { | ||
| try { | ||
| const result = await new Promise<{ jwtToken?: string }>((resolve) => { | ||
| chrome.storage.local.get(['jwtToken'], resolve); | ||
| }); | ||
| const token = result.jwtToken || ''; | ||
|
|
||
| const response = await apiRequest.post( | ||
| '/api/v1/categories', | ||
| { | ||
| categoryName: '만들어질카테고리일까', | ||
| }, | ||
| { | ||
| headers: { | ||
| Authorization: `Bearer ${token}`, | ||
| }, | ||
| } | ||
| ); | ||
| return response; | ||
| } catch (error) { | ||
| console.log('signup error: ' + JSON.stringify(error)); | ||
| throw error; | ||
| } | ||
| }; |
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.
하드코딩된 카테고리 이름 수정 필요
함수에서 카테고리 이름이 하드코딩되어 있습니다. 이는 테스트 목적으로 보이며 실제 구현에서는 매개변수로 받아야 합니다.
다음과 같이 수정하는 것을 제안합니다:
-export const makeCategories = async () => {
+export const makeCategories = async (categoryName: string) => {
try {
const result = await new Promise<{ jwtToken?: string }>((resolve) => {
chrome.storage.local.get(['jwtToken'], resolve);
});
const token = result.jwtToken || '';
const response = await apiRequest.post(
'/api/v1/categories',
{
- categoryName: '만들어질카테고리일까',
+ categoryName,
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response;
} catch (error) {
- console.log('signup error: ' + JSON.stringify(error));
+ console.log('create category error: ' + JSON.stringify(error));
throw error;
}
};📝 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.
| export const makeCategories = async () => { | |
| try { | |
| const result = await new Promise<{ jwtToken?: string }>((resolve) => { | |
| chrome.storage.local.get(['jwtToken'], resolve); | |
| }); | |
| const token = result.jwtToken || ''; | |
| const response = await apiRequest.post( | |
| '/api/v1/categories', | |
| { | |
| categoryName: '만들어질카테고리일까', | |
| }, | |
| { | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| }, | |
| } | |
| ); | |
| return response; | |
| } catch (error) { | |
| console.log('signup error: ' + JSON.stringify(error)); | |
| throw error; | |
| } | |
| }; | |
| export const makeCategories = async (categoryName: string) => { | |
| try { | |
| const result = await new Promise<{ jwtToken?: string }>((resolve) => { | |
| chrome.storage.local.get(['jwtToken'], resolve); | |
| }); | |
| const token = result.jwtToken || ''; | |
| const response = await apiRequest.post( | |
| '/api/v1/categories', | |
| { | |
| categoryName, | |
| }, | |
| { | |
| headers: { | |
| Authorization: `Bearer ${token}`, | |
| }, | |
| } | |
| ); | |
| return response; | |
| } catch (error) { | |
| console.log('create category error: ' + JSON.stringify(error)); | |
| throw error; | |
| } | |
| }; |
🤖 Prompt for AI Agents
In apps/extension/src/api/apiFetch.ts between lines 3 and 26, the function
makeCategories has a hardcoded category name '만들어질카테고리일까'. To fix this, modify
the function to accept a categoryName parameter and use it in the API request
payload instead of the hardcoded string. This will make the function reusable
with different category names.
| let token = | ||
| 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJwaW5iYWNrIiwiaWQiOiJhOTA1NGFjOS03MTg0LTQ3NjktYWY4Mi1jNGViYTg0YzYxYTIiLCJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTc1MjgwMDY1Nn0.hXti-Jlnhg8mRoPl5nB8Vi8UV6HPdZYAtgtpTuqtH39lQWle8T5GlX0ug0nNVUqu5B_Pyzafck7lhfXN6ArHOA'; | ||
|
|
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.
하드코딩된 JWT 토큰 보안 문제
코드에 하드코딩된 JWT 토큰이 포함되어 있습니다. PR 목표에서 언급한 임시 토큰이라고 하더라도 보안상 위험합니다.
다음과 같은 개선이 필요합니다:
- 하드코딩된 토큰을 환경 변수로 이동
- 또는 Chrome storage에서 토큰을 가져오는 로직으로 대체
- let token =
- 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJwaW5iYWNrIiwiaWQiOiJhOTA1NGFjOS03MTg0LTQ3NjktYWY4Mi1jNGViYTg0YzYxYTIiLCJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTc1MjgwMDY1Nn0.hXti-Jlnhg8mRoPl5nB8Vi8UV6HPdZYAtgtpTuqtH39lQWle8T5GlX0ug0nNVUqu5B_Pyzafck7lhfXN6ArHOA';
+ const result = await new Promise<{ jwtToken?: string }>((resolve) => {
+ chrome.storage.local.get(['jwtToken'], resolve);
+ });
+ let token = result.jwtToken || '';📝 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.
| let token = | |
| 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJwaW5iYWNrIiwiaWQiOiJhOTA1NGFjOS03MTg0LTQ3NjktYWY4Mi1jNGViYTg0YzYxYTIiLCJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTc1MjgwMDY1Nn0.hXti-Jlnhg8mRoPl5nB8Vi8UV6HPdZYAtgtpTuqtH39lQWle8T5GlX0ug0nNVUqu5B_Pyzafck7lhfXN6ArHOA'; | |
| const result = await new Promise<{ jwtToken?: string }>((resolve) => { | |
| chrome.storage.local.get(['jwtToken'], resolve); | |
| }); | |
| let token = result.jwtToken || ''; |
🧰 Tools
🪛 Gitleaks (8.27.2)
30-30: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.
(jwt)
🤖 Prompt for AI Agents
In apps/extension/src/api/axiosInstance.ts around lines 29 to 31, the JWT token
is hardcoded, which poses a security risk. Remove the hardcoded token and
instead retrieve the token securely by either reading it from an environment
variable or implementing logic to fetch it from Chrome storage. Update the code
to dynamically obtain the token at runtime rather than embedding it directly in
the source.
| const { data: categoriesData, isLoading, error } = useGetCategoriesDash(); | ||
| useEffect(() => { | ||
| if (categoriesData) { | ||
| const categoryNames: string[] = categoriesData.data.categories.map( | ||
| (item: Category) => item.categoryName | ||
| ); | ||
| setCategories(categoryNames); | ||
| console.log(categoryNames); | ||
| } | ||
| }, [categoriesData]); |
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.
기본 카테고리 "안 읽은 정보" 추가 필요
이전 학습 내용에 따르면, "안 읽은 정보"가 첫 번째 기본 카테고리로 포함되어야 하며 삭제할 수 없어야 합니다. 또한 프로덕션 코드에서는 console.log를 제거해야 합니다.
useEffect(() => {
if (categoriesData) {
const categoryNames: string[] = categoriesData.data.categories.map(
(item: Category) => item.categoryName
);
- setCategories(categoryNames);
- console.log(categoryNames);
+ // "안 읽은 정보"가 없으면 첫 번째로 추가
+ const defaultCategory = '안 읽은 정보';
+ if (!categoryNames.includes(defaultCategory)) {
+ setCategories([defaultCategory, ...categoryNames]);
+ } else {
+ setCategories(categoryNames);
+ }
}
}, [categoriesData]);📝 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.
| const { data: categoriesData, isLoading, error } = useGetCategoriesDash(); | |
| useEffect(() => { | |
| if (categoriesData) { | |
| const categoryNames: string[] = categoriesData.data.categories.map( | |
| (item: Category) => item.categoryName | |
| ); | |
| setCategories(categoryNames); | |
| console.log(categoryNames); | |
| } | |
| }, [categoriesData]); | |
| useEffect(() => { | |
| if (categoriesData) { | |
| const categoryNames: string[] = categoriesData.data.categories.map( | |
| (item: Category) => item.categoryName | |
| ); | |
| // "안 읽은 정보"가 없으면 첫 번째로 추가 | |
| const defaultCategory = '안 읽은 정보'; | |
| if (!categoryNames.includes(defaultCategory)) { | |
| setCategories([defaultCategory, ...categoryNames]); | |
| } else { | |
| setCategories(categoryNames); | |
| } | |
| } | |
| }, [categoriesData]); |
🤖 Prompt for AI Agents
In apps/extension/src/components/modalPop/ModalPop.tsx around lines 37 to 46,
you need to prepend the default category "안 읽은 정보" to the categories list so it
always appears first and cannot be deleted. Also, remove the console.log
statement from the useEffect to clean up production code. Update the
setCategories call to include this default category before the fetched
categories.
| time: '', | ||
| timeError: '', | ||
| }); | ||
| const [categories, setCategories] = useState(['']); |
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.
categories 상태 초기값 수정 필요
빈 문자열이 포함된 배열 ['']로 초기화되어 있습니다. 빈 배열로 초기화해야 합니다.
- const [categories, setCategories] = useState(['']);
+ const [categories, setCategories] = useState<string[]>([]);📝 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.
| const [categories, setCategories] = useState(['']); | |
| const [categories, setCategories] = useState<string[]>([]); |
🤖 Prompt for AI Agents
In apps/extension/src/components/modalPop/ModalPop.tsx at line 33, the
categories state is initialized with an array containing an empty string [''],
which is incorrect. Change the initial state to an empty array [] to properly
represent no categories initially.
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.
Actionable comments posted: 4
♻️ Duplicate comments (1)
apps/extension/src/popup.tsx (1)
6-8: 중앙화된 QueryClient 인스턴스 사용을 권장합니다.AI 요약에 따르면
apps/extension/src/utils/queryClient.ts에서 특정 설정(재시도 비활성화, 윈도우 포커스 시 재가져오기 비활성화 등)이 포함된 중앙화된queryClient인스턴스가 있다고 언급되어 있습니다. 일관성과 설정 관리를 위해 해당 인스턴스를 사용하는 것이 좋겠습니다.
🧹 Nitpick comments (1)
apps/extension/src/api/modalAxios.ts (1)
4-7: 불필요한 빈 객체 매개변수를 제거하세요.GET 요청에서 빈 객체
{}를 두 번째 매개변수로 전달하는 것은 불필요합니다.const { data } = await apiRequest.get( - `/api/v1/users/remind-time?now=${time}`, - {} + `/api/v1/users/remind-time?now=${time}` );
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/extension/src/api/modalAxios.ts(1 hunks)apps/extension/src/api/modalQueries.ts(1 hunks)apps/extension/src/components/modalPop/ModalPop.tsx(6 hunks)apps/extension/src/popup.tsx(1 hunks)packages/design-system/src/lib/fomatToday.ts(1 hunks)packages/design-system/src/lib/index.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/design-system/src/lib/fomatToday.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/extension/src/components/modalPop/ModalPop.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
apps/extension/src/popup.tsx (3)
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.720Z
Learning: In apps/client/src/shared/components/ui/modalPop/ModalPop.tsx, the InfoBox component uses hardcoded values for title, location, and icon URL as temporary test data. These should be replaced with dynamic data from props when implementing actual functionality and should be marked with TODO comments for future changes.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#30
File: apps/extension/src/App.tsx:10-21
Timestamp: 2025-07-08T11:47:10.642Z
Learning: In apps/extension/src/App.tsx, the InfoBox component currently uses a hardcoded external URL for the icon prop as a temporary static placeholder. The plan is to replace this with dynamic favicon extraction from bookmarked websites in future iterations.
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.792Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
🧬 Code Graph Analysis (1)
apps/extension/src/api/modalQueries.ts (1)
apps/extension/src/api/modalAxios.ts (1)
getRemindTime(3-9)
🪛 Biome (1.9.4)
apps/extension/src/api/modalAxios.ts
[error] 3-3: Don't use 'String' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'string' instead
(lint/complexity/noBannedTypes)
| @@ -1 +1,2 @@ | |||
| export { default as fomatToday } from './fomatToday'; | |||
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.
함수명 오타를 수정하세요.
fomatToday는 formatToday의 오타로 보입니다. 실제 함수명과 export명이 일치하지 않으면 개발자들에게 혼란을 줄 수 있습니다.
다음과 같이 수정하세요:
-export { default as fomatToday } from './fomatToday';
+export { default as formatToday } from './fomatToday';또는 모듈 파일명도 함께 수정하는 것을 고려하세요:
-export { default as fomatToday } from './fomatToday';
+export { default as formatToday } from './formatToday';📝 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.
| export { default as fomatToday } from './fomatToday'; | |
| export { default as formatToday } from './fomatToday'; |
🤖 Prompt for AI Agents
In packages/design-system/src/lib/index.ts at line 1, there is a typo in the
exported function name 'fomatToday' which should be corrected to 'formatToday'
to match the actual function name. Update the export statement to use
'formatToday' instead of 'fomatToday'. Additionally, verify if the module file
name './fomatToday' also contains the typo and consider renaming the file to
'./formatToday' to maintain consistency.
| createRoot(rootEl).render( | ||
| <QueryClientProvider client={queryClient}> | ||
| <App /> | ||
| </QueryClientProvider> | ||
| ); |
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.
중복된 렌더링 호출을 제거하세요.
동일한 루트 엘리먼트에 대해 createRoot(rootEl).render()가 두 번 호출되고 있습니다. 이는 예상치 못한 동작을 일으킬 수 있으며, 두 번째 렌더링이 첫 번째를 덮어쓸 수 있습니다.
다음과 같이 중복된 렌더링 호출을 제거하세요:
createRoot(rootEl).render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);
- createRoot(rootEl).render(
- <QueryClientProvider client={queryClient}>
- <App />
- </QueryClientProvider>
- );📝 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.
| createRoot(rootEl).render( | |
| <QueryClientProvider client={queryClient}> | |
| <App /> | |
| </QueryClientProvider> | |
| ); | |
| createRoot(rootEl).render( | |
| <QueryClientProvider client={queryClient}> | |
| <App /> | |
| </QueryClientProvider> | |
| ); |
🤖 Prompt for AI Agents
In apps/extension/src/popup.tsx around lines 16 to 20, there are duplicate calls
to createRoot(rootEl).render() on the same root element, which can cause
unexpected behavior by overwriting the first render. Remove the redundant
createRoot(rootEl).render() call so that the root element is rendered only once
with the QueryClientProvider and App components.
| @@ -0,0 +1,9 @@ | |||
| import apiRequest from './axiosInstance'; | |||
|
|
|||
| export const getRemindTime = async (time: String) => { | |||
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.
원시 타입 'string' 사용을 권장합니다.
타입 일관성을 위해 대문자 String 대신 소문자 string을 사용하세요.
-export const getRemindTime = async (time: String) => {
+export const getRemindTime = async (time: string) => {📝 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.
| export const getRemindTime = async (time: String) => { | |
| export const getRemindTime = async (time: string) => { |
🧰 Tools
🪛 Biome (1.9.4)
[error] 3-3: Don't use 'String' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'string' instead
(lint/complexity/noBannedTypes)
🤖 Prompt for AI Agents
In apps/extension/src/api/modalAxios.ts at line 3, replace the type annotation
from the primitive wrapper type 'String' to the primitive type 'string' for the
'time' parameter in the getRemindTime function to ensure type consistency and
best practices.
| return useQuery({ | ||
| queryKey: ['remindTime'], | ||
| queryFn: () => getRemindTime(time), | ||
| }); |
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
쿼리 키에 시간 매개변수를 포함하세요.
현재 쿼리 키가 ['remindTime']로 정적이어서, time 매개변수가 변경되어도 이전 캐시된 데이터가 반환될 수 있습니다. 적절한 캐싱과 데이터 무효화를 위해 쿼리 키에 time 매개변수를 포함하는 것이 좋습니다.
return useQuery({
- queryKey: ['remindTime'],
+ queryKey: ['remindTime', time],
queryFn: () => getRemindTime(time),
});📝 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.
| return useQuery({ | |
| queryKey: ['remindTime'], | |
| queryFn: () => getRemindTime(time), | |
| }); | |
| return useQuery({ | |
| - queryKey: ['remindTime'], | |
| + queryKey: ['remindTime', time], | |
| queryFn: () => getRemindTime(time), | |
| }); |
🤖 Prompt for AI Agents
In apps/extension/src/api/modalQueries.ts around lines 5 to 8, the query key for
useQuery is static as ['remindTime'], which causes caching issues when the time
parameter changes. To fix this, include the time parameter in the query key
array, such as ['remindTime', time], so that the cache correctly differentiates
queries based on the time argument and returns updated data accordingly.
* setting: create issue template * setting: create PR template * setting: update PR template * setting: create CODEOWNERS for auto reviewer * chore: 불필요한 next apps 삭제 * setting: create landing vite + react project * setting: create client vite + react project * chore: extension 폴더 생성 * setting: turbo.json 파일 설정 * setting: pnpm-workspace.yaml config 폴더 추가 * setting: package manager pnpm으로 강제하도록 설정 * setting: client app tsconfig pinback 공통 패키지로 설정 * setting: eslint 공통 pinback package로 설정 * setting: eslint 공통 pinback package로 설정 * chore: 불필요한 app 관련 파일 정리 * chore: 필요 없는 파일 제거 * chore: 필요 없는 파일 제거 * setting: design-system package 구조 생성 * setting: design-system 예시 코드 추가 * setting: landing app tsconfig pinback 공통 패키지로 설정 * setting: landing package.json client에 sync * chore: 불필요한 파일 제거 * chore: design-system test용 button 컴포넌트 추가 * setting: 증분 빌드 옵션 incremental false로 설정 * chore: html lan ko로 변경 * setting: 코드래빗 설정 파일(.coderabbit.yaml) 추가 * chore: CodeRabbit 리뷰 트리거용 주석 추가 * chore: CodeRabbit 트리거용 주석 제거 * Setting : 절대경로 설정 (#6) * setting : client 절대경로 설정 * setting : landing 절대경로 설정 * Merge pull request #16 from Pinback-Team/docs/#15/update-primitive-readme Docs(project): README ver 1.0 작성 * Update README.md * Setting(project): router 설정 (#14) * Setting : landing 라우터 설정 * Setting : client 라우터 설정 * Setting : 라우터 호출 위치 변경 * Setting(project): tailwind css setup (#10) * Setting : client tailwindcss 설치 * Setting : landing tailwind 설정 * fix : 사소한 수정 * refactor : 안쓰는 코드 제거 * Setting(project): axios query setup (#12) * setting : landing queryClient 설정 * setting : client Tanstack query 설정 * Stting : client Axios 설정 (instance) * Setting : landing Axios 설정 (instance) * refactor : 안쓰는 코드 삭제 * refactor : 안쓰는 코드 정리 * chore: 중복코드 제거 * setting(project): 깃 액션 세팅 및 vercel 배포 (#9) * setting : 깃 액션 세팅 * fix : labeler 파일 위치 수정 * fix : 주석 제거 * setting : 버전 수정 * setting : vercel 세팅 * Setting : 자동 리뷰어 할당 수정 (#22) * setting : 깃 액션 세팅 * fix : labeler 파일 위치 수정 * fix : 주석 제거 * setting : 버전 수정 * setting : vercel 세팅 * fix : 리뷰어 자동할당 본인 제거 * setting : frontend 라벨링 제거 * Setting(design-system): 디자인 시스템 토큰 & icons 설정 (#20) * setting: cn helper function 구현 * setting: .gitignore에 .tsbuildinfo 추가 * setting: cSpell pinback 및 turbo 추가 * setting: css 확장자 파일 tailwindcss로 인식되도록 설정 * setting: setting.json prettier & eslint 설정 추가 * setting: design-system styles token 설정 * setting: prettier/eslint root link * setting: 기본 폴더구조 gitkeep 추가 * chore: font token 오타 수정 * setting: font-family base pretendard 설정 * setting: svg sprite default setting * chore: code rabbit review 반영 * Setting(design-system): shadcn-ui default setting (#25) * setting: shadcn/ui default setting * chore: add pnpm-lock file * refactor: code review 반영 * chore: update pnpm-lock file * setting : 보일러플레이트 연동 * setting : tailwindCss 스타일 적용 * setting : custom.d.ts 타입 구체화 * setting : contents 스크립트 범위 수정 * setting : 폰트 1rem 기준 변경 * setting : extension 확장자 프로그램 초기 세팅 (#28) * setting : 보일러플레이트 연동 * setting : tailwindCss 스타일 적용 * setting : custom.d.ts 타입 구체화 * setting : contents 스크립트 범위 수정 * setting : 폰트 1rem 기준 변경 --------- Co-authored-by: 이재림 <[email protected]> * !HOTFIX(design-system): tailwind ds @source 추가 (#40) * Feature(extension): 토글 스위치 제작 (#39) * feat: 토글 스위치 제작 * chore: 안쓰는 코드 제거 * feat: 사이즈 분기 처리 추가 * feat: 토글 thumb 디테일 수정 * chore: 안쓰는 코드 제거 * feat: 의존성, duration 수정 * chore: design-system 패키지 export utils추가 * chore:안쓰는 코드 제거 * Feature(extension): 텍스트 필드 팝업 구현 (#32) * chore: 파일구조 세팅 * feat: ui 구현 * feat: 업데이트된 폰트 적용 * feat: 오버레이 추가 * feat: 삭제, 수정 팝업 분기처리 추가 * feat: x버튼 아이콘 추가 * chore: 안쓰는 코드 제거 * feat: 오버레이-> 박스 섀도우로 변경 * chore: 안쓰는 코드 제거 * feat: onCancel 옵셔널처리 * Feature(extension): textarea 컴포넌트 구현 (#35) * feat: textarea 구현 * feat: 스크롤바 디자인 커스텀 * chore: 안쓰는 코드 정리 * feat: 상대경로 절대경로로 변경 * feat: 글자수 제한 매직넘버 상수 정의 * feat: 유틸 경로 변경 * chore: 안쓰는 코드 삭제 * chore: 안쓰는 코드 제거 * feat: 유틸 경로 변경 * Feature(extension): 인포 박스 컴포넌트 제작 (#30) * feat : 인포 박스 컴포넌트 제작 * feat : ver->union 타입으로 수정 * fix : package.json 불필요 삭제 * fix : app.tsx 수정 사항 제거 * feat : 분기 옵션 수정 * Feature(design-system): Input 컴포넌트 구현 (#52) * feat: input 공통 컴포넌트 구현 * chore: svg.d.ts 파일 추가 * fix: error icon 오타 수정 * feat: aria-invalid 추가 * fix: design-system 내 절대 경로 추가 & tsconfig react.json으로 수정 * feat: input ref props 설정 * fix: build error 해결 * feat: input helperText error400 color로 변경 * Feature(client) useFunnel custom hook 구현 (#54) * setting: onBoarding 기본 구조 세팅 * chore: 코드 prettier 정리 * feat: useFunnel hook 구현 * fix: build error 해결 * chore: 불필요한 gitkeep 파일 삭제 * chore: tsconfig 경로 설정 수정 * refactor: Funnel 컴포넌트 fallback null 처리 추가 * Feature(design-system): dot-indicator 공통 컴포넌트 구현 (#57) * feat: dot-indicator 구현 * feat: input font token 미적용 이슈로 인한 tailwind 자체 value 사용 * Feature(client): dashboard-components (#43) * refactor: 코드 리뷰 피드백 반영 및 툴팁 간격 조정 - 레벨 데이터 중복 제거 (공통 상수로 분리) - 빈 index.ts 파일들에 실제 export 추가 - SectionTitle variant prop 구현 - Tailwind CSS 동적 클래스명 문제 해결 - 정보 아이콘과 툴팁 간격 8px로 조정 - 빌드 테스트 성공 * refactor: 대시보드 컴포넌트 리팩토링 및 코드 중복 제거 * fix: CodeRabbit 리뷰 피드백 반영 - useDashboard 훅 useCallback 의존성 배열 최적화 - AllViewButtonProps에서 사용하지 않는 children prop 제거 - styleUtils.ts CARD_CLASSES 중복 선언 문제 해결 - SectionTitle 컴포넌트 성능 최적화 및 CSS 클래스 일관성 개선 - React.memo 적용으로 불필요한 재렌더링 방지 - BookmarkCategory 컴포넌트 스타일 개선 * fix: CodeRabbit 리뷰 피드백 반영 * fix: CodeRabbit 리뷰 피드백 최종 반영 - 텍스트 색상 일관성 개선 (text-gray700 → text-gray800) - React import 추가로 타입 오류 해결 - BookmarkCategory 완전 리팩토링 (styleUtils 함수 적용) - 카테고리 스타일 유틸리티 함수 확장 - 인라인 스타일 제거로 코드 일관성 향상 * style: 코드 주석 제거 및 정리 * chore: .cursorrules를 gitignore에 추가 * fix: Git 추적에서 .cursorrules 파일 제거 * refactor: React.FC 제거 및 성능 최적화, 주석 정리 * fix: tailwindcss 중복 import 제거 * refactor: BookmarkSection 절대경로 적용 및 타입 정리 * refactor: Category 타입 분리 및 타입 시스템 개선 * refactor: Tooltip children prop required로 변경 및 사용처 수정 * refactor: 절대경로(@routes) 추가 및 관련 import 정리 * refactor: 절대경로 import 일괄 적용 및 경로 오류 수정 * refactor: 상대경로를 절대경로로 변경하고 React import 최적화 * feat: cva 라이브러리를 사용하여 variant 처리 개선 * refactor: tooltip 메시지를 constants 폴더로 분리 * refactor: Tooltip 컴포넌트의 CSS 변수를 Tailwind 클래스로 변경 * refactor: ThumbnailProps의 alt를 optional로 변경 * refactor: Thumbnail 컴포넌트에 cn 유틸리티 적용 * refactor: Props 타입을 컴포넌트 바로 위에 정의하는 컨벤션 적용 * refactor: DailyReminderCard 헤더 레이아웃을 absolute에서 flexbox로 개선 * refactor: 대시보드 컴포넌트 구조 정리 - features/dashboard 폴더를 pages/dashboard/components로 이동 * refactor: features 폴더 구조 개선 - dashboard 하위 폴더 제거 * refactor: CVA 라이브러리 적용으로 컴포넌트 스타일링 개선 * refactor: 인라인 스타일을 CVA로 변경 - 고정된 maxWidth 값 처리 * chore: 사용하지 않는 LAYOUT import 제거 (ts 경고 해결) * style: 리마인드 카드 패딩 및 스타일링 개선 * style: 카드 테두리 색상을 border-gray-200으로 통일 * style: 리마인드 카드 메모 텍스트 스타일 통일 및 디자인 토큰 적용 * refactor: 컴포넌트 구조 개선 및 디자인 시스템 통합 * test: 북마크 카드 테스트 케이스 추가 및 타이틀 스타일 개선 * Feature(client): onBoarding carousel및 story step 컴포넌트 구현 (#60) * feat: 온보딩 캐러셀 구현 * feat: funnel story step 구현 * feat: onBoarding funnel 구조 세팅 및 story step 추가 * refactor: story content 상수 분리 * refactor: story constants key에서 title로 변경 * refactor: STEP 상수 constants 폴더로 분리 * refactor: useFunnel initial step props 받도록 변경 * refactor: onboarding image alt 및 aria-label 추가 * refactor: story image depth onBoarding 추가하도록 변경 * Feature(extension): 카테고리 드롭다운 컴포넌트 구현 (#36) * feat : 드롭다운 퍼블리싱 * feat : hover 적용 처리 * feat : 아이콘 적용 * feat: 아이콘 적용 및 드롭다운 수정 * fix : 폰트 적용 수정 * feat : 클릭 후 텍스트 반영 * feat : 예시 카테고리 추가 * feat : 배열 유효성 체크 및 인덱스 고유값 * feat : 토글 아이콘 교체 * feat : medium,large 분기 처리 * feat : 다운 아이콘 추가 * feat : 아이콘 애니메이션 제거 * fix : app.tsx 수정사항 머지 충돌 해결 * feat : 아이콘 파일 수정 및 정상 적용 * feat: 아이콘 애니메이션 적용 * fix : app.tsx 상태 리버트 * fix : 아이콘 중복 이미지 삭제 및 수정 * fix: package.json 중복 제거 * feat : medium width 값 수정 * fix : console 제거 * fix : 변수 명칭 구체화 수정 * Feature(extension): 데이트 피커 컴포넌트 (#59) * feat : 인풋 컴포넌트 퍼블리싱 * feat : 공통화 후 분기 로직 분리 * feat : 시간 및 날짜 포맷팅 로직 * feat : 유효성 검사 * feat : 백스페이스 시 포맷팅 제거 * feat : 시간 유효성 추가 * feat : 수정 * refactor : 타입 파일 분리 * refactor : utils 파일로 리팩토링 * fix : app.tsx 초기 상태로 돌리기 * fix: 디자인시스템 package.json 모듈 타입 지정 * fix: 인터페이스 선언 위치 수정 * feat : constants로 상수 분리 * feat : constants 경로 지정 * Refactor(client): 파일 구조 변경 및 디자인 통일 (#65) * refactor: 대시보드 전용 컴포넌트 pages/dashboard/components로 이동 및 구조 정리 - Thumbnail, LevelInfoModal, Tooltip 대시보드 전용 폴더로 이동 - 관련 import 경로 일괄 수정 - shared/ui에서 export 및 파일 제거 - 구조 명확화로 유지보수성 향상 * refactor: 파일 구조 및 스타일 수정 * refactor: 상대경로를 절대경로로 변경하여 코드 가독성 향상 * Feat(client): SVG 파일 경로 수정 및 EmptyState 텍스트 색상 변경 * chore: public 폴더 재생성 및 vite.svg 복구 * refactor: 경로 변경 * Feature(design-systems): 공통 버튼 컴포넌트 (#63) * feat: 버튼 틀 공컴 연결 * Revert "feat: 버튼 틀 공컴 연결" This reverts commit 386d30c. * feat : 공통 버튼 공컴화 제작 * fix: 디자인 시스템 아이콘 상대경로로 수정 * feat : 사이즈에 따른 버튼 분기 cva * feat : 색상 분기 * feat : props 옵셔널 정의 제거 * feat : app.tsx 기본 형태로 돌리기 * [Refactor] 팝업 관련 컴포넌트 packages 공컴으로 마이그레이션 작업 (#68) * feat: 파일들 마이그레이션 * feat : index.ts 재정의 * fix: app.tsx 초기 상태로 수정 * Feature(extension): fcm token 발급 (#71) * feat: 파이어베이스 설치, 파일세팅 * feat: 환경변수 설정 * feat: env jason 설정 * feat: settingFCM 임포트 * feat: 수정중 * Revert "feat: 수정중" This reverts commit d123699. * feat: 필요한 파일 추가, .js->.ts 변경과 설정 변경 * feat: FCM SDK로 토큰 생성 성공 * feat: 환경변수 설정 * fix: 충돌 해결 * fix: build error fix * !HOTFIX: secret working * Feature(client): dashboard card view 구현 (#72) * feat: 북마크 카드 세션 구현 - 카테고리 필터링 기능 (BookmarkCategory) - 총 카드 개수 표시 (BookmarkCount) - 카드 그리드 4열 고정 - EmptyState 표시 - 전체보기 버튼 조건부 렌더링 (12개 이상) * feat: 데일리 리마인드 카드 세션 구현 - 타이머 기능 포함 (Timer 컴포넌트) - 카드 그리드 4열 고정 - 전체보기 버튼 조건부 렌더링 (12개 이상) - 토글 기능으로 확장/축소 가능 - 도토리 스탬프 표시 기능 * feat: 대시보드 레이아웃 및 스타일링 구현 - 최대 너비 1440px, 양쪽 패딩 설정 - 헤더 fixed 포지션, 높이 6rem - 세션 간 간격 140px, 카드 그리드 4열 고정 - 하단 패딩 36px 추가 * feat: 대시보드 데이터 및 훅 구현 - 북마크 카드 목데이터 추가 (카테고리, 읽음 상태 포함) - useDashboard 훅에서 불필요한 import 제거 - 카테고리 필터링 및 전체보기 기능 지원 * feat: API 및 타입 정의 추가 - timerApi 함수 추가 - EmptyStatePresets 업데이트 - API 타입 정의 추가 * fix: 린트 에러 수정 및 포맷팅 적용 * fix: BookmarkCardProps의 categoryId를 필수 속성으로 변경 * fix: 코드래빗 AI 봇 피드백 반영 - 안 읽은 정보 카테고리 count 값 수정 (3 → 4) - API limit 값 일관성 수정 (9 → 12) - 인터페이스 일관성 개선 (BaseCard 공통 인터페이스 추가) - 디자인 시스템 단위 일관성 수정 (px → rem) * feat: 북마크 카드 mock 데이터 주석 해제 및 대시보드 카테고리/EmptyState 로직 개선 * refactor: 카테고리 자동 생성 로직 함수화 및 불필요한 주석 제거 * fix: lint/prettier 에러 수정 및 코드 스타일 통일 * refactor: px 단위를 rem으로 통일하여 접근성 및 일관성 개선 * refactor: 중첩 삼항 연산자를 early return 패턴으로 개선하여 가독성 향상 * refactor: 조건에 의미있는 네이밍 추가 및 some 메서드 활용으로 가독성 및 성능 개선 * style: prettier 포맷팅 및 린트 자동 수정 * refactor: setIsExpanded 토글 시 prev 패턴 적용으로 상태 변경 안전성 향상 * Feature(client): onboarding time select step 컴포넌트 구현 (#73) * feat: timeSelect Step 기본 퍼블리싱 구현 * refactor: 버튼 역할 div button 태그로 변경 * feat: onBoarding header 연결 * feat: 리마인드 시간 아침/저녁 선택 로직 구현 * feat: max notice step & welcome step Funnel에 추가 * feat: useFunnel funnel내에서 boolean 분기처리 되도록 변경 * feat: mac window 구분용 useOSDetector 구현 * feat: 사용자 설정 dropdown open 로직 구현 * feat: header fixed로 변경 * Feature(extension): 익스텐션 팝업 컴포넌트 및 뷰 (#75) * fix: build 에러 상대 경로 수정 * feat : 익스텐션 medium 팝업 퍼블리싱 * feat: TimePicker에 사이즈 분기 처리 * feat: 팝업 레이아웃 수정 * feat: 팝업 헤더 분리 컴포넌트 연결 * feat: 토글 시 absolutea 처리 * feat: textarea 폰트 적용 및 placeholder * feat: 얼럿 메시지 -> 빨간 텍스트로 노출 * feat: 크롬 확장프로그램 디폴트 화면 세팅 * fix: 불필요 props 선언 제거 * feat: constants 상수 분리 * fix: firebase관련 세팅 삭제 * feat: 크롬 익스텐션 창 닫기 * feat: arial-label 추가 * feat: 아이콘 빌드파일 * Feature(client): onboarding mac notice & welcome step 컴포넌트 구현 (#77) * feat: mac notice step 구현 * feat: onboarding welcome step 컴포넌트 구현 * feat: main logo 수정 * chore: mac 분기처리 주석 제거 * refactor: img aria-label 중복 제거 * Feature(client): 대시보드용 팝업 컴포넌트 작업 및 플로우 연결 (#80) * feat: 대시보드 팝업 컴포넌트 퍼블리싱 * feat: 대시보드 팝업 토글 제어 props 연결 * feat: 카드 더보기 버튼 클릭 시, 팝업 핸들링 * feat: 모달 속 버튼 클릭시 닫기 제어 * feat: 북마크 카드 쪽 팝업닫기 제어 * feat: 북마크 카드 props 타입 통일 * feat: 팝업 바깥영역 클릭시 닫기 제어 * fix: 하드코딩 구간 표시 * fix: props에 옵셔널 조건 통일 * feat: 불필요 에러 메시지 함수 제거 및 팝업 상수 정의 * Setting(client): api 세팅 및 초기 토큰 발급 작업 (#88) * feat: api 연결 세팅 및 토큰 재발급 플로우 * fix: 콘솔 제거 * feat: 익스텐션 쪽 api 연결 확인 * feat: client api 세팅 주석 * Feature(client): design FCM token management & messaging architecture (#90) * feat: service worker register function 구현 * feat: background firebase messaging logic 구현 * setting: firebase sdk default setting * feat: FCM token 발급 test function 구현 * feat: extension google email get method 연결 * feat: 자동화 스크립트 추가 및 코드 품질 개선 - package.json에 format, lint:fix, fix-all, check-all 스크립트 추가 - 린트 및 포맷팅 자동 수정 기능 구현 - ModalPop 컴포넌트에서 불필요한 setErrorMessage prop 제거 - 코드 품질 개선 및 설정 파일 업데이트 * Feature(client): 대시보드 배너 구현 및 개발 워크플로우 개선 (#84) * feat: 대시보드 배너 및 타이머 기능 임시 저장 * feat: 배너 컴포넌트 및 관련 리소스 추가 * refactor: 배너 컴포넌트 분리 및 모달 위치 개선 * refactor: 배너 컴포넌트 UI 개선 및 중앙 정렬 적용 * feat: 카드 컴포넌트 UI 개선 - 썸네일 크기 통일 및 제목 말줄임 처리 * refactor: 배너 컴포넌트 코드 품질 개선 및 기능 최적화 * refactor: 배너 컴포넌트 폴더 구조 개선 및 코드 품질 향상 * fix: 리마인드 카드 썸네일 배경색 추가로 중앙 정렬 개선 * refactor: 배너 관련 파일 폴더 구조 개선 * cleanup: 중복 파일 제거 및 폴더 구조 정리 * fix: 썸네일 없을 때 배경 박스 제거 및 메모 텍스트 3줄 제한 강화 * fix: 린트 오류 해결 * fix: BannerHeadline 컴포넌트 수정 * fix: 헤더 로고 직접 import 방식으로 변경 및 스타일 수정 * refactor: 코드 품질 개선 및 최적화 - MAX_ACORN_COUNT 상수 추가로 마지막 단계 기준값 재사용 가능 - Timer 로직을 useTimer custom hook으로 분리 - 타입 추론 활용으로 제네릭 타입 제거 - API 응답에서 구조 분해 할당 사용 - 충돌하는 max-height 스타일 수정 - 조건부 스타일링 개선 * fix: TimePicker 컴포넌트에서 불필요한 setErrorMessage prop 제거 * chore: prettier 및 린트 포맷팅 반영 * Feature(client): 온보딩 ui 퍼블리싱 (#89) * feat: 다이얼 ui 구현 * feat: border 커스텀 * feat: ui 커스텀 * feat: ui 완성 * feat: 사용자 설정 시간 저장 * chore: 안쓰는 코드 삭제 * feat: 온보딩 사용자 설정 추가 * fix : 버블링 해결 * feat: 시간 선택 포맷 개선 및 팝업 토글 함수 수정 * feat: 사용자 설정 시간 선택 기능 개선 및 팝업 상태 반영 * feat: 팝업 외부 클릭 감지 기능 추가 및 사용자 설정 시간 선택 UI 개선 * feat: 온보딩 레이아웃 정렬, 프리셋 시간 선택 기능 개선 * feat: 버튼 컴포넌트 제작 * feat: 온보딩 단계에서 네비게이션 버튼 컴포넌트 추가 및 시간 선택 버튼 개선 * feat: 사용자 설정 시간 선택 UX 수정 * feat: 시간 선택 기능 개선 및 포맷 유틸리티 추가+ 버튼 레이아웃 * feat: 팝업 z인덱스 * fix: ts env 추적 못하는 문제 해결 * chore: 필요 없는 함수 주석 처리 * refactor: color 하드 코딩된 값 수정 * chore: props type interface로 변경 * feat: mac user button 분기 처리 & 토큰 발급 로직 수정 * chore: prettier 정리.. * Setting(extension): 익스텐션 쪽 API 세팅 및 client랑 데이터 연결 작업 (#93) * feat: api 연결 세팅 및 토큰 재발급 플로우 * fix: 콘솔 제거 * feat: 익스텐션 쪽 api 연결 확인 * feat: client api 세팅 주석 * feat: client->extension 토큰 전달 로직 * refactor: utils함수로 분리 * feat: 이메일 fetch 및 랜딩 연결 * fix: 콘솔 및 주석 제거 * Feature(extension): 북마크 저장 및 API 연결 작업 (#87) * setting: 익스텐션 세팅 수정 * feat: 북마크 저장 로직 구현 연습 * feat: url에 따른 썸네일 추적 * feat: 북마크 저장 기능 구현 * feat: 북마크 저장 시 창 닫기 * feat: 이미지 연결 * feat: 북마크 정보 팝업에 연동 * feat: 텍스트 포맷 및 이미지 연동 * feat: 북마크 제대로 저장 수정 * fix: 주석 제거 * feat: 텍스트 없으면 익스텐션 실행 끄기 * fix: 콘솔 제거 * feat: 크롬 도메인일 경우에는 꺼지지 않게 제어 * feat: api 테스트 코드 제거 * fix: 대시보드 누락 사항 복구 * fix: 데이터 누락 추가 * Api(client): 회원 가입 api 연결 (#97) * chore: signup 오타 수정 * feat: signup axios fetch 함수 구현 * feat: signup query 함수 구현 * api: signup api 연결 * feat: signup query onSuccess token localStorage 추가 로직 구현 * feat: next button step 변하는 로직 onSuccess로 이동 * feat: signup success시 localStorage 저장 및 send extension 로직 추가 * Feature(extension): modalpop의 카테고리 드롭다운에 popup 연결 (#102) * feat: 버튼 공통 컴포넌트 연결 * feat: input 아이콘 컬러 변경 * feat: 버튼 비활성화 * feat: 추가하기 팝업 연결 * feat: 카테고리 수정하기 팝업 연결 * chore: 안쓰는 코드 삭제 * feat: 이벤트 전파방지 코드 * chore: 안쓰는 코드 제거 * Api(client): 대시보드 api 연결 (#101) * feat: 대시보드 API 연동 # Conflicts: # apps/client/src/pages/dashboard/dashboard.tsx # apps/client/src/pages/onBoarding/OnBoarding.tsx * refactor: api 타입 분리 및 import 경로 일괄 수정 # Conflicts: # apps/client/src/pages/dashboard/dashboard.tsx * fix: 이메일 하드코딩 환경변수 처리 및 fallback 적용 # Conflicts: # apps/client/src/pages/dashboard/dashboard.tsx * fix: 썸네일 캐싱 및 에러 처리 개선, 환경변수 적용 * refactor: 썸네일 API를 대시보드 전용 폴더로 이동 및 구조 정리 * refactor: 대시보드 코드 정리 및 최적화 - TestSection 컴포넌트 삭제 - 테스트 버튼 UI 제거 - useDashboard 훅에서 테스트 관련 함수 제거 - 도토리 개수 업데이트 로직 개선 - 배너 렌더링 디버깅 로그 추가 - 썸네일 화질 개선 (64px → 128px) - api.allorigins.win 프록시 서비스 제거 - TypeScript 오류 수정 # Conflicts: # apps/client/src/pages/dashboard/dashboard.tsx * fix: ESLint 오류 수정 및 코드 정리 - 빈 함수 오류 수정 (empty arrow function) - non-null assertion 오류 수정 - 디버깅용 console.log 제거 - 코드 포맷팅 적용 * fix: 카드 더보기 버튼 이벤트 중첩 해결 및 토큰 관리 개선 - BookmarkCard, DailyReminderCard에서 더보기 버튼 클릭 시 e.stopPropagation() 추가 - DailyReminderCard 스탬프 오버레이에 pointer-events-none 추가 - Dashboard 모달 팝업 시 스크롤 고정 로직 추가 - axiosInstance에서 하드코딩된 토큰 발급 로직 제거 - 온보딩에서 저장된 토큰만 사용하도록 수정 - 대시보드에서 토큰이 없으면 온보딩으로 리다이렉트하는 로직 추가 * fix: 대시보드 토큰 통합 및 이벤트 처리 문제 수정 * fix: 콘솔 로그 및 errorUtils 파일 제거 및 개발자 테스트용 API 및 관련 코드 제거 * fix: api 폴더에서 썸네일 유틸리티를 utils 폴더로 분리 * fix: TypeScript 에러 수정 * fix: 주석 정리 및 간소화 * fix: axiosInstance에서 온보딩 토큰 사용하도록 수정 * fix: 주석 지우기 * fix: 주석 정리 * refactor: API 호출 함수 정리 및 썸네일 유틸리티 분리 - API 호출 함수에서 불필요한 try/catch 및 콘솔 로그 제거 - 썸네일 관련 유틸리티를 apis에서 utils로 분리 - Thumbnail 컴포넌트 import 경로 수정 - useAcornCount 훅에서 불필요한 try/catch 제거 * refactor: AxiosResponse 타입 활용 및 코드 개선 - API 함수들이 AxiosResponse 타입을 반환하도록 수정 - 훅들에서 response.data로 접근하도록 수정 - 사용하지 않는 AxiosError import 제거 - 썸네일 유틸리티에서 불필요한 Content-Type 헤더 제거 * Feature(client): dashboard popup에 추가 popup 연결 (#105) * feat: client dashboard modalpop에 추가 popup 연결 * feat: popup overlay z-index 임시 수정 * feat: popup overlay 적용 * feat: url title & location truncate 처리 * Feature(onboarding): story 변경사항 반영 (#113) * feat: 스토리 변경+헤더 프롭스 변경 * feat: 디테일 반영 * chore: 프리티어 적용 * Feature(landing): UI 구현과 로띠 적용 (#98) * Feature(landing): 홈 페이지 섹션 구성 요소 추가 * feat: landing 로띠 추가 * feat: 스크롤 효과 적용 * feat: 로띠 루프 설정 * feat: 로띠 추가 * feat: 버튼 컴포넌트 추가 * chore: 스타일 수정 * feat: 코드리뷰 반영 * feat: 텍스트 추가 * feat: 최종 수정 반영 * fix: 이름 자동 생성 오류 변경 * chore: 프리티어 수정 * Api(extension): 익스텐션 북마크 아티클 저장 API 연결 (#107) * feat: 크롬 스토리지에 저장 * feat: 모달 레이아웃 조정 및 색 적용 * feat: 카테고리 조회 및 가져오기 * fix: 드롭다운 초기값 설정 * feat: 포맷 함수+리마인드 get 연결 * feat: 북마크 아티클 api연결 * fix: 불필요 api 제거 * feat: 포맷 시간 추가 * fix: 콘솔 제거 --------- Co-authored-by: jjangminii <[email protected]> * Api (extension): 익스텐션 팝업 수정/삭제/생성 Edit 기능 API 연결 (#114) * feat: 크롬 스토리지에 저장 * feat: 모달 레이아웃 조정 및 색 적용 * feat: 카테고리 조회 및 가져오기 * fix: 드롭다운 초기값 설정 * feat: 포맷 함수+리마인드 get 연결 * feat: 북마크 아티클 api연결 * fix: 불필요 api 제거 * feat: 포맷 시간 추가 * fix: 콘솔 제거 * feat: 카테고리 생성 api * feat: 카테고리 수정 api * fix: 에러 던지기 * fix: 에러 얼럿 추가 * feat: 카테고리 삭제 api 연결 * feat: 토큰 연결 및 받아오기 * fix: 콘솔제거 * fix: lint 수정 --------- Co-authored-by: jjangminii <[email protected]> * Api(client) 대쉬보드 팝업 상세 조회/카테고리 조회/삭제 API 연결 (#115) * api: dashboard axios fetch 함수 구현 * api: dashboard query 함수 구현 * chore: query import 경로 수정 * chore: 불필요한 파일 삭제 * api: dashboard api 연결 * feat: og proxy 우회 로직 구현 * chore: 필요없는 코드 제거 * chore: pnpm lock sync * !HOTFIX: infoBox edit * Refactor(client): 1차 개발 QA (#118) * chore: level modal scroll bar 덜그럭 문제 해결 * feat: 아티클 삭제 query invalidate 적용 * Refactor: 개발 2차 QA 작업 (#119) * feat: 대시보드 카테고리 수정 및 삭제 api * feat: 토글 버튼 zindex 제어 * feat: 아티클 수정 patch api 연결 * feat: 카테고리 생성하기 * fix: lint 수정 * fix: lint dpfj * feat: 저장 시 모달 닫기 * fix: err lint 수정 * feat: 시간 포맷팅 수정 * feat: 모달 닫기 로직 --------- Co-authored-by: constantly-dev <[email protected]> Co-authored-by: karnelll <[email protected]> Co-authored-by: KIM JEONGMIN <[email protected]> Co-authored-by: 이재림 <[email protected]> Co-authored-by: SEOHEE CHOI <[email protected]> Co-authored-by: jjangminii <[email protected]>
📌 Related Issues
✅ 체크 리스트
📄 Tasks
⭐ PR Point (To Reviewer)
컨벱션 상, shared가 없기에 그냥 src/apis에 작업해두었습니다
📷 Screenshot
Summary by CodeRabbit
신규 기능
버그 수정
리팩터링/개선
문서 및 설정