Skip to content

feat: qa 반영 및 pwq 추가#70

Merged
dasosann merged 1 commit into
mainfrom
feat/admin-list
May 19, 2026
Merged

feat: qa 반영 및 pwq 추가#70
dasosann merged 1 commit into
mainfrom
feat/admin-list

Conversation

@dasosann
Copy link
Copy Markdown
Contributor

No description provided.

@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@dasosann dasosann merged commit 8fc928c into main May 19, 2026
2 checks passed
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 풀 리퀘스트는 관리자용 사용자 관리 기능(조회, 검색, 티켓 수량 조정) 신설과 PWA 지원을 위한 서비스 워커 및 매니페스트 설정을 주된 내용으로 합니다. 리뷰 결과, 700줄에 달하는 AdminMembers 컴포넌트를 스타일 가이드에 따라 분리하고, 아이콘 버튼에 aria-label을 추가하여 접근성을 개선할 것이 권장되었습니다. 또한 티켓 조정 시 Promise.allSettled를 통한 안정적인 비동기 처리와 서비스 워커의 캐싱 전략 최적화, 그리고 에러 메시지 표시 방식에 대한 개선 의견이 제시되었습니다.

AlertTriangle,
} from "lucide-react";

export default function AdminMembers() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

이 컴포넌트 파일은 현재 약 700줄에 달하며, 특히 모달 내부의 복잡한 로직이 포함되어 있어 가독성과 유지보수성이 떨어집니다. 저장소 스타일 가이드(71번 항목)에 따라, 수량 조정 모달 부분을 별도의 컴포넌트(예: AdminMemberAdjustModal.tsx)로 분리할 것을 강력히 권장합니다.

References
  1. 컴포넌트 파일이 200줄을 초과하면 더 작은 서브 컴포넌트로 분리할 것을 권장합니다. (link)

className="w-full rounded-xl border border-[#1e2030] bg-[#161827] py-2.5 pr-10 pl-10 text-sm text-white placeholder-[#4a4e69] transition-all duration-200 focus:border-[#06b6d4]/50 focus:bg-[#161827] focus:outline-none"
/>
{searchInput && (
<button
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

아이콘만 포함된 버튼에는 스크린 리더 사용자를 위한 aria-label 속성이 필요합니다. 스타일 가이드(78번 항목)를 준수하여 접근성을 개선해 주세요.

Suggested change
<button
<button
type="button"
onClick={handleClearSearch}
className="absolute top-1/2 right-3.5 -translate-y-1/2 text-[#4a4e69] transition-colors hover:text-white"
aria-label="검색어 초기화"
>
References
  1. 아이콘 전용 버튼의 aria-label 확인 (link)

<h2 className="text-base font-bold text-white sm:text-lg">
아이템 수량 조정
</h2>
<button
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

모달 닫기 버튼과 같이 아이콘만 있는 버튼에는 aria-label을 추가하여 웹 접근성 표준을 준수해야 합니다.

Suggested change
<button
<button
onClick={closeEditModal}
className="rounded-lg p-1 text-[#6b7094] transition-colors hover:bg-[#1e2030] hover:text-white"
aria-label="모달 닫기"
>
References
  1. 아이콘 전용 버튼의 aria-label 확인 (link)

Comment on lines +160 to +164
showToast({
title: "조정 실패",
body: bodyMsg,
icon: "error",
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

일반 규칙에 따라, 에러 메시지를 표시할 때는 토스트 알림 대신 브라우저 네이티브 alert() 함수를 사용하는 것이 권장됩니다.

      alert("조정 실패: " + bodyMsg);
References
  1. Prefer using the native alert() function for displaying error messages instead of toast notifications.

}

try {
await Promise.all(promises);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

두 가지 아이템(매칭권, 옵션권)을 동시에 수정할 때 Promise.all을 사용하면 하나라도 실패할 경우 전체가 실패로 처리되거나, 부분적인 성공 상태를 사용자에게 명확히 알리기 어렵습니다. Promise.allSettled를 사용하여 각 요청의 결과를 개별적으로 처리하고 적절한 피드백을 제공하는 것이 더 안전합니다.

Comment thread public/sw.js
Comment on lines +31 to +52
self.addEventListener("fetch", (event) => {
if (event.request.method !== "GET") return;

// Do not intercept FCM route or API calls
if (
event.request.url.includes("/api/") ||
event.request.url.includes("firebase")
) {
return;
}

event.respondWith(
caches.match(event.request).then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}
return fetch(event.request).catch(() => {
// Offline fallback could go here
});
}),
);
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

현재 서비스 워커의 fetch 핸들러는 모든 GET 요청에 대해 캐시 우선 전략을 사용하고 있습니다. 이는 Next.js의 동적 페이지나 자주 변경되는 정적 자산에 대해 의도치 않은 캐싱 문제를 일으킬 수 있습니다. API와 Firebase 경로는 제외되어 있지만, HTML 문서나 특정 정적 파일에 대해서는 네트워크 우선(Network First) 또는 Stale-While-Revalidate 전략을 고려해 보세요.

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