Skip to content

feat: 지원자 현황 확인 디자인 구현#596

Merged
manNomi merged 1 commit into
mainfrom
feat/application-status-design
Jul 6, 2026
Merged

feat: 지원자 현황 확인 디자인 구현#596
manNomi merged 1 commit into
mainfrom
feat/application-status-design

Conversation

@manNomi

@manNomi manNomi commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

  • 없음

작업 내용

  • 지원자 현황 확인 목록 화면을 Figma flow 1 기준으로 재구성했습니다.
    • 지원한 대학 영역, 성적 공유 참여 배너, 전체/지원자 있는 대학 탭, 권역/학점 필터 칩을 추가했습니다.
    • 대학별 지원자 현황 카드를 펼침/접힘 구조로 정리하고, 상세 페이지로 이동할 수 있게 했습니다.
  • 지원자 현황 대학 상세 화면을 Figma flow 2 기준으로 추가했습니다.
    • 대학 상세와 같은 hero/sheet 템플릿 위에 지원자 목록, 지망 순위/학점 정렬, 지원자 성적 카드를 배치했습니다.
  • university-web 대학 상세와 지원자 현황 상세에서 함께 쓸 수 있도록 MobileHeroDetailShell@solid-connect/ui에 추가했습니다.
  • 공통 UI 패키지의 Tailwind 클래스가 누락되지 않도록 web, university-web Tailwind content/transpile 설정을 보강했습니다.

검증

  • git diff --check
  • commit hook CI parity checks 통과
    • @solid-connect/web lint, typecheck
    • @solid-connect/university-web lint, typecheck
    • @solid-connect/admin lint, typecheck
  • pre-push hook CI parity checks 통과
    • @solid-connect/web lint, typecheck, build
    • @solid-connect/university-web lint, typecheck, build
    • @solid-connect/admin lint, typecheck, build
  • 추가 수동 검증
    • @solid-connect/ui lint/typecheck 통과
    • mock API + 실제 로그인 플로우로 /university/application 모바일/데스크톱 렌더 확인
    • mock API + 실제 로그인 플로우로 /university/application/[universityName] 모바일/데스크톱 렌더 확인
    • university-web 대학 상세 모바일/데스크톱 렌더 및 공통 hero sheet 적용 확인

참고

  • 이 PR은 기존 feat/desktop-mode-poc PR(feat: 데스크톱 최적화 레이아웃 적용 #576)에 섞이지 않도록 해당 브랜치를 base로 둔 stacked PR입니다.
  • #576이 먼저 머지되면 base를 main으로 변경할 수 있습니다.
  • 로컬 Node 버전은 v23.10.0이라 repository engines의 Node 22.x 경고가 출력됩니다.

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
solid-connect-university-web Ready Ready Preview, Comment Jul 6, 2026 2:31am
solid-connect-web-admin Ready Ready Preview, Comment Jul 6, 2026 2:31am
solid-connection-web Ready Ready Preview, Comment Jul 6, 2026 2:31am

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@manNomi, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b223e879-e944-4eba-83bc-754ba0db78e2

📥 Commits

Reviewing files that changed from the base of the PR and between a09f1c9 and 610e4cf.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • apps/web/next.config.mjs
  • apps/web/package.json
  • apps/web/src/app/university/application/ScorePageContent.tsx
  • apps/web/src/app/university/application/ScoreSheet.tsx
  • apps/web/src/app/university/application/[universityName]/ApplicationUniversityDetailContent.tsx
  • apps/web/src/app/university/application/[universityName]/page.tsx
  • apps/web/src/app/university/application/page.tsx
  • apps/web/src/constants/university.ts
  • apps/web/src/types/application.ts
  • apps/web/src/types/university.ts
  • apps/web/tailwind.config.ts
  • packages/ui/src/index.ts
  • packages/ui/src/mobile-hero-detail-shell.tsx

Walkthrough

  1. 타입을 확장했습니다. Applicant에 점수 관련 필드를 추가하고, ScoreSheet는 식별자와 선택 필드를 더 넓게 받도록 바꿨습니다.
  2. 점수표 페이지를 재구성했습니다. 검색/선호 기반 상태를 제거하고, 범위·지역·정렬 상태로 표시 목록을 계산하도록 바꿨습니다.
  3. 모바일 점수시트를 바꿨습니다. 상세 링크, 정원 표기, GPA/어학성적 포맷, 행 렌더링 구조를 새 컴포넌트로 정리했습니다.
  4. 대학별 상세 화면을 추가했습니다. 점수시트 매칭, 지원자 정렬, 공유 버튼, 스켈레톤/미존재 상태, 라우트 디코딩과 메타데이터 처리가 들어갔습니다.
  5. 상단 문구를 바꿨습니다. 지원자 현황 페이지의 타이틀을 “지원자 현황 확인”으로 통일했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: wibaek, enunsnv, khwww

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 지원자 현황 확인 UI 디자인 구현이라는 주요 변경사항을 잘 요약합니다.
Description check ✅ Passed 필수 섹션과 작업 내용이 모두 갖춰져 있어 템플릿 요구사항을 대부분 충족합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/application-status-design

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.

@manNomi

manNomi commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f26bdb3406

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/app/university/application/ScorePageContent.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
apps/web/src/app/university/application/ScoreSheet.tsx (1)

19-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

3. 포맷 헬퍼들, 상세 페이지 쪽과 완전히 똑같이 복붙된 상태예요.

formatApplicantGpa, formatApplicantLanguageTestApplicationUniversityDetailContent.tsx에도 토씨 하나 안 틀리고 그대로 존재합니다(그래프 컨텍스트 확인). 게다가 정원 없음 문구도 여기선 "미정", 상세 페이지의 getCapacityLabel"모집 미정"으로 이미 미묘하게 갈라졌어요 — 중복 코드가 벌써 드리프트하기 시작한 신호입니다. 공통 유틸(@/utils/applicant 같은 모듈)로 뽑아 두 파일에서 import하는 편을 추천드려요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/app/university/application/ScoreSheet.tsx` around lines 19 - 62,
The helper functions in ScoreSheet are duplicated with
ApplicationUniversityDetailContent, and the capacity label has already drifted
(“미정” vs “모집 미정”). Extract the shared formatting logic from formatApplicantGpa,
formatApplicantLanguageTest, formatApplicantLanguageTestName,
formatApplicantLanguageScore, and getScoreSheetCapacity into a common utility
module (for example an applicant utils file), then import and reuse those
helpers in both ScoreSheet and ApplicationUniversityDetailContent so the
behavior stays consistent.
apps/web/src/app/university/application/[universityName]/page.tsx (1)

6-9: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

2. 목록 페이지랑 상세 페이지 타이틀이 똑같아요.

metadata.title도 "지원자 현황 확인", TopDetailNavigation의 title도 "지원자 현황 확인"인데, 목록 페이지(application/page.tsx)도 동일한 문구를 쓰고 있어요. 브라우저 탭이나 상단 내비게이션만 보고는 지금 목록인지 특정 대학 상세인지 구분이 안 될 것 같아요. ${decodedUniversityName} 지원자 현황처럼 대학명을 넣어주면 어떨까요?

Also applies to: 21-21

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/app/university/application/`[universityName]/page.tsx around
lines 6 - 9, The university application detail page is using the same title as
the list page, so update the metadata and the TopDetailNavigation title in the
[universityName] page to include the decoded university name, using the existing
decodedUniversityName value and the page’s title setup so the detail view is
distinguishable from application/page.tsx.
apps/web/src/app/university/application/[universityName]/ApplicationUniversityDetailContent.tsx (2)

259-269: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

5. 클립보드 복사, 실패 처리가 없어요.

navigator.clipboard?.writeText(...)는 Promise를 반환하는데 .catch()가 없어서, 권한 정책 등으로 실패하면 콘솔에 unhandled rejection이 남고 사용자에게는 아무 피드백도 안 가요. 성공/실패 여부에 따른 토스트라도 붙이면 훨씬 친절할 것 같아요.

🔗 간단한 개선안
 const ShareActionButton = () => {
   const handleShare = () => {
-    navigator.clipboard?.writeText(window.location.href);
+    navigator.clipboard?.writeText(window.location.href).catch(() => {
+      // TODO: 사용자에게 실패 피드백 제공
+    });
   };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/web/src/app/university/application/`[universityName]/ApplicationUniversityDetailContent.tsx
around lines 259 - 269, The ShareActionButton handleShare flow currently calls
navigator.clipboard.writeText without any failure handling, so add Promise error
handling and user feedback there. Update the ShareActionButton component to
catch clipboard write failures, and surface success/failure through a toast or
similar message so users know whether the copy action worked. Keep the fix
localized to handleShare inside ApplicationUniversityDetailContent.

291-327: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

6. findScoreSheetWithApplicants 로직 자체는 괜찮아 보여요, 다만 테스트가 없네요.

지망 순위 병합/중복 제거 로직이 꽤 복잡한 편(여러 choice 배열을 순회하며 닉네임 기준 dedupe + preferenceOrder 유추)인데, 이 로직을 검증하는 단위 테스트가 이번 배치에 안 보여요. 핵심 파생 로직인 만큼 테스트를 추가해두면 이후 회귀를 잡기 쉬울 것 같아요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/web/src/app/university/application/`[universityName]/ApplicationUniversityDetailContent.tsx
around lines 291 - 327, Add unit tests for findScoreSheetWithApplicants to cover
the preference-order merge and nickname-based deduplication logic. Use
ApplicationUniversityDetailContent and the findScoreSheetWithApplicants helper
as the target, and verify that multiple scoreChoices entries for the same
university are merged correctly, duplicate applicants by nicknameForApply are
removed, and preferenceOrder falls back to the choice index when missing while
preserving an existing applicant.preferenceOrder when present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/web/src/app/university/application/`[universityName]/ApplicationUniversityDetailContent.tsx:
- Around line 249-257: The FavoriteActionButton currently renders a
clickable-looking button without any behavior, so add an onClick handler in
FavoriteActionButton and wire it to the existing favorite state/action flow in
ApplicationUniversityDetailContent. If the API or mutation is not ready yet,
make the control clearly non-interactive with a disabled/loading state or show a
user-facing toast instead of leaving it as a no-op.

In `@apps/web/src/app/university/application/`[universityName]/page.tsx:
- Around line 15-17: The ApplicationUniversityDetailPage currently calls
decodeURIComponent on universityName without protection, so malformed route
params can throw and crash the page. Update ApplicationUniversityDetailPage to
guard the decode step with try/catch and handle invalid universityName values
gracefully, returning a safe fallback or not-found/error state instead of
letting the server error bubble up. Use the existing
ApplicationUniversityDetailPage and decodedUniversityName logic as the place to
apply the defensive handling.

In `@apps/web/src/app/university/application/ScorePageContent.tsx`:
- Around line 355-363: `getAppliedUniversities`에서 `mine`가 없을 때 `choice[0]`를
fallback으로 쓰는 동작을 제거하세요. 현재 `ScorePageContent`의 이 함수는 각 지망에서 내 지원서가 포함된
`scoreSheet`만 골라야 하는데, `fallback` 때문에 다른 지원자의 대학이 내 “지원한 대학”으로 노출될 수 있습니다.
`mine`가 없으면 해당 `choice`는 반환하지 않도록 `flatMap` 로직을 수정하고, `preference`와
`scoreSheet`는 `mine`이 존재할 때만 생성되게 하세요.
- Around line 341-353: The uniqueScoreSheets helper is dropping applicants from
duplicate universities by keeping only the ScoreSheet with the largest
applicants array. Update uniqueScoreSheets in ScorePageContent.tsx to merge
applicants across all sheets for the same university, using the same
nicknameForApply-based aggregation approach as
ApplicationUniversityDetailContent.tsx, so getParticipantCount,
applicants.length, and sorting/rendering reflect the full combined list.

---

Nitpick comments:
In
`@apps/web/src/app/university/application/`[universityName]/ApplicationUniversityDetailContent.tsx:
- Around line 259-269: The ShareActionButton handleShare flow currently calls
navigator.clipboard.writeText without any failure handling, so add Promise error
handling and user feedback there. Update the ShareActionButton component to
catch clipboard write failures, and surface success/failure through a toast or
similar message so users know whether the copy action worked. Keep the fix
localized to handleShare inside ApplicationUniversityDetailContent.
- Around line 291-327: Add unit tests for findScoreSheetWithApplicants to cover
the preference-order merge and nickname-based deduplication logic. Use
ApplicationUniversityDetailContent and the findScoreSheetWithApplicants helper
as the target, and verify that multiple scoreChoices entries for the same
university are merged correctly, duplicate applicants by nicknameForApply are
removed, and preferenceOrder falls back to the choice index when missing while
preserving an existing applicant.preferenceOrder when present.

In `@apps/web/src/app/university/application/`[universityName]/page.tsx:
- Around line 6-9: The university application detail page is using the same
title as the list page, so update the metadata and the TopDetailNavigation title
in the [universityName] page to include the decoded university name, using the
existing decodedUniversityName value and the page’s title setup so the detail
view is distinguishable from application/page.tsx.

In `@apps/web/src/app/university/application/ScoreSheet.tsx`:
- Around line 19-62: The helper functions in ScoreSheet are duplicated with
ApplicationUniversityDetailContent, and the capacity label has already drifted
(“미정” vs “모집 미정”). Extract the shared formatting logic from formatApplicantGpa,
formatApplicantLanguageTest, formatApplicantLanguageTestName,
formatApplicantLanguageScore, and getScoreSheetCapacity into a common utility
module (for example an applicant utils file), then import and reuse those
helpers in both ScoreSheet and ApplicationUniversityDetailContent so the
behavior stays consistent.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2b6ac83d-af5e-4f9a-96fd-014da3910052

📥 Commits

Reviewing files that changed from the base of the PR and between 722afa5 and f930f35.

📒 Files selected for processing (6)
  • apps/web/src/app/university/application/ScorePageContent.tsx
  • apps/web/src/app/university/application/ScoreSheet.tsx
  • apps/web/src/app/university/application/[universityName]/ApplicationUniversityDetailContent.tsx
  • apps/web/src/app/university/application/[universityName]/page.tsx
  • apps/web/src/app/university/application/page.tsx
  • apps/web/src/types/application.ts

Comment thread apps/web/src/app/university/application/[universityName]/page.tsx Outdated
Comment thread apps/web/src/app/university/application/ScorePageContent.tsx
Comment thread apps/web/src/app/university/application/ScorePageContent.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/web/src/app/university/application/`[universityName]/ApplicationUniversityDetailContent.tsx:
- Around line 20-123: `ApplicationUniversityDetailContent` is still locally
redefining `MobileHeroDetailShell`, `MobileHeroDetailShellProps`, and
`MobileHeroDetailStat` instead of using the shared UI component. Replace the
local shell/type definitions with the exported `MobileHeroDetailShell` from
`@solid-connect/ui` and wire its props through this screen so the university
detail view reuses the common implementation and stays aligned with applicant
status.

In `@apps/web/src/app/university/application/ScorePageContent.tsx`:
- Around line 280-292: `REGIONS_KO` and `RegionKo` are out of sync, and the
`region as RegionKo` cast in `ScorePageContent` hides that mismatch so invalid
filter values like `"중국권"` can flow into state. Update the constants/types so
they agree by either changing `REGIONS_KO` to a `readonly RegionKo[]` that only
contains valid `RegionKo` values or expanding `RegionKo` to match the actual
region labels used by the filter UI, and remove the unsafe cast in the
`REGIONS_KO.map` render path.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 824a5d20-db45-46e4-9f76-7522c08d2581

📥 Commits

Reviewing files that changed from the base of the PR and between f930f35 and a09f1c9.

📒 Files selected for processing (6)
  • apps/web/src/app/university/application/ScorePageContent.tsx
  • apps/web/src/app/university/application/ScoreSheet.tsx
  • apps/web/src/app/university/application/[universityName]/ApplicationUniversityDetailContent.tsx
  • apps/web/src/app/university/application/[universityName]/page.tsx
  • apps/web/src/app/university/application/page.tsx
  • apps/web/src/types/application.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/app/university/application/page.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/src/types/application.ts
  • apps/web/src/app/university/application/ScoreSheet.tsx

Comment thread apps/web/src/app/university/application/ScorePageContent.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant