인사이트 스타일링 개선, 페이지네이션 적용#464
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthrough
Changes
Sequence DiagramsequenceDiagram
participant User as "User"
participant UI as "InsightsPagination\n(Component)"
participant Router as "Router"
participant Page as "InsightsPage"
participant Fetch as "fetchArticles"
participant Strapi as "Strapi API"
User->>UI: 페이지 선택
UI->>Router: push /insights?page=N
Router->>Page: 페이지 요청 (쿼리 포함)
Page->>Fetch: fetchArticles({ categorySlug, page: N, pageSize })
Fetch->>Strapi: GET /articles?pagination[page]=N&pagination[pageSize]=...
Strapi-->>Fetch: articles + meta.pagination
Fetch-->>Page: { data, meta.pagination }
Page-->>User: 렌더된 아티클 + Pagination
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~28 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 5
🧹 Nitpick comments (4)
src/app/(service)/insights/page.tsx (3)
86-92:cn()유틸리티 사용 일관성 개선Line 88에서 조건부 클래스에 템플릿 리터럴을 사용하고 있으나, Line 100에서는
cn()을 사용하고 있습니다. 코딩 가이드라인에 따라 className 조합 시 항상cn()유틸리티를 사용해야 합니다.♻️ cn() 사용으로 리팩터링
<Link href="/insights" - className={`shrink-0 whitespace-nowrap px-300 pb-200 transition-colors ${ - !selectedCategorySlug - ? 'font-designer-18b border-b-2 border-text-strong text-text-strong' - : 'font-designer-18r text-text-subtle hover:text-text-strong' - }`} + className={cn( + 'shrink-0 whitespace-nowrap px-300 pb-200 transition-colors', + !selectedCategorySlug + ? 'font-designer-18b border-b-2 border-text-strong text-text-strong' + : 'font-designer-18r text-text-subtle hover:text-text-strong', + )} >As per coding guidelines: "Always use
cn()utility for className composition. Never use template literal className strings."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/page.tsx around lines 86 - 92, Replace the template-literal className on the Link component that references selectedCategorySlug with a call to the cn() utility so class composition is consistent; specifically, import/use cn and pass the static classes ("shrink-0 whitespace-nowrap px-300 pb-200 transition-colors") plus a conditional object/ternary for selectedCategorySlug to apply either 'font-designer-18b border-b-2 border-text-strong text-text-strong' or 'font-designer-18r text-text-subtle hover:text-text-strong' — e.g., update the Link's className to use cn(...) and keep the same conditional logic around selectedCategorySlug.
76-76: Tailwind 임의 값 사용
max-w-[1280px]는 Tailwind 임의 값입니다. 프로젝트 학습 내용에 따르면w-7xl이 80rem(1280px)에 해당하는 유효한 Tailwind v4 유틸리티입니다.max-w-7xl사용을 권장합니다.Based on learnings: "In this project, treat 'w-7xl' as a valid Tailwind CSS v4 width utility (from the container scale) equivalent to 80rem (1280px)."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/page.tsx at line 76, Replace the arbitrary Tailwind value in the container div's className: locate the div in src/app/(service)/insights/page.tsx that currently contains "max-w-[1280px]" and change it to the semantic utility "max-w-7xl" (i.e., update the className on that div, preserving the other classes like mx-auto, w-full, px-200, py-400, etc.).
162-162: Tailwind 임의 값 사용
h-[80px],w-[80px],h-[120px],w-[120px]는 Tailwind 임의 값입니다. 프로젝트 디자인 토큰 사용을 권장합니다.As per coding guidelines: "Forbidden: Tailwind arbitrary values (e.g.,
p-[4px],w-[320px]). Use only project custom design tokens."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/page.tsx at line 162, The div using className "rounded-100 relative h-[80px] w-[80px] flex-shrink-0 overflow-hidden sm:h-[120px] sm:w-[120px]" uses Tailwind arbitrary values; replace h-[80px], w-[80px], sm:h-[120px], sm:w-[120px] with the project's design token utility classes (e.g., avatar/spacing tokens or predefined h-/w- classes) so the component in src/app/(service)/insights/page.tsx uses approved tokens; update the className on that div accordingly and verify responsive sizes map to the project's sm-token equivalents.src/app/(service)/insights/weekly/page.tsx (1)
57-57: 하드코딩된 색상 및 임의 값 사용 지양 필요이 파일의 기존 코드에서 코딩 가이드라인 위반이 발견됩니다:
- 하드코딩된 색상:
#181D27,#535862,#D5D7DA,#9CA3AF,#252B37- Tailwind 임의 값:
max-w-[1280px],h-[120px],w-[120px]- 조건부 클래스에 템플릿 리터럴 대신
cn()유틸리티 사용 필요현재 PR 범위는 아니지만, 향후 리팩터링 시 프로젝트 디자인 토큰(
text-text-strong,text-text-subtle,border-border-default등)으로 통일하는 것을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/weekly/page.tsx at line 57, Replace hardcoded hex colors and arbitrary Tailwind values in the JSX container and related elements (e.g., the div with className "mx-auto w-full max-w-[1280px] px-400 py-600" and any elements using h-[120px], w-[120px]) with project design tokens such as text-text-strong, text-text-subtle, border-border-default and standard Tailwind spacing/max-width classes; also swap any conditional className template literals for the cn() utility to compose classes. Locate usages in page.tsx (search for max-w-[1280px], `#181D27`, `#535862`, `#D5D7DA`, `#9CA3AF`, `#252B37`, h-[120px], w-[120px]) and replace them with the appropriate token or token-based Tailwind class and use cn(...) for conditional class construction.
🤖 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/`(service)/insights/ui/blog-detail-page.tsx:
- Around line 359-363: The returned file descriptor currently prefers
fileData.name over fileData.alternativeText, causing file names like
"hero-banner.webp" to be exposed to assistive tech; update the return object in
the function that builds the file descriptor so the display text uses
alternativeText first (e.g., set name to fileData.alternativeText ??
fileData.name ?? ''), and make the same change for the other occurrence
referenced around the second return (the similar block at lines ~390-392) so alt
text is prioritized consistently.
- Around line 468-470: The time element currently shows article.createdAt but
should show the actual publication timestamp; update the UI to use
article.publishedAt (formatted via formatDate) instead of article.createdAt so
the 발행일 label displays the Article.publishedAt value; locate the time element
and replace the reference to createdAt with publishedAt (e.g., use
formatDate(article.publishedAt)) and ensure Article.publishedAt is available
where the component reads article.
- Around line 490-493: The author avatar URL is always prefixed with STRAPI_URL,
which breaks when article.author.avatar.url is already an absolute URL; update
the Image src logic used where article.author.avatar?.url is rendered to detect
absolute URLs (e.g., starts with "http://" or "https://" or protocol-relative
"//") and only prepend STRAPI_URL when the value is a relative path, so the
Image component receives a correct single absolute URL.
- Around line 127-130: 파일의 arbitrary Tailwind 값(text-[13px], rounded-[4px],
text-[`#333d4b`], border-[var(--color-rose-500)], max-w-[740px], px-[24px] 등)을
프로젝트 디자인 토큰으로 교체하세요: blog-detail-page.tsx의 figure/figcaption과 관련된 클래스들을 찾아(예: 해당
<figure> 블록 및 주석된 범위 150-171, 178-287, 295-345, 440-469, 489-506) text-[13px] →
텍스트 토큰(e.g., text-text-*), rounded-[4px] → rounded-150/비슷 토큰, 색상/경계/spacing 직접값
→ `@theme` inline 토큰 또는 p-200/px-200/ max-w-* 커스텀 클래스로 대체하도록 변경하고, 모든 하드코딩된 hex,
arbitrary spacing/width 값을 글로벌 토큰 클래스로 매핑하여 일관된 디자인 토큰만 사용하도록 리팩토링하세요.
- Around line 266-287: The fenced-code renderers (the inline code renderer
"code: ({ children, className }) => { ... }" and the "pre: ({ children }) =>
..." renderer) currently duplicate block styling causing nested boxes and use
forbidden arbitrary Tailwind values and hardcoded hex colors; fix by making
block styles the responsibility of only the pre renderer (detect block via
className?.includes('language-') in the code renderer and for block cases return
a plain <code> without background/padding/overflow), keep inline styling only
for non-block inline code, and replace all arbitrary classes (rounded-[4px],
px-[16px], py-[12px], bg-[`#F6F8FA`], text-[`#333`], etc.) with the project design
tokens / custom tailwind classes (use `@theme` tokens and classes like bg-*,
text-text-*, spacing/rounded token classes) so the pre renderer owns
bg/padding/overflow and the code renderer only handles inline text styling.
---
Nitpick comments:
In `@src/app/`(service)/insights/page.tsx:
- Around line 86-92: Replace the template-literal className on the Link
component that references selectedCategorySlug with a call to the cn() utility
so class composition is consistent; specifically, import/use cn and pass the
static classes ("shrink-0 whitespace-nowrap px-300 pb-200 transition-colors")
plus a conditional object/ternary for selectedCategorySlug to apply either
'font-designer-18b border-b-2 border-text-strong text-text-strong' or
'font-designer-18r text-text-subtle hover:text-text-strong' — e.g., update the
Link's className to use cn(...) and keep the same conditional logic around
selectedCategorySlug.
- Line 76: Replace the arbitrary Tailwind value in the container div's
className: locate the div in src/app/(service)/insights/page.tsx that currently
contains "max-w-[1280px]" and change it to the semantic utility "max-w-7xl"
(i.e., update the className on that div, preserving the other classes like
mx-auto, w-full, px-200, py-400, etc.).
- Line 162: The div using className "rounded-100 relative h-[80px] w-[80px]
flex-shrink-0 overflow-hidden sm:h-[120px] sm:w-[120px]" uses Tailwind arbitrary
values; replace h-[80px], w-[80px], sm:h-[120px], sm:w-[120px] with the
project's design token utility classes (e.g., avatar/spacing tokens or
predefined h-/w- classes) so the component in
src/app/(service)/insights/page.tsx uses approved tokens; update the className
on that div accordingly and verify responsive sizes map to the project's
sm-token equivalents.
In `@src/app/`(service)/insights/weekly/page.tsx:
- Line 57: Replace hardcoded hex colors and arbitrary Tailwind values in the JSX
container and related elements (e.g., the div with className "mx-auto w-full
max-w-[1280px] px-400 py-600" and any elements using h-[120px], w-[120px]) with
project design tokens such as text-text-strong, text-text-subtle,
border-border-default and standard Tailwind spacing/max-width classes; also swap
any conditional className template literals for the cn() utility to compose
classes. Locate usages in page.tsx (search for max-w-[1280px], `#181D27`, `#535862`,
`#D5D7DA`, `#9CA3AF`, `#252B37`, h-[120px], w-[120px]) and replace them with the
appropriate token or token-based Tailwind class and use cn(...) for conditional
class construction.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5306602d-acaf-4d7b-b3aa-618afa40f26e
📒 Files selected for processing (6)
src/api/strapi/api/fetch-articles.tssrc/app/(service)/insights/page.tsxsrc/app/(service)/insights/ui/blog-detail-page.tsxsrc/app/(service)/insights/ui/insights-pagination.tsxsrc/app/(service)/insights/weekly/page.tsxsrc/app/sitemap.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/(service)/insights/ui/blog-detail-page.tsx (1)
60-60:⚠️ Potential issue | 🟡 Minoralt 텍스트 우선순위 수정 필요
resolveMedia함수에서는alternativeText를 우선하도록 수정되었지만, ImageSlider에서는 여전히name을 먼저 사용하고 있습니다. 접근성을 위해 설명 텍스트인alternativeText가 파일명보다 우선되어야 합니다.🔧 제안 코드
<Image src={imageUrl} - alt={file.name || file.alternativeText || 'Slider Image'} + alt={file.alternativeText || file.name || 'Slider Image'} width={800} height={500} className="h-auto w-full object-contain" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/ui/blog-detail-page.tsx at line 60, The ImageSlider alt prop currently prefers file.name over descriptive text; update the alt value in the ImageSlider render to prefer file.alternativeText first (matching resolveMedia behavior), then fall back to file.name and finally a default like 'Slider Image' so accessibility uses the descriptive alternativeText when present.
🧹 Nitpick comments (1)
src/app/(service)/insights/ui/blog-detail-page.tsx (1)
142-159: react-markdown 컴포넌트에 타입 정의 추가 권장Static analysis에서
any타입 사용이 감지되었습니다. react-markdown의Components타입을 활용하면 타입 안전성을 높일 수 있습니다.♻️ 타입 개선 예시
import type { Components } from 'react-markdown'; const MarkdownComponents: Components = { video: ({ src, children }) => { // ... }, img: ({ src, alt }) => { // ... }, // ... };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`(service)/insights/ui/blog-detail-page.tsx around lines 142 - 159, Replace the ad-hoc any typing for the react-markdown custom renderer by declaring a typed Components object from react-markdown and use it for the components prop; specifically, import the Components type and create e.g. const MarkdownComponents: Components = { video: ({ src, children }) => { ... }, img: ({ src, alt }) => { ... } } and then pass MarkdownComponents to ReactMarkdown's components prop so the video renderer (the video: (...) => { ... } implementation) no longer uses any and gains proper typing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/app/`(service)/insights/ui/blog-detail-page.tsx:
- Line 60: The ImageSlider alt prop currently prefers file.name over descriptive
text; update the alt value in the ImageSlider render to prefer
file.alternativeText first (matching resolveMedia behavior), then fall back to
file.name and finally a default like 'Slider Image' so accessibility uses the
descriptive alternativeText when present.
---
Nitpick comments:
In `@src/app/`(service)/insights/ui/blog-detail-page.tsx:
- Around line 142-159: Replace the ad-hoc any typing for the react-markdown
custom renderer by declaring a typed Components object from react-markdown and
use it for the components prop; specifically, import the Components type and
create e.g. const MarkdownComponents: Components = { video: ({ src, children })
=> { ... }, img: ({ src, alt }) => { ... } } and then pass MarkdownComponents to
ReactMarkdown's components prop so the video renderer (the video: (...) => { ...
} implementation) no longer uses any and gains proper typing.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6e71b36c-223d-4e50-8865-85543833fc24
📒 Files selected for processing (1)
src/app/(service)/insights/ui/blog-detail-page.tsx
🌱 연관된 이슈
)하여 자체 스타일링해옴
☘️ 작업 내용
🍀 참고사항
스크린샷 (선택)
Summary by CodeRabbit
New Features
Style
Chores