Skip to content

💄 어드민 성적 관리 페이지 피그마 디자인 반영#421

Merged
manNomi merged 3 commits intomainfrom
investigate/web-build-mentor-login
Feb 14, 2026
Merged

💄 어드민 성적 관리 페이지 피그마 디자인 반영#421
manNomi merged 3 commits intomainfrom
investigate/web-build-mentor-login

Conversation

@manNomi
Copy link
Contributor

@manNomi manNomi commented Feb 14, 2026

Summary

  • 어드민 /scores 페이지를 피그마 시안(노드 4686:30397) 기준의 레이아웃으로 리디자인했습니다.
  • 좌측 관리 메뉴, 상단 탭, 검색/생성 액션, 상태 필터 UI를 시안 구조에 맞춰 구성했습니다.
  • 기존 GPA/어학성적 탭 데이터 흐름은 유지하면서 화면 스타일만 정돈했습니다.

Verification

  • pnpm --filter @solid-connect/admin exec tsc --noEmit
  • pnpm --filter @solid-connect/admin run build
  • pre-push 훅 turbo typecheck 통과

@vercel
Copy link

vercel bot commented Feb 14, 2026

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

Project Deployment Actions Updated (UTC)
solid-connect-web-admin Ready Ready Preview, Comment Feb 14, 2026 1:18pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
solid-connection-web Skipped Skipped Feb 14, 2026 1:18pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Warning

Rate limit exceeded

@manNomi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 25 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

apps/admin/src/routes/scores/index.tsx 파일의 점수 관리 페이지가 단순 컨테이너에서 완전한 관리 인터페이스로 재구성되었습니다. 새로운 기능으로는 왼쪽 사이드바 네비게이션, 상단 탭 컨트롤, 검색 입력, 생성 액션 버튼, 검증 상태 필터(PENDING, APPROVED, REJECTED)가 추가되었습니다. 기존 GPA 및 Language 점수 테이블 컴포넌트는 그대로 유지되며 탭 인터페이스로 통합됩니다. 총 137줄이 추가되고 26줄이 제거되었습니다.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Detailed Changes

1. 레이아웃 구조 개선

- 기존의 단순 점수 컨테이너를 관리 대시보드 레이아웃으로 전환했습니다.
- 왼쪽 사이드바 네비게이션이 추가되어 여러 섹션 간 이동이 가능해졌습니다.
- 상단에 탭 기반 지역 분류 컨트롤이 배치되었습니다.

2. 새로운 UI 컴포넌트 도입

- lucide-react 아이콘 라이브러리(Search, Plus, MapPin)가 임포트되었습니다.
- Button과 Input 컴포넌트가 새로 추가되어 사용자 인터랙션을 강화했습니다.
- cn 유틸리티 함수를 통해 동적 클래스 네이밍이 구현되었습니다.

3. 상태 관리 및 데이터 구조 확장

- searchKeyword 상태가 추가되어 검색 기능을 지원합니다.
- sideMenus 상수로 사이드바 메뉴 항목들을 관리합니다.
- topTabs 상수로 상단 탭 데이터를 구성합니다.

4. 필터 및 검증 상태 관리

- verifyFilter 상태를 통해 PENDING, APPROVED, REJECTED 세 가지 검증 상태를 구분합니다.
- 각 필터 버튼이 활성 상태에 따라 스타일이 동적으로 변경됩니다.
- 검증 상태별 점수 데이터 필터링이 가능해졌습니다.

5. 기능성 개선

- 검색 입력창과 "권역/나라 생성하기" 버튼이 통합되어 사용자 경험이 향상됩니다.
- GPA와 Language 점수 테이블이 탭 인터페이스로 조직되었습니다.
- 기존 라우트 가드는 유지되며 UI 렌더링 로직만 강화되었습니다.
🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (47 files):

⚔️ .husky/pre-commit (content)
⚔️ .husky/pre-push (content)
⚔️ apps/admin/src/routes/scores/index.tsx (content)
⚔️ apps/web/src/apis/Auth/postAppleAuth.ts (content)
⚔️ apps/web/src/apis/Auth/postKakaoAuth.ts (content)
⚔️ apps/web/src/apis/reports/postReport.ts (content)
⚔️ apps/web/src/apis/universities/server/getRecommendedUniversity.ts (content)
⚔️ apps/web/src/apis/universities/server/getSearchUniversitiesByFilter.ts (content)
⚔️ apps/web/src/apis/universities/server/getSearchUniversitiesByText.ts (content)
⚔️ apps/web/src/app/(home)/_ui/NewsSection/index.tsx (content)
⚔️ apps/web/src/app/(home)/_ui/PopularUniversitySection/_ui/PopularUniversityCard.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/CommunityPageContent.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/PostCards.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/[postId]/CommentSection.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/[postId]/Content.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/[postId]/KebabMenu.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/[postId]/PostPageContent.tsx (content)
⚔️ apps/web/src/app/community/[boardCode]/page.tsx (content)
⚔️ apps/web/src/app/mentor/[id]/_ui/MentorDetialContent/_ui/MentorArticle/index.tsx (content)
⚔️ apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_ui/ChatInputBar/index.tsx (content)
⚔️ apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/_ui/ChatMessageBox/index.tsx (content)
⚔️ apps/web/src/app/my/modify/_ui/ModifyContent/_ui/ImageInputFiled/index.tsx (content)
⚔️ apps/web/src/app/my/modify/_ui/ModifyContent/index.tsx (content)
⚔️ apps/web/src/app/university/(home)/_ui/HomeUniversityCard.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/[id]/_ui/UniversityDetail/_ui/LanguageSection.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/[id]/_ui/UniversityDetail/_ui/TitleSection.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/[id]/_ui/UniversityDetail/index.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/search/_ui/SearchPageContent.tsx (content)
⚔️ apps/web/src/app/university/[homeUniversity]/search/page.tsx (content)
⚔️ apps/web/src/app/university/application/apply/DoneStep.tsx (content)
⚔️ apps/web/src/app/university/list/[homeUniversityName]/page.tsx (content)
⚔️ apps/web/src/app/university/score/example/gpa-cert/page.tsx (content)
⚔️ apps/web/src/app/university/score/example/lang-cert/page.tsx (content)
⚔️ apps/web/src/components/home/NewsCards.tsx (content)
⚔️ apps/web/src/components/layout/GlobalLayout/ui/ClientModal/index.tsx (content)
⚔️ apps/web/src/components/login/signup/SignupSurvey.tsx (content)
⚔️ apps/web/src/components/mentor/ArticleBottomSheetModal/index.tsx (content)
⚔️ apps/web/src/components/mentor/MentorApplyCountContent/index.tsx (content)
⚔️ apps/web/src/components/ui/OptimisticImg/index.tsx (content)
⚔️ apps/web/src/components/ui/ProfileWithBadge.tsx (content)
⚔️ apps/web/src/components/ui/ReportPanel/_hooks/useSelectReportHandler.ts (content)
⚔️ apps/web/src/components/ui/ReportPanel/index.tsx (content)
⚔️ apps/web/src/components/ui/UniverSityCard/index.tsx (content)
⚔️ docs/development-workflow.md (content)
⚔️ turbo.json (content)
⚔️ vercel.json (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 변경사항의 핵심(어드민 성적 관리 페이지의 피그마 디자인 반영)을 명확하고 간결하게 요약합니다.
Description check ✅ Passed PR 설명은 주요 작업 내용(피그마 디자인 적용, UI 구성 변경, 데이터 흐름 유지)과 검증 방법을 충분히 포함합니다.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch investigate/web-build-mentor-login

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

@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: 2

🤖 Fix all issues with AI agents
In `@apps/admin/src/routes/scores/index.tsx`:
- Line 29: The searchKeyword state (searchKeyword, setSearchKeyword) is only
bound to the Input but never used by GpaScoreTable or LanguageScoreTable (also
referenced around the block for lines 97-105), leaving the search UI
non-functional; either remove the unused state and Input or wire it through by
passing searchKeyword as a prop to GpaScoreTable and LanguageScoreTable (e.g.,
add a prop like searchKeyword) and update those components to filter their data
or trigger the appropriate API call when the value changes—alternatively, add a
clear TODO comment near the Input and state to indicate intentional future
hookup.
- Around line 31-36: The sideMenus array currently marks the wrong menu as
active; update the sideMenus constant so the item with label "성적 관리" has active:
true and all other items (e.g., the item with label "대학 관리") have active: false.
Locate the sideMenus declaration in this file and flip the active flag
accordingly (ensure the array remains typed as const and the icons/labels are
unchanged).
🧹 Nitpick comments (2)
apps/admin/src/routes/scores/index.tsx (2)

60-74: 3. 사이드바 네비게이션, 상단 탭, 생성 버튼에 인터랙션 로직이 없습니다.

현재 상태:

  • 사이드바 <button> 들은 onClick 핸들러가 없어 클릭해도 페이지 이동이 되지 않습니다.
  • 상단 탭(topTabs)도 활성 상태가 "권역/나라"로 하드코딩되어 있고, 탭 전환 로직이 없습니다.
  • "권역/나라 생성하기" 버튼 역시 onClick이 없습니다.

디자인 시안 반영 목적의 UI 스캐폴딩이라면 이해하지만, 향후 기능 연동 시 누락되지 않도록 TODO 주석이나 disabled 상태를 명시해두시면 협업 시 혼동을 줄일 수 있습니다.

Also applies to: 79-92, 107-113


31-38: 4. sideMenustopTabs 상수를 컴포넌트 바깥으로 추출할 수 있습니다.

이 상수 배열들은 렌더링마다 재생성됩니다. as const로 선언되어 있고 props나 state에 의존하지 않으므로, 컴포넌트 외부(모듈 스코프)로 옮기면 불필요한 재생성을 방지할 수 있습니다.


function ScoresPage() {
const [verifyFilter, setVerifyFilter] = useState<VerifyStatus>("PENDING");
const [searchKeyword, setSearchKeyword] = useState("");
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

2. searchKeyword 상태가 수집만 되고 실제로 사용되지 않습니다.

searchKeywordInput에 바인딩되어 입력값을 추적하지만, GpaScoreTable이나 LanguageScoreTable에 전달되지 않고, 필터링이나 API 호출에도 쓰이지 않아 현재로서는 동작하지 않는 검색 UI입니다. 추후 연동 예정이라면 괜찮지만, 의도를 명확히 남겨두시면 좋겠습니다.

Also applies to: 97-105

🤖 Prompt for AI Agents
In `@apps/admin/src/routes/scores/index.tsx` at line 29, The searchKeyword state
(searchKeyword, setSearchKeyword) is only bound to the Input but never used by
GpaScoreTable or LanguageScoreTable (also referenced around the block for lines
97-105), leaving the search UI non-functional; either remove the unused state
and Input or wire it through by passing searchKeyword as a prop to GpaScoreTable
and LanguageScoreTable (e.g., add a prop like searchKeyword) and update those
components to filter their data or trigger the appropriate API call when the
value changes—alternatively, add a clear TODO comment near the Input and state
to indicate intentional future hookup.

Comment on lines +31 to +36
const sideMenus = [
{ label: "대학 관리", icon: Building2, active: true },
{ label: "멘토 관리", icon: UserCircle2, active: false },
{ label: "유저 관리", icon: UserCircle2, active: false },
{ label: "성적 관리", icon: FileText, active: false },
] as const;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

1. 사이드바 활성 메뉴 항목이 현재 페이지와 불일치합니다.

이 파일은 /scores 라우트(성적 관리 페이지)인데, sideMenus에서 active: true로 설정된 항목은 "대학 관리"입니다. "성적 관리"가 활성화되어야 할 것으로 보입니다.

🐛 수정 제안
 const sideMenus = [
-    { label: "대학 관리", icon: Building2, active: true },
+    { label: "대학 관리", icon: Building2, active: false },
     { label: "멘토 관리", icon: UserCircle2, active: false },
     { label: "유저 관리", icon: UserCircle2, active: false },
-    { label: "성적 관리", icon: FileText, active: false },
+    { label: "성적 관리", icon: FileText, active: true },
 ] as const;
📝 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
const sideMenus = [
{ label: "대학 관리", icon: Building2, active: true },
{ label: "멘토 관리", icon: UserCircle2, active: false },
{ label: "유저 관리", icon: UserCircle2, active: false },
{ label: "성적 관리", icon: FileText, active: false },
] as const;
const sideMenus = [
{ label: "대학 관리", icon: Building2, active: false },
{ label: "멘토 관리", icon: UserCircle2, active: false },
{ label: "유저 관리", icon: UserCircle2, active: false },
{ label: "성적 관리", icon: FileText, active: true },
] as const;
🤖 Prompt for AI Agents
In `@apps/admin/src/routes/scores/index.tsx` around lines 31 - 36, The sideMenus
array currently marks the wrong menu as active; update the sideMenus constant so
the item with label "성적 관리" has active: true and all other items (e.g., the item
with label "대학 관리") have active: false. Locate the sideMenus declaration in this
file and flip the active flag accordingly (ensure the array remains typed as
const and the icons/labels are unchanged).

@vercel vercel bot temporarily deployed to Preview – solid-connection-web February 14, 2026 13:18 Inactive
@manNomi manNomi merged commit bb3735e into main Feb 14, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant