Skip to content

[FIX]: 세션 관리 이미지 순서 관련 버그 수정#229

Closed
JiiminHa wants to merge 4 commits intodevelopfrom
fix/227-session-image
Closed

[FIX]: 세션 관리 이미지 순서 관련 버그 수정#229
JiiminHa wants to merge 4 commits intodevelopfrom
fix/227-session-image

Conversation

@JiiminHa
Copy link
Member

@JiiminHa JiiminHa commented Mar 2, 2026

ISSUE 🔗

close #227


What is this PR? 🔍

이미지 업로드 및 정렬 로직

  • 정렬 로직 개선: 새 이미지에 order 속성을 할당하는 로직이 개선되었습니다. 이제 기존 이미지 중 가장 높은 순서 값을 기준으로 새 번호를 할당하여, 이미지가 삭제되거나 재정렬된 후에도 올바른 위치에 추가되도록 보장합니다.
  • 유연한 스키마 대응: 이미지 업로드 응답 스키마에서 orders3Key 필드를 선택 사항(optional)으로 허용합니다. order 값이 제공되지 않을 경우 기본값 0으로 설정하여 백엔드 통신의 견고함을 높였습니다.
  • 레이아웃 일관성: 캐러셀 너비를 명시적으로 설정하여 레이아웃의 일관성을 개선했습니다.

사용자 경험(UX) 개선 사항

  • 업로드 피드백: "이미지 추가(Add Image)" 버튼은 이제 사용자가 이미지 한도를 초과하려고 할 때 즉각적인 피드백을 제공합니다. 최대 이미지 수(MAX_IMAGES)에 도달하면 알림창을 표시하고 버튼을 시각적으로 비활성화하며, 비활성 상태를 반영하도록 버튼 스타일이 업데이트됩니다.

Screenshot 📷

2026-03-02.5.31.55.mov



Test Checklist ✔

  • 기존에 열린 세션 이미지 추가 삭제 잘되는지 확인
  • 5장 넘어갈 시 alert창 뜨는 거 확인
  • 이미지 4장 넘어갈 시 스크롤바 확인

@JiiminHa JiiminHa added this to the cotato.kr | 🌐 홈페이지 milestone Mar 2, 2026
@JiiminHa JiiminHa self-assigned this Mar 2, 2026
@JiiminHa JiiminHa added 🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정 🥔 HOMEPAGE 코테이토 홈페이지 사이트 관련 작업 labels Mar 2, 2026
@vercel
Copy link

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cotato-fe-v2-homepage Ready Ready Preview, Comment Mar 2, 2026 0:06am
cotato-fe-v2-recruit Error Error Mar 2, 2026 0:06am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04d2135 and 7d3ac7e.

📒 Files selected for processing (2)
  • apps/homepage/src/app/(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx
  • packages/tailwind-config/theme/custom-scrollbar.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/homepage/src/app/(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx

📝 Walkthrough

Summary by CodeRabbit

릴리스 노트

  • 새 기능

    • 이미지 카루셀에 커스텀 스크롤바 스타일 추가
  • 개선 사항

    • 이미지 추가 기능 개선: 최대 개수 도달 시 경고 알림 표시
    • 이미지 순서 지정 로직 개선으로 더 나은 정렬 처리
    • 이미지 추가 시 UI 피드백 강화 (비활성화 상태 시각화)
    • 응답 필드 유연성 향상

Walkthrough

세션 이미지 캐러셀 컴포넌트에서 최대 이미지 개수(5개) 제한을 추가하고, 이미지 순서 계산 로직을 개선하며, 스키마 필드를 선택적으로 변경하고 커스텀 스크롤바 유틸리티를 추가했습니다.

Changes

Cohort / File(s) Summary
캐러셀 UI 및 로직 개선
SessionImageCarouselEdit.tsx, useSessionImageCarousel.tsx
이미지 추가 시 최대 개수 제한 검증 추가; 이미지 순서를 기존 이미지의 최대값 기반으로 계산; currentIndex 업데이트 로직 수정; MAX_IMAGES 상수 공개 내보내기
업로드 응답 스키마
admin-sessions.schema.ts
CompleteImageUploadResponseSchema의 s3Key와 order 필드를 선택적으로 변경 (order는 기본값 0 설정)
스타일 유틸리티
custom-scrollbar.css
세션 캐러셀용 커스텀 scrollbar 유틸리티 추가

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

📷 UI

Suggested reviewers

  • DandelionQZ
  • choyeon2e
  • kimminna
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive 연결된 이슈 #227은 제목만 있고 상세 내용(버그 설명, 발생 상황, 예상 결과)이 비어 있어 요구사항을 명확히 검증하기 어렵습니다. 이슈 #227에 버그 재현 방법, 발생 상황(Given-When-Then), 예상 결과 등의 상세 정보를 입력하여 요구사항을 명시적으로 정의해주세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 세션 관리 이미지 순서 버그 수정이라는 주요 변경사항을 명확하게 요약하고 있으며, 실제 코드 변경과 일치합니다.
Description check ✅ Passed PR 설명은 이미지 업로드 및 정렬 로직 개선, UX 개선사항, 스크린샷, 테스트 체크리스트 등을 포함하여 변경사항과 충분히 관련성 있게 설명되어 있습니다.
Out of Scope Changes check ✅ Passed 모든 코드 변경사항이 이미지 순서 버그 수정과 UX 개선이라는 PR 목표 범위 내에 있으며, 무관한 변경사항은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/227-session-image

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link
Contributor

@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.

🧹 Nitpick comments (3)
apps/homepage/src/app/(with-header)/mypage/admin/sessions/_hooks/useSessionImageCarousel.tsx (1)

64-67: order fallback 처리 및 인덱스 설정 확인 필요

Line 64의 newImage.order ?? nextOrder fallback은 백엔드가 order를 반환하지 않을 경우를 잘 처리합니다.

Line 67의 setCurrentIndex(images.length)는 클로저 특성상 업데이트 전 images 배열 길이를 참조하므로, 새로 추가된 이미지의 인덱스를 올바르게 가리킵니다. (예: 기존 3개 → 새 이미지 인덱스 3)

다만, 이 동작이 의도적임을 명확히 하기 위해 주석을 추가하면 유지보수에 도움이 됩니다.

📝 선택적 주석 추가
          setCurrentIndex(images.length);
+          // images.length는 클로저로 인해 업데이트 전 값을 참조하므로,
+          // 새로 추가된 이미지의 인덱스(0-based)와 일치합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/homepage/src/app/`(with-header)/mypage/admin/sessions/_hooks/useSessionImageCarousel.tsx
around lines 64 - 67, The fallback newImage.order ?? nextOrder correctly handles
missing order from the backend but the intent of using
setCurrentIndex(images.length) (which relies on the pre-update images.length to
point at the newly appended image) is not obvious; add a short clarifying
comment next to the setCurrentIndex(images.length) call explaining that
images.length is intentionally used before state update because the new image is
appended to the end and its index equals the previous length, and mention
newImage.order and nextOrder to show the fallback behavior is deliberate.
apps/homepage/src/app/(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx (1)

141-145: 접근성 개선 제안: disabled 속성 추가

현재 스타일로만 비활성화 상태를 표현하고 있습니다. 스크린 리더 사용자를 위해 disabled 속성을 추가하면 접근성이 향상됩니다.

♿ 접근성 개선 제안
 <button
   type='button'
+  disabled={!canAddMore}
   onClick={() => {
     if (!canAddMore) {
       alert(`이미지는 최대 ${MAX_IMAGES}장까지 추가할 수 있습니다.`);
       return;
     }
     fileInputRef.current?.click();
   }}
   className={`flex h-20 w-20 shrink-0 flex-col items-center justify-center gap-1 rounded-lg border border-dashed ${
     canAddMore
       ? 'cursor-pointer border-neutral-300 bg-neutral-50'
-      : 'cursor-not-allowed border-neutral-300 bg-neutral-50 opacity-50'
+      : 'border-neutral-300 bg-neutral-50 opacity-50 disabled:cursor-not-allowed'
   }`}
   aria-label='이미지 추가'>

참고: WAI-ARIA - Button

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/homepage/src/app/`(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx
around lines 141 - 145, The element using the conditional className in
SessionImageCarouselEdit is only visually disabled; update the interactive
element so it uses a real disabled state: if it’s a <button> set
disabled={!canAddMore} (and keep the existing className logic), otherwise
replace the div with a <button> or add aria-disabled={String(!canAddMore)} plus
role="button" and tabIndex={-1} when !canAddMore; reference the canAddMore
variable and the JSX block with the conditional className to locate where to
apply disabled/aria-disabled.
apps/homepage/src/styles/globals.css (1)

60-81: LGTM! 커스텀 스크롤바 스타일링 잘 추가되었습니다.

Tailwind @layer utilities를 활용한 좋은 패턴입니다. 다만, 하드코딩된 색상값(#737373, #e5e5e5) 대신 Tailwind 테마 색상(neutral-500, neutral-200)을 사용하면 디자인 시스템 일관성이 더 좋아질 수 있습니다.

♻️ 선택적 개선 제안
 `@layer` utilities {
   .custom-scrollbar {
     scrollbar-width: thin;
-    scrollbar-color: `#737373` `#e5e5e5`;
+    scrollbar-color: theme('colors.neutral.500') theme('colors.neutral.200');
   }
 
   .custom-scrollbar::-webkit-scrollbar-track {
-    background: `#e5e5e5`;
+    background: theme('colors.neutral.200');
     border-radius: 10px;
   }
 
   .custom-scrollbar::-webkit-scrollbar-thumb {
-    background-color: `#737373`;
+    background-color: theme('colors.neutral.500');
     border-radius: 10px;
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/homepage/src/styles/globals.css` around lines 60 - 81, Replace the
hardcoded hex colors in the .custom-scrollbar rules with Tailwind theme tokens
so the styles follow the design system: change occurrences of `#737373` to
theme('colors.neutral.500') and `#e5e5e5` to theme('colors.neutral.200') in the
.custom-scrollbar, .custom-scrollbar::-webkit-scrollbar-track, and
.custom-scrollbar::-webkit-scrollbar-thumb selectors (use the Tailwind theme()
helper in your CSS).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/homepage/src/app/`(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx:
- Around line 141-145: The element using the conditional className in
SessionImageCarouselEdit is only visually disabled; update the interactive
element so it uses a real disabled state: if it’s a <button> set
disabled={!canAddMore} (and keep the existing className logic), otherwise
replace the div with a <button> or add aria-disabled={String(!canAddMore)} plus
role="button" and tabIndex={-1} when !canAddMore; reference the canAddMore
variable and the JSX block with the conditional className to locate where to
apply disabled/aria-disabled.

In
`@apps/homepage/src/app/`(with-header)/mypage/admin/sessions/_hooks/useSessionImageCarousel.tsx:
- Around line 64-67: The fallback newImage.order ?? nextOrder correctly handles
missing order from the backend but the intent of using
setCurrentIndex(images.length) (which relies on the pre-update images.length to
point at the newly appended image) is not obvious; add a short clarifying
comment next to the setCurrentIndex(images.length) call explaining that
images.length is intentionally used before state update because the new image is
appended to the end and its index equals the previous length, and mention
newImage.order and nextOrder to show the fallback behavior is deliberate.

In `@apps/homepage/src/styles/globals.css`:
- Around line 60-81: Replace the hardcoded hex colors in the .custom-scrollbar
rules with Tailwind theme tokens so the styles follow the design system: change
occurrences of `#737373` to theme('colors.neutral.500') and `#e5e5e5` to
theme('colors.neutral.200') in the .custom-scrollbar,
.custom-scrollbar::-webkit-scrollbar-track, and
.custom-scrollbar::-webkit-scrollbar-thumb selectors (use the Tailwind theme()
helper in your CSS).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e17812f and 04d2135.

📒 Files selected for processing (4)
  • apps/homepage/src/app/(with-header)/mypage/admin/sessions/_components/carousel/SessionImageCarouselEdit.tsx
  • apps/homepage/src/app/(with-header)/mypage/admin/sessions/_hooks/useSessionImageCarousel.tsx
  • apps/homepage/src/schemas/admin/admin-sessions.schema.ts
  • apps/homepage/src/styles/globals.css

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

Labels

🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정 🥔 HOMEPAGE 코테이토 홈페이지 사이트 관련 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX]: 세션 관리 이미지 순서 관련 버그 수정

1 participant