Conversation
[Feat] 대시보드 페이지 UI 구현
Bumps [next](https://github.com/vercel/next.js) from 16.1.1 to 16.1.6. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](vercel/next.js@v16.1.1...v16.1.6) --- updated-dependencies: - dependency-name: next dependency-version: 16.1.6 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
….1.6 chore(deps): bump next from 16.1.1 to 16.1.6
Bumps [axios](https://github.com/axios/axios) from 1.13.2 to 1.13.5. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.13.2...v1.13.5) --- updated-dependencies: - dependency-name: axios dependency-version: 1.13.5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0. - [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md) - [Commits](isaacs/node-glob@v10.4.5...v10.5.0) --- updated-dependencies: - dependency-name: glob dependency-version: 10.5.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
….13.5 chore(deps): bump axios from 1.13.2 to 1.13.5
….5.0 chore(deps): bump glob from 10.4.5 to 10.5.0
[Feat] Template 도메인 API 연동
📝 WalkthroughWalkthrough이 변경은 랜딩 페이지에 다국어 지원 푸터를 추가하고, Portfolio의 자동 무한스크롤을 수동 "더보기" 버튼으로 변경하며, 대시보드 레이아웃 컴포넌트와 사이드바 import 경로를 추가/수정합니다. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 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. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/landing/Footer.tsx (1)
4-20:⚠️ Potential issue | 🟠 Major환경변수 누락 시
href="undefined"링크가 생성됩니다.현재 문자열 템플릿 사용으로 인해 환경변수가 정의되지 않았을 때
"undefined"문자열이 href 값으로 설정됩니다. 라인 8, 13, 18의footerLinks배열에서 이러한 문제가 발생하며, 이는 라인 38-44의<a>태그에서 실제 깨진 링크로 렌더링됩니다.필수 환경변수에 대해 Nullish Coalescing Operator(??)를 사용하여 fallback 값을 지정하세요:
🛠️ 제안 변경
const footerLinks = [ { title: "Follow us", items: ["Instagram"], - href: `${process.env.NEXT_PUBLIC_INSTAGRAM_URL}`, + href: process.env.NEXT_PUBLIC_INSTAGRAM_URL ?? "#", }, { title: "Company", items: ["Feedback"], - href: `mailto:${process.env.NEXT_PUBLIC_EMAIL_ADDRESS}`, + href: process.env.NEXT_PUBLIC_EMAIL_ADDRESS + ? `mailto:${process.env.NEXT_PUBLIC_EMAIL_ADDRESS}` + : "#", }, { title: "Resources", items: ["Privacy policy"], - href: `${process.env.NEXT_PUBLIC_PRIVACY_POLICY_NOTION_URL}`, + href: process.env.NEXT_PUBLIC_PRIVACY_POLICY_NOTION_URL ?? "#", }, ];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/Footer.tsx` around lines 4 - 20, The footerLinks array creates href values via template strings which yield the literal "undefined" when environment variables are missing; update the hrefs in the footerLinks entries (the objects for "Follow us", "Company", and "Resources" used by the Footer component / anchor rendering) to use nullish coalescing (e.g., process.env.NEXT_PUBLIC_INSTAGRAM_URL ?? '' or another safe fallback) instead of `${...}` so missing env vars produce a safe fallback (empty string or '#') and prevent broken links in the <a> render path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`[locale]/dashboard/layout.tsx:
- Around line 3-9: 현재 기본 내보내기된 선언식 컴포넌트 DashboardLayout을 팀 규칙에 맞춰 Arrow function
스타일로 변경하세요: 함수 선언 export default function DashboardLayout(...) 대신 const
DashboardLayout: React.FC<{ children: ReactNode }> = ({ children }) => { return
<>{children}</>; }; export default DashboardLayout; 그리고 파일에 ReactNode 또는 React를
참조할 수 없으면 상단에 import type { ReactNode } from 'react' 또는 import React from
'react'를 추가해 타입이 해결되도록 하세요.
In `@src/app/layout.tsx`:
- Around line 23-26: The Footer component is placed in the root layout
(src/app/layout.tsx) inside QueryProvider, causing it to appear on all routes;
remove the <Footer /> from layout.tsx and instead add it to the landing-specific
layout or the landing page component that should show it (use the component at
"@/components/landing/Footer"), or create a new src/app/(landing)/layout.tsx
that wraps landing routes with <Footer />; update imports and ensure
QueryProvider remains in the root layout if needed, and that only the landing
routes import or render Footer.
---
Outside diff comments:
In `@src/components/landing/Footer.tsx`:
- Around line 4-20: The footerLinks array creates href values via template
strings which yield the literal "undefined" when environment variables are
missing; update the hrefs in the footerLinks entries (the objects for "Follow
us", "Company", and "Resources" used by the Footer component / anchor rendering)
to use nullish coalescing (e.g., process.env.NEXT_PUBLIC_INSTAGRAM_URL ?? '' or
another safe fallback) instead of `${...}` so missing env vars produce a safe
fallback (empty string or '#') and prevent broken links in the <a> render path.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/app/[locale]/dashboard/layout.tsxsrc/app/[locale]/mypage/page.tsxsrc/app/layout.tsxsrc/app/price/page.tsxsrc/components/landing/Footer.tsxsrc/components/landing/Portfolio.tsx
💤 Files with no reviewable changes (1)
- src/app/price/page.tsx
| export default function DashboardLayout({ | ||
| children, | ||
| }: { | ||
| children: ReactNode; | ||
| }) { | ||
| return <>{children}</>; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# TSX 파일에서 export default function 패턴 확인
rg -nP --type=tsx 'export default function [A-Z]\w*\s*\('Repository: studiio-x/landing-fe
Length of output: 91
🏁 Script executed:
#!/bin/bash
# .tsx 파일에서 "export default function" 패턴 찾기
fd -e tsx | xargs rg -n 'export default function [A-Z]' | head -20Repository: studiio-x/landing-fe
Length of output: 846
🏁 Script executed:
#!/bin/bash
# Arrow function 스타일 (const ... = (...) => ) 패턴 찾기
fd -e tsx | xargs rg -n 'const [A-Z]\w+ = \(' | grep -E '(=|=>)' | head -20Repository: studiio-x/landing-fe
Length of output: 1981
팀 코딩 규칙에 따라 Arrow function 스타일로 변경해주세요.
코딩 가이드라인에서 "Arrow function 기반 function component" 스타일을 명시하고 있으므로, 아래와 같이 수정이 필요합니다.
♻️ 제안 변경
-import type { ReactNode } from "react";
-
-export default function DashboardLayout({
- children,
-}: {
- children: ReactNode;
-}) {
- return <>{children}</>;
-}
+import type { ReactNode } from "react";
+
+type DashboardLayoutProps = {
+ children: ReactNode;
+};
+
+const DashboardLayout = ({ children }: DashboardLayoutProps) => {
+ return <>{children}</>;
+};
+
+export default DashboardLayout;📝 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 function DashboardLayout({ | |
| children, | |
| }: { | |
| children: ReactNode; | |
| }) { | |
| return <>{children}</>; | |
| } | |
| import type { ReactNode } from "react"; | |
| type DashboardLayoutProps = { | |
| children: ReactNode; | |
| }; | |
| const DashboardLayout = ({ children }: DashboardLayoutProps) => { | |
| return <>{children}</>; | |
| }; | |
| export default DashboardLayout; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/`[locale]/dashboard/layout.tsx around lines 3 - 9, 현재 기본 내보내기된 선언식
컴포넌트 DashboardLayout을 팀 규칙에 맞춰 Arrow function 스타일로 변경하세요: 함수 선언 export default
function DashboardLayout(...) 대신 const DashboardLayout: React.FC<{ children:
ReactNode }> = ({ children }) => { return <>{children}</>; }; export default
DashboardLayout; 그리고 파일에 ReactNode 또는 React를 참조할 수 없으면 상단에 import type {
ReactNode } from 'react' 또는 import React from 'react'를 추가해 타입이 해결되도록 하세요.
| <QueryProvider> | ||
| {children} | ||
| <Footer /> | ||
| </QueryProvider> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Footer 사용 위치 확인
rg -n --type=tsx '<Footer\s*/>' src/app
# layout.tsx 파일 목록 확인
fd -t f 'layout.tsx' src/app
# src/app 디렉토리 구조 확인
tree -L 3 src/app 2>/dev/null || find src/app -type f -name '*.tsx' -o -name '*.ts' | head -30Repository: studiio-x/landing-fe
Length of output: 798
🏁 Script executed:
#!/bin/bash
# src/app/layout.tsx의 실제 내용 확인
cat -n src/app/layout.tsx
# Footer 컴포넌트 정의 위치 확인
rg -n 'Footer' src/app --type ts --type tsx
# query-provider.tsx 확인 (QueryProvider 옆에 Footer가 있는지)
cat -n src/app/query-provider.tsxRepository: studiio-x/landing-fe
Length of output: 2014
🏁 Script executed:
#!/bin/bash
# landing 관련 레이아웃 그룹 확인
fd -t f 'layout.tsx' src/app | grep -i landing
# 랜딩 페이지 구조 재확인
ls -la src/app/
# 페이지 구조: page.tsx 모두 확인
fd -t f 'page.tsx' src/appRepository: studiio-x/landing-fe
Length of output: 1196
🏁 Script executed:
#!/bin/bash
# 확인: [locale] 레이아웃이 루트 레이아웃과 합성되는지 검증
cat -n src/app/\[locale\]/layout.tsxRepository: studiio-x/landing-fe
Length of output: 1255
Footer를 루트 레이아웃에 배치하면 모든 라우트에 전역 노출됩니다.
PR 목표가 "랜딩 페이지 푸터 추가"라면, 현재 위치(src/app/layout.tsx line 25)는 범위가 너무 넓습니다. 이 배치로는 /dashboard, /login, /signup, /mypage 등 모든 페이지에 Footer가 표시됩니다.
컴포넌트 경로(@/components/landing/Footer)에서도 랜딩 전용임이 명확한데, 실제로는 전역 적용되고 있습니다. 랜딩 페이지 전용 레이아웃 구조로 이동시키거나 페이지 컴포넌트 내에서 직접 import하는 방식으로 수정하시기 바랍니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/layout.tsx` around lines 23 - 26, The Footer component is placed in
the root layout (src/app/layout.tsx) inside QueryProvider, causing it to appear
on all routes; remove the <Footer /> from layout.tsx and instead add it to the
landing-specific layout or the landing page component that should show it (use
the component at "@/components/landing/Footer"), or create a new
src/app/(landing)/layout.tsx that wraps landing routes with <Footer />; update
imports and ensure QueryProvider remains in the root layout if needed, and that
only the landing routes import or render Footer.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/components/landing/Footer.tsx (2)
29-29: Logo 컴포넌트에 접근성 라벨 추가를 고려하세요.스크린 리더 사용자를 위해 Logo 컴포넌트에
aria-label을 추가하거나, Logo 컴포넌트 내부에서 접근성 텍스트가 제공되는지 확인해보세요.♿ 접근성 개선 예시
- <Logo className="mb-8 h-6 w-28" /> + <Logo className="mb-8 h-6 w-28" aria-label="StudioX" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/Footer.tsx` at line 29, The Logo usage in Footer.tsx lacks an accessibility label; update the <Logo> invocation (or the Logo component itself) to provide accessible text for screen readers—either add an appropriate aria-label (e.g., company name + "logo") to the Logo element in Footer.tsx or ensure the Logo component exposes readable text (or marks the SVG as decorative with aria-hidden when appropriate); target the Logo component referenced in Footer.tsx and implement the aria attributes or internal accessible text accordingly.
7-23: 데이터 구조 단순화를 고려해보세요.현재 각 섹션의
items배열에 하나의 항목만 있고,href가 섹션 전체에 공유되는 구조입니다. 향후 여러 링크가 추가될 계획이 없다면, 구조를 단순화하거나 각 항목별로href를 가지도록 변경하는 것이 더 직관적일 수 있습니다.♻️ 항목별 href를 가지는 구조 예시
const footerLinks = [ { title: t("followUs"), - items: [t("instagram")], - href: `${process.env.NEXT_PUBLIC_INSTAGRAM_URL}`, + items: [{ label: t("instagram"), href: process.env.NEXT_PUBLIC_INSTAGRAM_URL }], }, // ... ];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/landing/Footer.tsx` around lines 7 - 23, Footer's link data is overstructured: footerLinks currently has an items array with single string and a section-level href; update the shape so each link item owns its own href (or if sections will never have multiple links, remove items and give the section a single label + href). Locate the footerLinks constant in Footer.tsx and either (A) change items from string[] to an array of objects like { label: t("..."), href: process.env... } for each section so each link carries its own href, or (B) if only one link per section is expected, replace items with a single label field and href on the section object (e.g., title, label: t("..."), href: ...), then update consuming code in the Footer component to render using the new structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/landing/Footer.tsx`:
- Around line 41-47: In Footer.tsx update the anchor rendering (the <a> that
uses href={section.href}, key={itemIndex}, and displays {item}) to treat
external links safely and accessibly: add target="_blank" and rel="noopener
noreferrer" to prevent reverse tabnabbing, and include an accessible indicator
such as an aria-label or visually hidden text that mentions the link opens in a
new tab (e.g., append "opens in a new tab" to aria-label) so screen reader users
are informed; ensure this change is applied where the anchor is created inside
the Footer component or its render function.
---
Nitpick comments:
In `@src/components/landing/Footer.tsx`:
- Line 29: The Logo usage in Footer.tsx lacks an accessibility label; update the
<Logo> invocation (or the Logo component itself) to provide accessible text for
screen readers—either add an appropriate aria-label (e.g., company name +
"logo") to the Logo element in Footer.tsx or ensure the Logo component exposes
readable text (or marks the SVG as decorative with aria-hidden when
appropriate); target the Logo component referenced in Footer.tsx and implement
the aria attributes or internal accessible text accordingly.
- Around line 7-23: Footer's link data is overstructured: footerLinks currently
has an items array with single string and a section-level href; update the shape
so each link item owns its own href (or if sections will never have multiple
links, remove items and give the section a single label + href). Locate the
footerLinks constant in Footer.tsx and either (A) change items from string[] to
an array of objects like { label: t("..."), href: process.env... } for each
section so each link carries its own href, or (B) if only one link per section
is expected, replace items with a single label field and href on the section
object (e.g., title, label: t("..."), href: ...), then update consuming code in
the Footer component to render using the new structure.
| <a | ||
| href={section.href} | ||
| key={itemIndex} | ||
| className="Body_3_medium lg:Body_2_medium text-Grey-300 block" | ||
| > | ||
| {item} | ||
| </a> |
There was a problem hiding this comment.
외부 링크에 보안 속성과 접근성 속성을 추가하세요.
Instagram, 개인정보처리방침 등 외부 링크에 target="_blank"와 rel="noopener noreferrer"를 추가하면 보안(reverse tabnabbing 방지)과 UX가 개선됩니다. 또한, 새 창에서 열린다는 것을 스크린 리더 사용자에게 알리기 위해 시각적 표시나 aria-label을 고려해보세요.
🔒 보안 및 접근성 개선 제안
<a
href={section.href}
key={itemIndex}
className="Body_3_medium lg:Body_2_medium text-Grey-300 block"
+ target="_blank"
+ rel="noopener noreferrer"
>
{item}
</a>📝 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.
| <a | |
| href={section.href} | |
| key={itemIndex} | |
| className="Body_3_medium lg:Body_2_medium text-Grey-300 block" | |
| > | |
| {item} | |
| </a> | |
| <a | |
| href={section.href} | |
| key={itemIndex} | |
| className="Body_3_medium lg:Body_2_medium text-Grey-300 block" | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| > | |
| {item} | |
| </a> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/landing/Footer.tsx` around lines 41 - 47, In Footer.tsx update
the anchor rendering (the <a> that uses href={section.href}, key={itemIndex},
and displays {item}) to treat external links safely and accessibly: add
target="_blank" and rel="noopener noreferrer" to prevent reverse tabnabbing, and
include an accessible indicator such as an aria-label or visually hidden text
that mentions the link opens in a new tab (e.g., append "opens in a new tab" to
aria-label) so screen reader users are informed; ensure this change is applied
where the anchor is created inside the Footer component or its render function.
|
흠... dev 코드랑 랜딩 페이지 코드가 섞여 있는 것 같은데 |
|
그리구 코드래빗 리뷰 적용시킨 다음에 머지해야 할 것 같아요 !! 저 푸터가 랜딩 말고 다른 모든 페이지에도 표시되는 건가요 ?? |
💡 PR 타입
📝 PR 내용
(@chaeyoungwon 그래서 dev가 아닌 main으로 머지해서 push해도 될까용??)
🔍 관련 이슈
📸 작업 화면
Summary by CodeRabbit
새로운 기능
개선 사항
수정