Skip to content

Comments

fix: 대학 검색 기본 경로를 인하대 페이지로 변경#457

Merged
manNomi merged 3 commits intomainfrom
fix/university-search-default-inha
Feb 20, 2026
Merged

fix: 대학 검색 기본 경로를 인하대 페이지로 변경#457
manNomi merged 3 commits intomainfrom
fix/university-search-default-inha

Conversation

@manNomi
Copy link
Contributor

@manNomi manNomi commented Feb 20, 2026

요약

  • /university/search 페이지에서 검색 시 이동 경로를 기존 /university?...에서 /university/inha?...로 변경했습니다.
  • 단순 검색 입력(SearchBar)과 조건 검색 폼(PageContent) 모두 동일하게 인하대 기본 경로를 사용하도록 맞췄습니다.
  • 하드코딩 대신 HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA]를 사용해 기존 상수 체계를 따르도록 적용했습니다.

변경 파일

  • apps/web/src/app/university/search/SearchBar.tsx
  • apps/web/src/app/university/search/PageContent.tsx

검증

  • pnpm --filter @solid-connect/web run lint:check
  • pnpm --filter @solid-connect/web run typecheck
  • pnpm --filter @solid-connect/web run build

@vercel
Copy link

vercel bot commented Feb 20, 2026

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

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

@github-actions github-actions bot added the web label Feb 20, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Walkthrough

  1. 탭: Search 컴포넌트들이 홈 대학교 슬러그를 prop으로 받도록 변경되었습니다.
  2. 탭: SearchBar와 SchoolSearchForm의 제출 경로가 /university?{query}에서 /university/{homeUniversitySlug}?{query}로 변경되었습니다.
  3. 탭: 새로운 클라이언트 컴포넌트 SearchClientContent가 추가되어 대학 선택 필과 SearchBar/SchoolSearchForm에 선택된 슬러그를 전달합니다.
  4. 탭: UniversityListContent가 initialSearchTextinitialRegion props를 받아 내부 상태를 초기화하고, 해당 props 변경 시 상태를 동기화하도록 useEffect 훅이 추가되었습니다.
  5. 탭: 대학 목록 페이지(page.tsx)가 검색 파라미터를 받아 필터 기반 서버 호출 경로를 분기하고, 초기 입력값/지역/시험 타입을 컴포넌트에 전달하도록 시그니처와 로직이 확장되었습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • wibaek
  • enunsnv
  • khwww
🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive PR 설명이 변경 내용을 명확히 설명했으나, 템플릿의 필수 섹션인 '관련 이슈'와 '특이 사항' 섹션이 부재합니다. 관련 이슈 번호를 '관련 이슈' 섹션에 추가하고, 필요 시 주의사항을 '특이 사항' 섹션에 명시해 주세요.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 PR의 주요 변경사항인 대학 검색의 기본 경로를 인하대 페이지로 변경하는 내용을 명확하게 요약하고 있습니다.

✏️ 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/university-search-default-inha

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.

🧹 Nitpick comments (2)
apps/web/src/app/university/search/PageContent.tsx (1)

37-37: defaultHomeUniversitySlug 상수를 컴포넌트 바깥으로 이동하는 것을 고려해보세요.

  1. 현재 위치 문제

    • defaultHomeUniversitySlug는 props나 state에 의존하지 않으며, 모든 렌더링에서 동일한 값("inha")을 반환합니다.
    • 컴포넌트 내부에 선언하면 매 렌더마다 불필요하게 재평가됩니다.
  2. 추가로 확인할 점

    • SearchBar.tsx에도 동일한 const defaultHomeUniversitySlug = HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA];가 선언되어 있습니다.
    • 같은 폴더 내 두 파일에서 동일한 상수가 중복되고 있으니, 모듈 스코프로 올리거나 공유 상수로 추출하는 것을 권장합니다.
♻️ 개선 예시
 import { CountryCode, HomeUniversity, LanguageTestType } from "@/types/university";
 import CustomDropdown from "../CustomDropdown";

+const defaultHomeUniversitySlug = HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA];

 const SchoolSearchForm = () => {
   const router = useRouter();
-  const defaultHomeUniversitySlug = HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/university/search/PageContent.tsx` at line 37, Move the
constant defaultHomeUniversitySlug =
HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA] out of the component scope and
into module scope (or a shared constants module) so it is not re-evaluated on
every render; update the component to import/use that module-level/shared
constant instead of redeclaring it, and do the same for the duplicate
declaration found in SearchBar (consolidate into one exported constant to avoid
duplication).
apps/web/src/app/university/search/SearchBar.tsx (1)

32-32: defaultHomeUniversitySlugPageContent.tsx와 중복됩니다. 모듈 스코프로 이동을 권장합니다.

  1. 중복 선언

    • PageContent.tsx 37번 줄과 완전히 동일한 상수가 다시 선언되어 있습니다.
    • 같은 폴더 내에서 동일한 값을 두 번 정의하는 것은 DRY 원칙에 어긋납니다.
  2. 렌더링 최적화

    • props·state와 무관한 정적 상수이므로 컴포넌트 내부에 둘 이유가 없습니다.
    • 모듈 스코프로 올리거나, 별도의 상수 파일로 추출하면 양쪽 컴포넌트가 함께 참조할 수 있습니다.
♻️ 개선 예시 (모듈 스코프로 이동)
 import { HOME_UNIVERSITY_TO_SLUG_MAP } from "@/constants/university";
 import { HomeUniversity } from "@/types/university";

+const defaultHomeUniversitySlug = HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA];

 const SearchBar = ({ initText }: SearchBarProps) => {
   const router = useRouter();
-  const defaultHomeUniversitySlug = HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/university/search/SearchBar.tsx` at line 32, The constant
defaultHomeUniversitySlug in SearchBar (derived from HOME_UNIVERSITY_TO_SLUG_MAP
and HomeUniversity) is duplicated with PageContent.tsx; extract that constant to
module scope or a shared constants module (e.g., export
DEFAULT_HOME_UNIVERSITY_SLUG from a new or existing constants file) and update
both SearchBar.tsx and PageContent.tsx to import it instead of declaring it
locally; remove the local declaration in SearchBar (and in PageContent if
duplicated) so the single exported symbol is reused across components.
🤖 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/web/src/app/university/search/PageContent.tsx`:
- Line 37: Move the constant defaultHomeUniversitySlug =
HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA] out of the component scope and
into module scope (or a shared constants module) so it is not re-evaluated on
every render; update the component to import/use that module-level/shared
constant instead of redeclaring it, and do the same for the duplicate
declaration found in SearchBar (consolidate into one exported constant to avoid
duplication).

In `@apps/web/src/app/university/search/SearchBar.tsx`:
- Line 32: The constant defaultHomeUniversitySlug in SearchBar (derived from
HOME_UNIVERSITY_TO_SLUG_MAP and HomeUniversity) is duplicated with
PageContent.tsx; extract that constant to module scope or a shared constants
module (e.g., export DEFAULT_HOME_UNIVERSITY_SLUG from a new or existing
constants file) and update both SearchBar.tsx and PageContent.tsx to import it
instead of declaring it locally; remove the local declaration in SearchBar (and
in PageContent if duplicated) so the single exported symbol is reused across
components.

@vercel vercel bot temporarily deployed to Preview – solid-connect-web-admin February 20, 2026 16:50 Inactive
@manNomi manNomi merged commit 5c0414f into main Feb 20, 2026
9 of 10 checks passed
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.

🧹 Nitpick comments (3)
apps/web/src/app/university/[homeUniversity]/page.tsx (1)

16-16: revalidatesearchParams 동시 사용 시 ISR 캐시 동작을 검토해보세요.

searchParams는 Dynamic API로, 이를 접근하면 페이지가 요청 시점에 동적 렌더링으로 opt-in됩니다. 따라서 export const revalidate = 15552000이 설정되어 있어도, searchParams의 각 고유 조합마다 별도의 캐시 엔트리가 생성될 수 있습니다. searchText, languageTestType, countryCode 조합이 많아질수록 캐시 스토리지가 과도하게 커질 수 있습니다.

운영 환경에서 캐시 크기가 우려된다면:

  • revalidate를 제거하고 export const dynamic = 'force-dynamic'으로 명시적으로 동적 렌더링을 선언하거나,
  • 자주 사용되는 필터 조합에 대해서만 generateStaticParams를 확장하는 방안을 검토해보세요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/university/`[homeUniversity]/page.tsx at line 16, The page
exports a static ISR revalidate value while also reading searchParams
(searchText, languageTestType, countryCode), which causes per-query dynamic
cache entries and potentially unbounded cache growth; either remove export const
revalidate = 15552000 and add export const dynamic = 'force-dynamic' to opt into
fully dynamic rendering, or keep ISR but implement generateStaticParams to
prebuild only the common filter combinations (or sanitize/limit which
searchParams are read) so cache entries remain bounded; update the page
component's exports (revalidate or dynamic) and/or add a generateStaticParams
implementation accordingly.
apps/web/src/app/university/search/SearchClientContent.tsx (1)

1-49: 새 컴포넌트 구조 LGTM! 대학 선택 → 라우팅 흐름이 명확합니다. 👍

  1. 초기값 설정 (Lines 11-13)

    • HOME_UNIVERSITY_TO_SLUG_MAP[HomeUniversity.INHA]를 사용해 하드코딩을 피한 점이 좋습니다.
  2. pill 선택 → slug 전파 (Lines 18-44)

    • selectedHomeUniversitySlugSearchBarSchoolSearchForm 양쪽에 일관되게 전달됩니다.

[Optional] SchoolSearchForm 임포트 별칭이 파일명과 불일치합니다.

PageContent.tsx의 default export는 SchoolSearchForm이지만, 모듈 파일명이 컴포넌트명과 다르기 때문에 다음 개발자가 파일을 찾을 때 약간 혼란스러울 수 있습니다.

✨ 가독성 개선 제안 (선택 사항)

파일명을 컴포넌트명에 맞게 일치시키거나, export 이름을 파일명 기준으로 통일하는 것을 검토해보세요:

-import SchoolSearchForm from "./PageContent";
+import SchoolSearchForm from "./SchoolSearchForm"; // 파일명 변경 시

또는 현재 파일명(PageContent.tsx)을 유지한다면 임포트 alias를 파일명 기반으로 사용:

-import SchoolSearchForm from "./PageContent";
+import PageContent from "./PageContent";
// ...
-<SchoolSearchForm homeUniversitySlug={selectedHomeUniversitySlug} />
+<PageContent homeUniversitySlug={selectedHomeUniversitySlug} />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/app/university/search/SearchClientContent.tsx` around lines 1 -
49, The import alias for the default export doesn't match the filename:
SearchClientContent imports SchoolSearchForm from "./PageContent" which can
confuse future readers; either rename the module file PageContent.tsx to match
the component (SchoolSearchForm.tsx) or change the export/default name in
PageContent.tsx to match the filename (e.g., export default PageContent) and
update usages accordingly (references: SchoolSearchForm in SearchClientContent
and the default export inside PageContent.tsx).
apps/web/src/app/university/[homeUniversity]/_ui/UniversityListContent.tsx (1)

31-37: [Optional] props→state 동기화에 useEffect 대신 key prop 사용을 고려해보세요.

현재 두 useEffectinitialSearchText/initialRegion이 변경될 때 state를 동기화합니다. 이 패턴은 "render 후 한 프레임 지연"이 발생할 수 있습니다. 부모에서 key를 교체하면 컴포넌트를 완전히 리셋하여 더 예측 가능하게 동작합니다.

✨ 대안: key prop 기반 리셋 (선택 사항)

부모 컴포넌트(page.tsx)에서 key를 지정하면 두 useEffect를 모두 제거할 수 있습니다:

// page.tsx
 <UniversityListContent
+  key={`${initialSearchText}-${initialRegion}`}
   universities={filteredUniversities}
   homeUniversity={universityInfo}
   homeUniversitySlug={homeUniversity}
   initialSearchText={initialSearchText}
   initialRegion={initialRegion}
 />
// UniversityListContent.tsx
-import { useEffect, useMemo, useState } from "react";
+import { useMemo, useState } from "react";
 
-  useEffect(() => {
-    setSearchText(initialSearchText.trim());
-  }, [initialSearchText]);
-
-  useEffect(() => {
-    setSelectedRegion(initialRegion);
-  }, [initialRegion]);

단, 이 방식은 같은 값으로 재방문할 때도 컴포넌트를 리마운트하므로 현재 UX에 적합한지 확인이 필요합니다.

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

In `@apps/web/src/app/university/`[homeUniversity]/_ui/UniversityListContent.tsx
around lines 31 - 37, The two useEffect hooks in UniversityListContent that call
setSearchText(initialSearchText.trim()) and setSelectedRegion(initialRegion)
cause a render-after-mount sync and should be replaced by resetting the
component via a key from the parent: remove those useEffect blocks (referencing
setSearchText, initialSearchText, setSelectedRegion, initialRegion in
UniversityListContent) and instead have the parent (page component that renders
<UniversityListContent ... />) pass a unique key derived from initialSearchText
and/or initialRegion so the component remounts with fresh state; ensure this
change is acceptable for UX because remounting will reset internal state on
revisit.
🤖 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/web/src/app/university/`[homeUniversity]/_ui/UniversityListContent.tsx:
- Around line 31-37: The two useEffect hooks in UniversityListContent that call
setSearchText(initialSearchText.trim()) and setSelectedRegion(initialRegion)
cause a render-after-mount sync and should be replaced by resetting the
component via a key from the parent: remove those useEffect blocks (referencing
setSearchText, initialSearchText, setSelectedRegion, initialRegion in
UniversityListContent) and instead have the parent (page component that renders
<UniversityListContent ... />) pass a unique key derived from initialSearchText
and/or initialRegion so the component remounts with fresh state; ensure this
change is acceptable for UX because remounting will reset internal state on
revisit.

In `@apps/web/src/app/university/`[homeUniversity]/page.tsx:
- Line 16: The page exports a static ISR revalidate value while also reading
searchParams (searchText, languageTestType, countryCode), which causes per-query
dynamic cache entries and potentially unbounded cache growth; either remove
export const revalidate = 15552000 and add export const dynamic =
'force-dynamic' to opt into fully dynamic rendering, or keep ISR but implement
generateStaticParams to prebuild only the common filter combinations (or
sanitize/limit which searchParams are read) so cache entries remain bounded;
update the page component's exports (revalidate or dynamic) and/or add a
generateStaticParams implementation accordingly.

In `@apps/web/src/app/university/search/SearchClientContent.tsx`:
- Around line 1-49: The import alias for the default export doesn't match the
filename: SearchClientContent imports SchoolSearchForm from "./PageContent"
which can confuse future readers; either rename the module file PageContent.tsx
to match the component (SchoolSearchForm.tsx) or change the export/default name
in PageContent.tsx to match the filename (e.g., export default PageContent) and
update usages accordingly (references: SchoolSearchForm in SearchClientContent
and the default export inside PageContent.tsx).

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