Feat(client, landing): 이용약관, 개인정보 처리방침 뷰 구현 및 footer 링크 반영#233
Feat(client, landing): 이용약관, 개인정보 처리방침 뷰 구현 및 footer 링크 반영#233constantly-dev merged 12 commits intodevelopfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@constantly-dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 3 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
Walkthrough이 PR은 이용약관·개인정보처리방침 정적 페이지를 추가하고 여러 클라이언트 페이지에 Footer를 통합하며, ROUTES_CONFIG·라우터를 업데이트하고 Layout의 사이드바 숨김 로직을 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 사용자
participant Router as Router
participant Layout as Layout
participant Sidebar as Sidebar
participant Page as Page
Note over User,Router: 사용자가 경로로 접근 (/policy, /terms 또는 기타)
User->>Router: 요청 경로 전달
Router->>Layout: 페이지 렌더링 요청
Layout->>Layout: isSidebarHidden 계산 (onboarding || login || policy)
alt 사이드바 숨김
Layout-->>Sidebar: 숨김 처리
else 사이드바 노출
Layout-->>Sidebar: 노출 처리
end
Layout->>Page: 해당 페이지(정책 또는 콘텐츠+Footer) 렌더링
Page-->>User: 콘텐츠 및 Footer 전달
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
|
✅ Storybook chromatic 배포 확인: |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI Agents
In @apps/client/src/layout/Layout.tsx:
- Around line 12-15: The sidebar-hide check in Layout.tsx is failing due to
inconsistent casing between the hardcoded startsWith('/onboarding') and
routesConfig's onBoarding.path ('/onBoarding') while onBoardingCallback.path
uses '/onboarding'; fix by referencing the canonical route value (e.g., use
routesConfig.onBoarding.path and routesConfig.onBoardingCallback.path) or
normalize casing before comparing (e.g., compare
location.pathname.toLowerCase().startsWith(routesConfig.onBoarding.path.toLowerCase())),
ensuring isSidebarHidden uses the route constants rather than hardcoded strings
so the onboarding path is detected correctly.
In @apps/client/src/pages/myBookmark/components/footer/Footer.tsx:
- Around line 25-57: The row uses a single flex container with class "flex
items-center justify-between" wrapping three children (the address block, the
copyright p referencing currentYear, and the social icons div), which can leave
the middle item visually off-center; pick one fix: either change the container
to a three-column grid (e.g., replace the "flex ... justify-between" container
with a grid and use "grid-cols-3 items-center" and add "text-center" to the
middle copyright p), or keep flex and give the left and right children (the
address element and the social icons div) "flex-1" so the middle copyright p
stays centered, or use "justify-center" with a gap and ensure left/right blocks
are absolutely or relatively positioned; update Footer.tsx accordingly by
modifying the container class and/or adding flex-1/text-center to the specific
children (address, the copyright <p> using currentYear, and the social icons
<div>).
- Around line 26-31: The Footer component currently hardcodes the support email
in the JSX (see address block in Footer.tsx), which exposes it to crawlers;
remove the plain email string and instead render a link to a dedicated contact
page or a server-backed contact endpoint (e.g., replace the paragraph that
contains "이한비 · pinback0615@gmail.com" with an anchor to a Contact/Support route
or API), or if you must display an email obfuscate it at runtime (construct it
via JS parts or fetch from a backend endpoint) so the raw address is not present
in the source; update the Footer rendering logic and any imports/props
accordingly to use the contact route or runtime-obfuscated value.
In @apps/client/src/pages/policy/TermsOfService.tsx:
- Line 179: The last list item in the TermsOfService component
(TermsOfService.tsx) is truncated ("브라우저 또는 보안 정책을 우회하여 확장프로그") — update the
text in the corresponding <li> within the TermsOfService component so the
sentence is complete (e.g. "브라우저 또는 보안 정책을 우회하여 확장프로그램을 사용하는 행위" or the correct
finalized wording) to avoid the broken phrase.
🧹 Nitpick comments (5)
apps/client/src/pages/policy/PrivacyPolicy.tsx (1)
7-11: 로고 클릭 동작을 홈 페이지 이동으로 변경하는 것을 권장합니다.현재 로고 클릭 시
window.location.reload()로 페이지를 새로고침하는데, 이는 일반적인 UX 패턴과 다릅니다. 일반적으로 로고는 홈 페이지(또는 메인 페이지)로 이동하는 역할을 합니다. 또한cursor-pointer클래스가 누락되어 클릭 가능한 요소임을 시각적으로 표시하지 못하고 있습니다.🔎 제안하는 개선 방안
+import { useNavigate } from 'react-router-dom'; + const PrivacyPolicy = () => { + const navigate = useNavigate(); + return ( <> <header className="z-5 bg-white-bg absolute top-0 flex w-full justify-items-start px-[8.2rem] py-[2.5rem]"> <img src={HeaderLogo} alt="header logo" - onClick={() => window.location.reload()} + className="cursor-pointer" + onClick={() => navigate('/')} /> </header>apps/client/src/pages/policy/TermsOfService.tsx (2)
7-12: 로고 클릭 동작을 홈 페이지 이동으로 변경하는 것을 권장합니다.PrivacyPolicy와 동일한 이슈입니다.
window.location.reload()대신 홈 페이지로 이동하도록 변경하는 것이 좋습니다.🔎 제안하는 개선 방안
+import { useNavigate } from 'react-router-dom'; + const TermsOfService = () => { + const navigate = useNavigate(); + return ( <> <header className="z-5 bg-white-bg absolute top-0 flex w-full justify-items-start px-[8.2rem] py-[2.5rem]"> <img src={HeaderLogo} alt="header logo" className="cursor-pointer" - onClick={() => window.location.reload()} + onClick={() => navigate('/')} /> </header>
6-13: 선택 사항: 공통 헤더 컴포넌트 추출을 고려해보세요.
PrivacyPolicy와TermsOfService가 동일한 헤더 구조를 공유하고 있습니다. 향후 정책 페이지가 더 추가될 경우를 대비해 공통PolicyPageHeader컴포넌트로 추출하는 것을 고려해볼 수 있습니다.apps/client/src/pages/remind/Remind.tsx (1)
26-26: 여러 페이지에서 중복된 Footer 컴포넌트를 공유 컴포넌트로 통합하는 것을 고려하세요.AI 요약에 따르면 MyBookmark와 Remind 페이지에 각각 별도의 Footer 컴포넌트가 추가되었습니다. 이들 컴포넌트의 내용이 동일하거나 유사하다면,
@shared/components디렉터리에 공통 Footer 컴포넌트를 만들어 코드 중복을 줄이고 유지보수성을 개선할 수 있습니다.🔎 제안하는 리팩토링 방향
-import Footer from './components/footer/Footer'; +import Footer from '@shared/components/footer/Footer';그리고
apps/client/src/shared/components/footer/Footer.tsx에 공통 Footer 컴포넌트를 생성하세요.Also applies to: 181-181
apps/landing/src/components/Footer.tsx (1)
5-5: 환경 변수를 사용하여 SERVICE_URL을 관리하는 것을 권장합니다.
SERVICE_URL이 하드코딩되어 있어 개발, 스테이징, 프로덕션 환경에서 유연하게 대응하기 어렵습니다. 환경 변수로 관리하면 배포 환경에 따라 적절한 URL을 사용할 수 있습니다.🔎 제안하는 수정 사항
- const SERVICE_URL = 'https://pinback.today'; + const SERVICE_URL = import.meta.env.VITE_SERVICE_URL || 'https://pinback.today';그리고
.env파일에 환경별 URL을 설정하세요:VITE_SERVICE_URL=https://pinback.today
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/client/src/layout/Layout.tsxapps/client/src/pages/myBookmark/MyBookmark.tsxapps/client/src/pages/myBookmark/components/footer/Footer.tsxapps/client/src/pages/onBoarding/components/footer/Footer.tsxapps/client/src/pages/policy/PrivacyPolicy.tsxapps/client/src/pages/policy/TermsOfService.tsxapps/client/src/pages/remind/Remind.tsxapps/client/src/pages/remind/components/footer/Footer.tsxapps/client/src/routes/router.tsxapps/client/src/routes/routesConfig.tsapps/landing/src/components/Footer.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.065Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.678Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.
📚 Learning: 2025-07-08T11:47:10.642Z
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 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.
Applied to files:
apps/client/src/pages/myBookmark/MyBookmark.tsx
🧬 Code graph analysis (2)
apps/client/src/routes/router.tsx (1)
apps/client/src/routes/routesConfig.ts (1)
ROUTES_CONFIG(1-38)
apps/client/src/layout/Layout.tsx (1)
apps/client/src/routes/routesConfig.ts (1)
ROUTES_CONFIG(1-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: storybook
🔇 Additional comments (14)
apps/client/src/pages/onBoarding/components/footer/Footer.tsx (1)
10-22: 내부 라우팅 전환이 올바르게 구현되었습니다.외부 링크에서 React Router의
Link컴포넌트로 전환하여 페이지 새로고침 없이 내부 네비게이션을 지원합니다. 라우트 경로도routesConfig와 일치합니다.apps/client/src/pages/myBookmark/MyBookmark.tsx (1)
21-21: Footer 컴포넌트 통합이 올바르게 구현되었습니다.Footer가 메인 컨텐츠와 모달 포털 사이에 적절하게 배치되어 있습니다.
Also applies to: 106-106
apps/client/src/routes/router.tsx (1)
7-8: 정책 페이지 라우트 설정이 올바르게 구현되었습니다.새로운 개인정보 처리방침과 이용약관 페이지가 라우터에 적절히 통합되었으며,
ROUTES_CONFIG를 통해 일관되게 관리되고 있습니다.Also applies to: 47-54
apps/landing/src/components/Footer.tsx (1)
19-19: LGTM!링크 구조가 올바르게 업데이트되었으며,
target="_blank"와 함께rel="noopener noreferrer"보안 속성이 적절하게 적용되었습니다.Also applies to: 28-28
apps/client/src/layout/Layout.tsx (2)
8-10: LGTM!정책 페이지 확인 로직이 올바르게 구현되었으며,
ROUTES_CONFIG를 활용하여 일관성을 유지하고 있습니다.
20-20: 조건부 렌더링 구현은 올바릅니다.
isSidebarHidden플래그를 사용한 조건부 렌더링 로직은 적절합니다. 다만, 위에서 지적한 대소문자 불일치 문제가 해결되어야 의도한 대로 동작합니다.apps/client/src/routes/routesConfig.ts (1)
30-37: LGTM!새로운 정책 페이지 라우트가 명확하고 일관성 있게 추가되었습니다. 경로 네이밍(
/policy,/terms)도 관례적이며 적절합니다.apps/client/src/pages/remind/components/footer/Footer.tsx (3)
1-5: LGTM!임포트와 초기 설정이 적절합니다.
currentYear계산도 표준적인 방식입니다.
10-22: LGTM!내부 정책 페이지 링크가
Link컴포넌트를 사용하여 SPA 네비게이션을 올바르게 구현하고 있으며, 스타일링도 적절합니다.
38-55: LGTM!외부 소셜 링크가 보안 속성(
rel="noopener noreferrer")과 접근성 속성(aria-label)을 적절하게 포함하고 있습니다.apps/client/src/pages/myBookmark/components/footer/Footer.tsx (4)
1-2: LGTM! 적절한 import 사용내부 네비게이션을 위해
Link컴포넌트를 사용하고, 디자인 시스템의Icon을 활용하는 것이 올바릅니다.
10-22: LGTM! 내부 라우팅 적절하게 구현됨
Link컴포넌트를 사용하여/terms와/policy페이지로의 내부 네비게이션이 올바르게 구현되었습니다. 호버 효과와 스타일링도 적절합니다.
8-8: 고정 padding-right 값 확인 필요Footer에 고정된
pr-[3rem]값이 사용되고 있습니다. 사이드바의 표시/숨김 상태에 따라 이 값이 적절한지 확인이 필요합니다.다양한 뷰포트와 사이드바 상태에서 레이아웃이 올바르게 동작하는지 테스트해주세요.
38-56: LGTM! 접근성 모범 사례 준수외부 링크에 적절한 보안 속성(
rel="noopener noreferrer")과 접근성 레이블(aria-label)이 적용되어 있습니다. 호버 상태의 시각적 피드백도 잘 구현되었습니다.
| const isSidebarHidden = | ||
| location.pathname.startsWith('/onboarding') || | ||
| location.pathname.startsWith('/login') || | ||
| isPolicyPage; |
There was a problem hiding this comment.
CRITICAL: 경로 대소문자 불일치로 인한 사이드바 숨김 로직 오류
Line 13에서 startsWith('/onboarding')로 체크하고 있지만, routesConfig.ts의 onBoarding.path는 /onBoarding(대문자 B)으로 정의되어 있습니다. 이로 인해 온보딩 페이지에서 사이드바가 의도대로 숨겨지지 않습니다.
참고로 onBoardingCallback.path는 /onboarding/callback(소문자)로 정의되어 있어 라우트 정의 자체에도 일관성이 없습니다.
🔎 제안하는 수정 방안
옵션 1: Layout.tsx 수정 (권장)
const isSidebarHidden =
- location.pathname.startsWith('/onboarding') ||
+ location.pathname.startsWith(ROUTES_CONFIG.onBoarding.path) ||
location.pathname.startsWith('/login') ||
isPolicyPage;옵션 2: routesConfig.ts의 경로 통일
onBoarding.path를 소문자 /onboarding으로 변경하여 onBoardingCallback과 일관성을 맞춥니다.
📝 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 isSidebarHidden = | |
| location.pathname.startsWith('/onboarding') || | |
| location.pathname.startsWith('/login') || | |
| isPolicyPage; | |
| const isSidebarHidden = | |
| location.pathname.startsWith('/onBoarding') || | |
| location.pathname.startsWith('/login') || | |
| isPolicyPage; |
🤖 Prompt for AI Agents
In @apps/client/src/layout/Layout.tsx around lines 12 - 15, The sidebar-hide
check in Layout.tsx is failing due to inconsistent casing between the hardcoded
startsWith('/onboarding') and routesConfig's onBoarding.path ('/onBoarding')
while onBoardingCallback.path uses '/onboarding'; fix by referencing the
canonical route value (e.g., use routesConfig.onBoarding.path and
routesConfig.onBoardingCallback.path) or normalize casing before comparing
(e.g., compare
location.pathname.toLowerCase().startsWith(routesConfig.onBoarding.path.toLowerCase())),
ensuring isSidebarHidden uses the route constants rather than hardcoded strings
so the onboarding path is detected correctly.
| <div className="flex items-center justify-between"> | ||
| <address className="flex gap-[0.8rem] not-italic"> | ||
| <p className="caption2-sb text-font-ltgray-4">운영팀 문의</p> | ||
| <p className="caption2-m text-font-ltgray-4"> | ||
| 이한비 · pinback0615@gmail.com | ||
| </p> | ||
| </address> | ||
| <p className="caption2-m text-font-ltgray-4"> | ||
| ©{currentYear} pinback All rights reserved. | ||
| </p> | ||
|
|
||
| <div className="flex items-end gap-[1.2rem]"> | ||
| <p className="caption2-m text-gray400">TEAM. 도묵이</p> | ||
| <a | ||
| href="https://instagram.com/pinback.today/" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| aria-label="Pinback 인스타그램" | ||
| className="transition-opacity hover:opacity-80" | ||
| > | ||
| <Icon name="instagram" width={28} height={28} /> | ||
| </a> | ||
| <a | ||
| href="https://pinback.palms.blog/" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| aria-label="Pinback 블로그" | ||
| className="transition-opacity hover:opacity-80" | ||
| > | ||
| <Icon name="palms" width={28} height={28} /> | ||
| </a> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
레이아웃 구조 검토 필요
justify-between을 사용하여 3개의 요소(연락처, 저작권, 소셜 아이콘)를 배치하고 있습니다. 이 경우 가운데 요소(저작권 텍스트)가 시각적으로 중앙에 위치하지 않을 수 있습니다.
의도한 레이아웃이 맞는지 확인하고, 필요시 다음과 같은 대안을 고려해보세요:
justify-center와gap사용- Grid 레이아웃 사용하여 명시적인 열 배치
- 각 섹션에
flex-1적용
🔎 Grid 레이아웃 대안
- <div className="flex items-center justify-between">
+ <div className="grid grid-cols-3 items-center">
- <address className="flex gap-[0.8rem] not-italic">
+ <address className="flex gap-[0.8rem] not-italic justify-self-start">
<p className="caption2-sb text-font-ltgray-4">운영팀 문의</p>
<p className="caption2-m text-font-ltgray-4">
이한비 · pinback0615@gmail.com
</p>
</address>
- <p className="caption2-m text-font-ltgray-4">
+ <p className="caption2-m text-font-ltgray-4 justify-self-center">
©{currentYear} pinback All rights reserved.
</p>
- <div className="flex items-end gap-[1.2rem]">
+ <div className="flex items-end gap-[1.2rem] justify-self-end">
<p className="caption2-m text-gray400">TEAM. 도묵이</p>🤖 Prompt for AI Agents
In @apps/client/src/pages/myBookmark/components/footer/Footer.tsx around lines
25 - 57, The row uses a single flex container with class "flex items-center
justify-between" wrapping three children (the address block, the copyright p
referencing currentYear, and the social icons div), which can leave the middle
item visually off-center; pick one fix: either change the container to a
three-column grid (e.g., replace the "flex ... justify-between" container with a
grid and use "grid-cols-3 items-center" and add "text-center" to the middle
copyright p), or keep flex and give the left and right children (the address
element and the social icons div) "flex-1" so the middle copyright p stays
centered, or use "justify-center" with a gap and ensure left/right blocks are
absolutely or relatively positioned; update Footer.tsx accordingly by modifying
the container class and/or adding flex-1/text-center to the specific children
(address, the copyright <p> using currentYear, and the social icons <div>).
| <address className="flex gap-[0.8rem] not-italic"> | ||
| <p className="caption2-sb text-font-ltgray-4">운영팀 문의</p> | ||
| <p className="caption2-m text-font-ltgray-4"> | ||
| 이한비 · pinback0615@gmail.com | ||
| </p> | ||
| </address> |
There was a problem hiding this comment.
이메일 주소 노출로 인한 스팸 위험
운영팀 이메일 주소가 프론트엔드 코드에 평문으로 노출되어 있어 스팸봇의 타겟이 될 수 있습니다. 다음 방법을 고려해보세요:
- 전용 문의 폼 구현
- 이메일 주소 난독화
- 별도의 고객지원 이메일 서비스 활용
🔎 이메일 난독화 예시
- <p className="caption2-m text-font-ltgray-4">
- 이한비 · pinback0615@gmail.com
- </p>
+ <p className="caption2-m text-font-ltgray-4">
+ 이한비 · pinback0615{'@'}gmail{'.'}com
+ </p>또는 문의 페이지 링크로 대체:
- <p className="caption2-m text-font-ltgray-4">
- 이한비 · pinback0615@gmail.com
- </p>
+ <Link to="/contact" className="caption2-m text-font-ltgray-4 hover:underline">
+ 운영팀에 문의하기
+ </Link>📝 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.
| <address className="flex gap-[0.8rem] not-italic"> | |
| <p className="caption2-sb text-font-ltgray-4">운영팀 문의</p> | |
| <p className="caption2-m text-font-ltgray-4"> | |
| 이한비 · pinback0615@gmail.com | |
| </p> | |
| </address> | |
| <address className="flex gap-[0.8rem] not-italic"> | |
| <p className="caption2-sb text-font-ltgray-4">운영팀 문의</p> | |
| <p className="caption2-m text-font-ltgray-4"> | |
| 이한비 · pinback0615{'@'}gmail{'.'}com | |
| </p> | |
| </address> |
🤖 Prompt for AI Agents
In @apps/client/src/pages/myBookmark/components/footer/Footer.tsx around lines
26 - 31, The Footer component currently hardcodes the support email in the JSX
(see address block in Footer.tsx), which exposes it to crawlers; remove the
plain email string and instead render a link to a dedicated contact page or a
server-backed contact endpoint (e.g., replace the paragraph that contains "이한비 ·
pinback0615@gmail.com" with an anchor to a Contact/Support route or API), or if
you must display an email obfuscate it at runtime (construct it via JS parts or
fetch from a backend endpoint) so the raw address is not present in the source;
update the Footer rendering logic and any imports/props accordingly to use the
contact route or runtime-obfuscated value.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (1)
10-24: 시맨틱 HTML 및 스타일 개선 제안
<p>태그는 단락을 나타내므로 구분자(|)에는<span>이 더 적합합니다.Link컴포넌트는 기본적으로 클릭 가능한 요소이므로cursor-pointer클래스가 불필요합니다.♻️ 개선 제안
<Link to={ROUTES_CONFIG.termsOfService.path} - className="caption1-sb text-font-gray-2 cursor-pointer hover:underline" + className="caption1-sb text-font-gray-2 hover:underline" > 이용약관 </Link> - <p className="caption1-sb text-font-gray-2">|</p> + <span className="caption1-sb text-font-gray-2" aria-hidden="true">|</span> <Link to={ROUTES_CONFIG.privacyPolicy.path} - className="caption1-sb text-font-gray-2 cursor-pointer hover:underline" + className="caption1-sb text-font-gray-2 hover:underline" >
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/client/src/pages/login/Login.tsxapps/client/src/pages/myBookmark/components/footer/Footer.tsxapps/client/src/pages/onBoarding/components/footer/Footer.tsxapps/client/src/pages/onBoarding/components/funnel/step/SocialLoginStep.tsxapps/client/src/pages/remind/components/footer/Footer.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/client/src/pages/onBoarding/components/footer/Footer.tsx
- apps/client/src/pages/remind/components/footer/Footer.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.065Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.678Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.
📚 Learning: 2025-07-15T20:00:13.756Z
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 80
File: apps/client/src/shared/components/ui/modalPop/ModalPop.tsx:36-41
Timestamp: 2025-07-15T20:00:13.756Z
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.
Applied to files:
apps/client/src/pages/onBoarding/components/funnel/step/SocialLoginStep.tsx
🧬 Code graph analysis (2)
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (1)
apps/client/src/routes/routesConfig.ts (1)
ROUTES_CONFIG(1-38)
apps/client/src/pages/login/Login.tsx (1)
apps/client/src/routes/routesConfig.ts (1)
ROUTES_CONFIG(1-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: storybook
🔇 Additional comments (6)
apps/client/src/pages/onBoarding/components/funnel/step/SocialLoginStep.tsx (1)
5-5: 라우트 중앙화 리팩토링이 올바르게 적용되었습니다.하드코딩된 라우트 경로를
ROUTES_CONFIG로 교체하여 라우트 관리를 중앙화한 것은 좋은 개선입니다. 타입 안전성이 확보되고 향후 경로 변경 시 유지보수가 용이해집니다.Also applies to: 38-38, 45-45
apps/client/src/pages/login/Login.tsx (1)
9-9: LGTM! 라우트 설정이 일관되게 적용되었습니다.
SocialLoginStep컴포넌트와 동일한 패턴으로ROUTES_CONFIG를 활용하여 라우트를 중앙화했습니다. 코드베이스 전반에 걸쳐 일관된 접근 방식이 적용되어 좋습니다.Also applies to: 52-52, 59-59
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (4)
1-3: LGTM!임포트가 깔끔하고 모두 컴포넌트에서 사용되고 있습니다.
5-6: LGTM!컴포넌트 선언과 연도 계산이 적절합니다.
39-56: LGTM!외부 링크에
target="_blank",rel="noopener noreferrer",aria-label이 적절히 적용되어 보안 및 접근성 모범 사례를 잘 따르고 있습니다.
38-38: 이 색상 클래스는 프로젝트의 정의된 디자인 토큰 시스템의 일부입니다.text-gray400은packages/design-system에 정의되어 있으며 프로젝트 전반에서 일관되게 사용되고 있습니다. 프로젝트는text-gray900,bg-gray200,placeholder-font-gray-3등 의도적으로 다양한 네이밍 패턴을 사용하는 커스텀 디자인 토큰 시스템을 운영하고 있으므로, 이를 변경할 필요가 없습니다.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (1)
40-56: 소셜 미디어 URL을 상수로 추출하는 것을 고려해보세요.Instagram과 블로그 URL이 컴포넌트 내에 하드코딩되어 있습니다. 향후 URL 변경 시 유지보수를 위해 별도 상수 파일이나 환경 변수로 관리하는 것을 권장합니다.
♻️ 제안하는 리팩토링
상수 파일 생성 (예:
src/constants/social.ts):export const SOCIAL_LINKS = { instagram: 'https://instagram.com/pinback.today/', blog: 'https://pinback.palms.blog/', } as const;Footer 컴포넌트에서 사용:
+import { SOCIAL_LINKS } from '@constants/social'; + const Footer = () => { // ... return ( // ... <a - href="https://instagram.com/pinback.today/" + href={SOCIAL_LINKS.instagram} target="_blank" rel="noopener noreferrer" aria-label="Pinback 인스타그램" className="transition-opacity hover:opacity-80" > <Icon name="instagram" width={28} height={28} /> </a> <a - href="https://pinback.palms.blog/" + href={SOCIAL_LINKS.blog} target="_blank" rel="noopener noreferrer" aria-label="Pinback 블로그" className="transition-opacity hover:opacity-80" > <Icon name="palms" width={28} height={28} /> </a> ); };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/client/src/pages/myBookmark/MyBookmark.tsxapps/client/src/pages/myBookmark/components/footer/Footer.tsxapps/client/src/pages/remind/Remind.tsxapps/client/src/pages/remind/components/footer/Footer.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/client/src/pages/remind/components/footer/Footer.tsx
- apps/client/src/pages/myBookmark/MyBookmark.tsx
- apps/client/src/pages/remind/Remind.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.065Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
Learnt from: constantly-dev
Repo: Pinback-Team/pinback-client PR: 5
File: apps/extension/src/index.css:1-1
Timestamp: 2025-08-19T17:18:57.678Z
Learning: constantly-dev는 디자인 시스템 설정 PR 머지 후 `import 'pinback/tailwind-config/shared-styles.css';`를 `app.css`나 `index.css`에서 사용하여 공유 스타일을 관리할 계획입니다.
🧬 Code graph analysis (1)
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (1)
apps/client/src/routes/routesConfig.ts (1)
ROUTES_CONFIG(1-38)
🔇 Additional comments (4)
apps/client/src/pages/myBookmark/components/footer/Footer.tsx (4)
1-7: 좋은 구조입니다!중앙화된 라우팅 관리를 위해
ROUTES_CONFIG를 사용하고 있고, 동적으로 현재 연도를 계산하는 방식이 적절합니다.
11-23: 라우팅 구현이 올바릅니다.
ROUTES_CONFIG를 사용하여 일관된 라우팅을 유지하고 있으며,hover:underline효과로 사용자 경험이 개선되었습니다.
24-26: 섹션 간 간격 확인이 필요합니다.상단 링크 영역(이용약관, 개인정보처리방침)과 하단 정보 영역(연락처, 저작권) 사이에 명시적인 여백이 없습니다. 의도한 디자인인지 확인하고, 필요시 간격을 추가하는 것을 고려해보세요.
💡 간격 추가 예시
</div> - <div className="flex items-center justify-between"> + <div className="mt-[2.4rem] flex items-center justify-between"> <address className="flex gap-[0.8rem] not-italic">
39-56: 접근성 구현이 우수합니다.외부 링크에 적절한
rel="noopener noreferrer"보안 속성과aria-label이 적용되어 있습니다.
📌 Related Issues
📄 Tasks
⭐ PR Point (To Reviewer)
이용약관이랑 개인정보 처리방침 뷰 구현했습니다. 그리고 기존 노션으로 되어있던 footer link를 해당 뷰로 router 처리하도록 수정하였습니다.
📷 Screenshot
Summary by CodeRabbit
새로운 기능
개선 사항
✏️ Tip: You can customize this high-level summary in your review settings.