Skip to content

nextjs 에러 대응#63

Merged
basilry merged 3 commits intomasterfrom
dev
Dec 8, 2025
Merged

nextjs 에러 대응#63
basilry merged 3 commits intomasterfrom
dev

Conversation

@basilry
Copy link
Copy Markdown
Owner

@basilry basilry commented Dec 8, 2025

Summary by CodeRabbit

  • 신기능

    • 신규 프로젝트 페이지 추가: Haru Weather, Push Server
    • 프로젝트 목록 데이터에 새 항목 추가 및 기존 항목의 링크 갱신
  • 업데이트

    • Next.js 관련 의존성 업그레이드 (v15 → v16)
    • 토스트 알림 자동 종료 시간 약 10초로 연장
  • 개선사항

    • TypeScript 설정 정리 및 빌드 관련 옵션 보강
    • 토스트 스타일 폰트 크기 조정
  • 기타

    • 크롤러 접근 차단을 위한 robots 규칙 추가

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 8, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Next.js 의존성(@next/third-parties, next)을 ^15.3.4에서 ^16.0.7로 업그레이드하고, 두 개의 새로운 프로젝트 상세 페이지 컴포넌트(HaruWeather, PushServer) 및 해당 라우트를 추가했습니다. 프로젝트 메타 데이터(mainProjects.json)와 TypeScript 설정(tsconfig.json)을 확장하고, Toast 관련 스타일과 동작(src/styles/toast.scss, src/app/layout.tsx)을 변경했으며 robots.txt를 새로 추가했습니다.

Changes

Cohort / File(s) Change Summary
의존성 업그레이드
package.json
@next/third-partiesnext 버전을 ^15.3.4^16.0.7로 업데이트
HaruWeather 프로젝트 페이지
src/app/(contents)/projects/haruWeather/HaruWeather.tsx, src/app/(contents)/projects/haruWeather/page.tsx
HaruWeather 상세 컴포넌트 추가 및 페이지 라우트 등록 (default export)
PushServer 프로젝트 페이지
src/app/(contents)/projects/pushServer/PushServer.tsx, src/app/(contents)/projects/pushServer/page.tsx
PushServer 상세 컴포넌트 추가 및 페이지 라우트 등록 (default export)
프로젝트 데이터 업데이트
src/lib/json/mainProjects.json
HaruWeather 항목 추가(id:9), 푸시서버 항목(URL) 업데이트, 일부 로고 높이 조정
Toast 및 레이아웃 설정
src/app/layout.tsx, src/styles/toast.scss
ToastContainer autoClose를 1800ms → 9999ms로 변경; .Toastify { font-size: $small-font; } 규칙 추가
TypeScript 구성 변경
tsconfig.json
paths, lib 포맷을 다중라인으로 정리, jsx 런타임을 preservereact-jsx로 변경, 여러 컴파일러 옵션(예: forceConsistentCasingInFileNames, noEmit, esModuleInterop, module, moduleResolution) 추가
크롤러 차단 파일
robots.txt
여러 User-agent에 대해 Disallow: / 규칙을 추가 (파일 최종 줄에 개행 없음)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 새로 추가된 프로젝트 페이지 두 파일은 구조가 유사하므로 빠르게 확인 가능.
  • tsconfig.json의 컴파일러 옵션 및 jsx 변경이 빌드/타입 체크에 미치는 영향 점검 필요.
  • package.json의 Next.js 메이저 업그레이드가 런타임 호환성(특히 app 디렉토리/랜타임 변경)에 미칠 영향 검토 권장.
  • robots.txt의 광범위한 크롤러 차단 의도 확인 필요.

Possibly related PRs

  • [update] ga 추가 #58 — 동일한 package.json 의존성(next, @next/third-parties) 버전 변경을 포함하므로 관련성 높음.

Poem

🐰 새벽 들판에 코드가 피어나네,
버전은 높아지고 페이지가 늘고,
토스트는 오래 머물러 반짝이고,
타입은 까다로워져도 우린 껑충,
당근 한 입에 배포를 축하하네 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive Pull request title '에러 대응' is vague and generic, not describing specific changes clearly. While it mentions 'nextjs', it lacks concrete detail about what error was addressed or what the actual changes accomplish. Change title to specify the main change, such as 'Upgrade Next.js to v16 and add new project pages' or 'Fix Next.js compatibility issues and add HaruWeather/PushServer projects'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7cf4c2a and 1d085e8.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json (2 hunks)
  • robots.txt (1 hunks)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@basilry basilry merged commit cce9086 into master Dec 8, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
package.json (1)

57-63: Next 16.0.7 보안 패치 적용은 적절하지만, React/Node/서드파티 버전 정합성 점검이 필요합니다

  • Next 보안 공지 기준으로 15.x/16.x App Router RCE 이슈(CVE-2025-66478)는 16.0.7에서 패치되므로, 15.3.4 → 16.0.7 업그레이드는 방향 자체는 매우 적절합니다.(nextjs.org)
  • 다만 Next 16은 최소 Node 20.9.0+, TypeScript 5.1+를 요구하므로(현재 TS 5.2.2는 OK), 로컬/서버/CI Node 버전이 20.9 이상인지 한 번 확인해 두는 편이 안전합니다.(nextjs.org)
  • Next 16 공식 가이드는 next@latest로 올릴 때 react, react-dom도 함께 최신으로 올릴 것을 권장합니다. 현재 여전히 react/react-dom이 18.2.0인 상태라, 의존성 해상 결과에 따라 React 18/19가 섞여 로딩되거나 경고가 발생할 여지가 있습니다. (예: npm install next@latest react@latest react-dom@latest 예시).(nextjs.org)
  • @next/third-parties 역시 공식 문서에서 항상 @next/third-parties@latest next@latest 조합으로 설치하라고 권장하고 있어, Next를 16.x로 올린 김에 해당 패키지도 최신 버전으로 정렬하는 것을 추천드립니다.(nextjs.org)
  • Next 16에서는 cookies(), headers(), draftMode, params, searchParams 등 Request API의 동기 접근이 완전히 제거되어 비동기 API만 허용되므로, 기존 코드에서 이들 API를 사용 중이면 한 번 전역 검색 후 마이그레이션 여부를 확인해 보시는 게 좋습니다.(nextjs.org)

위 네 가지(React/ReactDOM 버전, Node 런타임 버전, @next/third-parties 버전, Request API 사용처)는 실제 환경에서 next build / next start를 돌려 보면서 경고나 에러가 없는지 꼭 한 번 검증해 주세요.

tsconfig.json (1)

1-66: tsconfig 확장은 전반적으로 Next 권장 설정과 잘 맞지만, target/jsx 값은 한 번 점검해 보는 것을 추천드립니다

  • paths 정리, noEmit: true, module: "esnext", moduleResolution: "node", resolveJsonModule, isolatedModules 등은 Next + TS 환경에서 일반적으로 권장되는 설정이라 방향이 좋습니다.
  • include".next/types/**/*.ts"가 들어가 있고, next-env.d.ts, **/*.ts, **/*.tsx를 포함하는 구조는 Next 공식 TypeScript 문서에서 링크/라우트 타입 생성을 위해 안내하는 패턴과 일치합니다.(nextjs.org)
  • 다만 Next 16 최소 런타임이 Node 20.9+ 및 최신 브라우저(Chrome/Edge/Firefox 111+, Safari 16.4+) 기준이라, 타입 시스템 관점에서도 target: "es5" 대신 "es2020" 또는 "esnext" 정도로 올려 두는 편이 더 현실 환경에 가깝고, 최신 JS 내장 객체/메서드에 대한 타입 추론도 좋아집니다. (실제 JS 출력은 SWC가 담당하고 noEmit: true라 빌드에는 영향이 없고 타입 정의에만 영향을 줍니다.)(nextjs.org)
  • "jsx": "react-jsx"는 Next가 기본적으로 생성하는 tsconfig.json"jsx": "preserve"와는 다른 값입니다. noEmit: true인 만큼 SWC 번들 결과에는 직접 영향이 없겠지만, tsc --noEmit를 별도로 돌리거나 에디터에서 타입스크립트 언어 서비스를 사용할 때 JSX 처리 방식이 Next 가이드와 달라질 수 있습니다. 공식 예제와 맞추고 싶다면 "jsx": "preserve"로 되돌리는 것도 한 가지 옵션입니다.(nextjs.org)

요약하면 현재 설정도 동작에는 큰 문제 없을 가능성이 높지만,

  1. target을 최소 ES2020 이상으로 상향,
  2. jsx를 유지할지/preserve로 되돌릴지 결정한 뒤 next buildtsc --noEmit를 한 번씩 돌려 경고나 타입 에러가 없는지 확인해 보시는 것을 권장드립니다.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3655e7b and 7cf4c2a.

⛔ Files ignored due to path filters (5)
  • package-lock.json is excluded by !**/package-lock.json
  • public/skills/vercel.png is excluded by !**/*.png
  • public/skills/vite.png is excluded by !**/*.png
  • public/skills/vue.png is excluded by !**/*.png
  • public/test.svg is excluded by !**/*.svg
📒 Files selected for processing (9)
  • package.json (1 hunks)
  • src/app/(contents)/projects/haruWeather/HaruWeather.tsx (1 hunks)
  • src/app/(contents)/projects/haruWeather/page.tsx (1 hunks)
  • src/app/(contents)/projects/pushServer/PushServer.tsx (1 hunks)
  • src/app/(contents)/projects/pushServer/page.tsx (1 hunks)
  • src/app/layout.tsx (1 hunks)
  • src/lib/json/mainProjects.json (2 hunks)
  • src/styles/toast.scss (1 hunks)
  • tsconfig.json (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/app/(contents)/projects/pushServer/PushServer.tsx (2)
src/lib/stores/store.ts (1)
  • useCoreStore (6-15)
src/app/(contents)/projects/Projects.tsx (1)
  • ReactElement (15-73)
src/app/(contents)/projects/pushServer/page.tsx (10)
src/app/(contents)/projects/imsPart1/page.tsx (1)
  • JSX (3-5)
src/app/(contents)/projects/ltcga/page.tsx (1)
  • ReactElement (4-6)
src/app/(contents)/projects/page.tsx (1)
  • JSX (3-5)
src/app/(contents)/donate/page.tsx (1)
  • JSX (1-3)
src/app/(contents)/notice/page.tsx (1)
  • JSX (1-3)
src/app/(contents)/projects/hectonTechblog/page.tsx (1)
  • JSX (3-5)
src/app/(contents)/visitor/page.tsx (1)
  • JSX (3-5)
src/app/login/page.tsx (1)
  • Page (4-6)
src/app/(mydata)/research/page.tsx (1)
  • ReactElement (4-6)
src/app/(mydata)/certification/page.tsx (1)
  • ReactElement (4-6)
src/app/(contents)/projects/haruWeather/HaruWeather.tsx (1)
src/lib/stores/store.ts (1)
  • useCoreStore (6-15)
🔇 Additional comments (9)
src/styles/toast.scss (1)

3-5: Toast 전역 폰트 사이즈 설정은 자연스러워 보입니다

루트 .Toastify$small-font를 지정해서 라이브러리 기본값을 맞춰주는 방향은 괜찮아 보입니다. 이미 .Toastify__toast-body에 동일한 크기가 적용되어 있어서 실제 텍스트 크기는 크게 변하지 않을 것이지만, 제목/버튼 등 다른 요소에 미세한 레이아웃 변화가 있을 수 있으니 실제 토스트를 띄워서 모바일/데스크톱에서 한 번씩만 눈으로 확인해 보시면 좋겠습니다.

src/app/layout.tsx (1)

56-59: Toast autoClose 9999ms 설정이 UX 의도와 맞는지 한 번만 확인해 주세요

이제 토스트가 약 10초 동안 유지되기 때문에, 알림을 충분히 읽을 수 있다는 장점은 있지만 짧은 알림이 자주 뜨는 화면에서는 오래 남아서 시야를 가릴 수도 있습니다. “조금 더 오래 보이지만 결국은 자동으로 사라지는” 것이 의도였다면 현재 값으로 충분해 보이고, 사실상 수동 닫기를 원했다면 autoClose={false} 도 고려해 볼 수 있습니다. 실제 사용 시나리오(모바일/데스크톱 모두) 기준으로 한번 UX를 점검해 주세요.

src/app/(contents)/projects/haruWeather/page.tsx (1)

1-8: HaruWeather page 래퍼 구성은 기존 라우트 패턴과 잘 맞습니다

HaruWeather를 별도 page 컴포넌트로 감싸서 기본 export 하는 구조가 다른 (contents)/projects/*/page.tsx들과 일관되고, 타입도 ReactElement로 명시되어 있어 유지보수 측면에서도 무난합니다.

src/app/(contents)/projects/pushServer/page.tsx (1)

1-9: PushServer page 추가도 기존 구조와 일관되고, 프로젝트 리스트 URL과 잘 연결됩니다

PushServerpage 컴포넌트로 감싸서 기본 export 하는 패턴이 다른 페이지들과 동일하고, src/lib/json/mainProjects.json에서 id 8의 url/projects/pushServer로 지정해 둔 부분과도 라우트 경로가 정확히 일치합니다. 이 상태라면 프로젝트 목록에서 해당 항목 클릭 시 이 페이지로 자연스럽게 연결될 것으로 보입니다.

src/lib/json/mainProjects.json (1)

56-60: 프로젝트 메타데이터 변경 내용이 라우트/페이지들과 잘 정합됩니다

  • id 3의 logos[1].height를 30→20으로 줄인 변경은 순수하게 시각적 조정이라 데이터 구조나 기능 측면 문제는 없어 보입니다.
  • id 8 "또하나의가족, 플랫폼 고도화 - 푸시서버 구축"url"/projects/pushServer"로 설정한 부분은 새로 추가된 src/app/(contents)/projects/pushServer/page.tsx 라우트와 정확히 매칭됩니다.
  • 새 id 9 "Haru Weather" 항목 역시 url: "/projects/haruWeather"로 설정되어 있고, 해당 경로에 haruWeather/page.tsx가 존재하므로 프로젝트 리스트 → 상세 페이지 네비게이션이 자연스럽게 동작할 것으로 보입니다.

전체적으로 JSON 구조와 라우트 구조가 잘 맞춰져 있어서, 이 파일 변경은 그대로 승인해도 무방해 보입니다.

Also applies to: 150-166

src/app/(contents)/projects/pushServer/PushServer.tsx (4)

1-12: 임포트 구문은 적절합니다.

클라이언트 컴포넌트 지시어와 필요한 의존성들이 올바르게 임포트되어 있습니다.


180-191: 중첩된 TextBasic 컴포넌트 구조를 검토하세요.

라인 182-190에서 TextBasic 컴포넌트 내부에 다른 TextBasic 컴포넌트들이 중첩되어 있습니다. 이 구조가 의도된 것인지 확인이 필요합니다. 일반적으로 리스트 아이템은 별도의 요소로 렌더링하는 것이 더 적절합니다.

다음과 같이 구조를 개선하는 것을 고려하세요:

-                        <TextBasic size="small">
-                            {"  - 총 3가지 로직 개발"}
-                            <TextBasic size="small">
-                                {"1) 한 번이라도 요양상담의 답변을 받은 유저에게 매주 월요일 대량발송"}
-                            </TextBasic>
-                            <TextBasic size="small">
-                                {"2) 요양상담을 접수하지 않고 이탈한 사용자에게 익일 대량발송"}
-                            </TextBasic>
-                            <TextBasic size="small">
-                                {"3) 한 주 간 조회수가 가장 높았던 요양정보를 금요일에 일괄발송"}
-                            </TextBasic>
-                        </TextBasic>
+                        <TextBasic size="small">{"  - 총 3가지 로직 개발"}</TextBasic>
+                        <TextBasic size="small">
+                            {"1) 한 번이라도 요양상담의 답변을 받은 유저에게 매주 월요일 대량발송"}
+                        </TextBasic>
+                        <TextBasic size="small">
+                            {"2) 요양상담을 접수하지 않고 이탈한 사용자에게 익일 대량발송"}
+                        </TextBasic>
+                        <TextBasic size="small">
+                            {"3) 한 주 간 조회수가 가장 높았던 요양정보를 금요일에 일괄발송"}
+                        </TextBasic>

36-147: All image files referenced in the component exist in the public directory. No missing files detected.

Likely an incorrect or invalid review comment.


1-1: > Likely an incorrect or invalid review comment.

Comment on lines +37 to +38
<img src="/myFace.png" alt="logo" width={30} height={30} />
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's read the HaruWeather.tsx file to understand its content
cat -n src/app/\(contents\)/projects/haruWeather/HaruWeather.tsx

Repository: basilry/kbslBlog

Length of output: 10778


🏁 Script executed:

# Let's verify the PicsTemplate to understand what solutionPics vs haruWeatherPics would be
find . -type f -name "PicsTemplate*" | head -20

Repository: basilry/kbslBlog

Length of output: 106


🏁 Script executed:

cat -n src/app/\(contents\)/projects/PicsTemplate.tsx | head -100

Repository: basilry/kbslBlog

Length of output: 2210


🏁 Script executed:

# Check what pic directories exist to confirm naming pattern
find . -type d -name "*Pics" -o -name "*pics" | grep -v node_modules

Repository: basilry/kbslBlog

Length of output: 175


🏁 Script executed:

# Check other projects to understand the domain naming pattern
ls -la public/solutionPics/ | head -20

Repository: basilry/kbslBlog

Length of output: 805


HaruWeather 상세 내용과 이미지 경로에서 Solution 프로젝트로부터의 복붙 흔적이 있으며, 접근성 이슈가 여러 곳에 있습니다

  • "설명"과 "포지션" 섹션은 Haru Weather(개인 사이드 프로젝트, OpenWeather API, Vue3/Vite)에 맞게 작성되어 있으나, "프로젝트 인원"(F/E: 4명, B/E: 2명)과 "성과" 섹션의 "프로젝트 관리자 시스템 개발", "총 84개 페이지 중 31개 신규 페이지", "AWS EC2/ELB 관리" 등의 내용은 기존 Solution 프로젝트 설명을 그대로 복붙한 것으로 보입니다. 포트폴리오 독자의 혼동을 피하려면, 이 부분을 Haru Weather에서 실제로 얻은 성과나 배운 점으로 다시 작성해 주시기 바랍니다.

  • 사용스택 섹션의 기술 아이콘들(vite, vue, typescript, sass, prettier, eslint, vercel)의 alt 속성이 모두 "myFace"로 설정되어 있으며, 상단 로고 이미지도 alt="logo"로 되어 있습니다. 스크린리더 접근성을 위해 실제 기술 이름(예: "vite", "vue", "TypeScript")으로 변경해 주세요.

  • 이미지 영역에서 PicsTemplate filePath={"solutionPics"} domainName={"sol"}를 사용하고 있는데, 이는 Solution 프로젝트용 리소스입니다. 현재 설정으로는 /solutionPics/sol1.png 형태의 Solution 프로젝트 스크린샷을 불러오게 되므로, Haru Weather 전용 이미지 세트를 별도로 준비하고 filePath/domainName을 적절히 수정해 주시기 바랍니다.

🤖 Prompt for AI Agents
In src/app/(contents)/projects/haruWeather/HaruWeather.tsx around lines 37–38,
the file contains leftover Solution-project content and accessibility issues:
replace any copied "프로젝트 인원" and "성과" text with Haru Weather–specific
team/impact/learned-items (or remove if not applicable), update all image alt
attributes (logo and tech icons) from generic values like "logo" or "myFace" to
the actual names (e.g., "Haru Weather logo", "Vite", "Vue 3", "TypeScript",
"Sass", "Prettier", "ESLint", "Vercel") for screen-reader accessibility, and
change the PicsTemplate props (filePath/domainName) from the Solution values
("solutionPics"/"sol") to Haru Weather–specific ones (e.g., "haruPics"/"haru" or
appropriate folder names) so the component loads Haru Weather screenshots
instead of Solution images.

Comment on lines +18 to +25
<div className={styles.list}>
<Link href={"/projects"} className={classNames(styles.link, darkMode && styles.dark)}>
<img src={`/${darkMode ? "link_white" : "link"}.svg`} alt={"link"} width={15} />
<TextBasic size={"medium"} bold={"bold"}>
프로젝트 목록
</TextBasic>
</Link>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Next.js Image 컴포넌트를 일관되게 사용하세요.

라인 20에서 <img> 태그를 사용하고 있는데, 라인 37에서는 Next.js의 Image 컴포넌트를 사용하고 있습니다. 성능 최적화와 자동 이미지 최적화를 위해 Next.js의 Image 컴포넌트를 일관되게 사용하는 것이 좋습니다.

다음과 같이 수정하세요:

-                    <img src={`/${darkMode ? "link_white" : "link"}.svg`} alt={"link"} width={15} />
+                    <Image src={`/${darkMode ? "link_white" : "link"}.svg`} alt={"link"} width={15} height={15} />
📝 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.

Suggested change
<div className={styles.list}>
<Link href={"/projects"} className={classNames(styles.link, darkMode && styles.dark)}>
<img src={`/${darkMode ? "link_white" : "link"}.svg`} alt={"link"} width={15} />
<TextBasic size={"medium"} bold={"bold"}>
프로젝트 목록
</TextBasic>
</Link>
</div>
<div className={styles.list}>
<Link href={"/projects"} className={classNames(styles.link, darkMode && styles.dark)}>
<Image src={`/${darkMode ? "link_white" : "link"}.svg`} alt={"link"} width={15} height={15} />
<TextBasic size={"medium"} bold={"bold"}>
프로젝트 목록
</TextBasic>
</Link>
</div>

<TextBasic size="xxx-large" bold="bold">
{"또하나의가족, 플랫폼 전반 핑거푸시 외부 API 연동 및 로직 개발"}
</TextBasic>
<br />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

CSS 마진을 사용하여 간격을 조정하는 것을 고려하세요.

여러 위치에서 <br /> 태그를 사용하여 수직 간격을 조정하고 있습니다. 유지보수성과 일관성을 위해 CSS 마진이나 패딩을 사용하는 것이 더 좋습니다.

예를 들어, 스타일 모듈에 다음과 같은 클래스를 추가할 수 있습니다:

.sectionSpacing {
  margin-bottom: 1.5rem;
}

.paragraphSpacing {
  margin-bottom: 2rem;
}

그리고 컴포넌트에서 다음과 같이 사용하세요:

<div className={styles.sectionSpacing}>
  <TextBasic size="large" bold="bold">
    {"설명"}
  </TextBasic>
  {/* ... */}
</div>

Also applies to: 41-41, 52-53, 60-61, 149-150, 156-157, 176-176, 192-192, 201-201

Comment on lines +35 to +38
<div className={styles.logos}>
<img src="/hecton.png" alt="logo" width={30} height={20} />
<Image src="/ddoga_logo.svg" alt="logo" width={120} height={30} />
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

이미지 컴포넌트 사용을 통일하세요.

라인 36에서 <img> 태그를 사용하고 라인 37에서 Next.js Image 컴포넌트를 사용하는 등 일관성이 없습니다. 모든 이미지에 대해 Next.js Image 컴포넌트를 사용하여 최적화 혜택을 받으세요.

다음과 같이 수정하세요:

-                        <img src="/hecton.png" alt="logo" width={30} height={20} />
+                        <Image src="/hecton.png" alt="logo" width={30} height={20} />
📝 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.

Suggested change
<div className={styles.logos}>
<img src="/hecton.png" alt="logo" width={30} height={20} />
<Image src="/ddoga_logo.svg" alt="logo" width={120} height={30} />
</div>
<div className={styles.logos}>
<Image src="/hecton.png" alt="logo" width={30} height={20} />
<Image src="/ddoga_logo.svg" alt="logo" width={120} height={30} />
</div>
🤖 Prompt for AI Agents
In src/app/(contents)/projects/pushServer/PushServer.tsx around lines 35 to 38,
the code mixes a native <img> tag and Next.js Image component; replace the
native <img> with Next.js Image for consistency and optimization. Import Image
from 'next/image' if not already imported, swap the <img src="/hecton.png"
alt="logo" width={30} height={20} /> with an Image component using the same src,
alt, width and height props, and ensure any parent styling still applies (or
adjust className) so the image renders correctly.

Comment on lines +66 to +147
<img
className={styles.skillImgs}
src="/skills/typescript.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/nextjs.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/sass.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/zustand.png"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/prettier.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/eslint.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/mysql.png"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/aws.svg"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
</div>
<div>
<img
className={styles.skillImgs}
src="/skills/nodejs.png"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
<img
className={styles.skillImgs}
src="/skills/expressjs.png"
alt="myFace"
sizes={"100vw"}
width={60}
height={60}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

잘못된 alt 텍스트를 수정하고 코드 중복을 제거하세요.

모든 스킬 이미지의 alt 텍스트가 "myFace"로 설정되어 있는데, 이는 접근성 측면에서 심각한 문제입니다. 각 이미지는 "TypeScript", "Next.js", "SASS" 등 실제 기술 이름을 alt 텍스트로 가져야 합니다.

또한, 동일한 패턴의 이미지 렌더링 코드가 반복되고 있어 유지보수가 어렵습니다.

해결 방법 1: 데이터 기반 접근 방식으로 리팩토링

컴포넌트 상단에 스킬 데이터를 정의하세요:

const skills = [
    { src: "/skills/typescript.svg", alt: "TypeScript" },
    { src: "/skills/nextjs.svg", alt: "Next.js" },
    { src: "/skills/sass.svg", alt: "SASS" },
    { src: "/skills/zustand.png", alt: "Zustand" },
    { src: "/skills/prettier.svg", alt: "Prettier" },
    { src: "/skills/eslint.svg", alt: "ESLint" },
    { src: "/skills/mysql.png", alt: "MySQL" },
    { src: "/skills/aws.svg", alt: "AWS" },
]

const backendSkills = [
    { src: "/skills/nodejs.png", alt: "Node.js" },
    { src: "/skills/expressjs.png", alt: "Express.js" },
]

그리고 렌더링 부분을 다음과 같이 변경하세요:

-                        <div>
-                            <img
-                                className={styles.skillImgs}
-                                src="/skills/typescript.svg"
-                                alt="myFace"
-                                sizes={"100vw"}
-                                width={60}
-                                height={60}
-                            />
-                            {/* ... 반복되는 img 태그들 ... */}
-                        </div>
+                        <div>
+                            {skills.map((skill) => (
+                                <Image
+                                    key={skill.src}
+                                    className={styles.skillImgs}
+                                    src={skill.src}
+                                    alt={skill.alt}
+                                    width={60}
+                                    height={60}
+                                />
+                            ))}
+                        </div>
+                        <div>
+                            {backendSkills.map((skill) => (
+                                <Image
+                                    key={skill.src}
+                                    className={styles.skillImgs}
+                                    src={skill.src}
+                                    alt={skill.alt}
+                                    width={60}
+                                    height={60}
+                                />
+                            ))}
+                        </div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant