From 3e9120beb64543d310c6452a65c1303d6b89a5fa Mon Sep 17 00:00:00 2001 From: manNomi Date: Tue, 6 Oct 2026 01:11:51 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20perf:=20=ED=99=88=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=95=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_hooks/useHomeUniversityList.ts | 22 ++++-------- .../_utils/getHomeUniversityPreviews.ts | 35 +++++++++++++++++++ .../app/(home)/_ui/UniversityList/index.tsx | 8 ++--- .../app/(home)/_ui/UniversityList/types.ts | 4 +++ apps/web/src/app/(home)/page.tsx | 4 ++- .../components/ui/UniverSityCard/index.tsx | 4 +-- .../university/UniversityCards/index.tsx | 4 +-- apps/web/src/types/university.ts | 6 ++++ 8 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 apps/web/src/app/(home)/_ui/UniversityList/_utils/getHomeUniversityPreviews.ts create mode 100644 apps/web/src/app/(home)/_ui/UniversityList/types.ts diff --git a/apps/web/src/app/(home)/_ui/UniversityList/_hooks/useHomeUniversityList.ts b/apps/web/src/app/(home)/_ui/UniversityList/_hooks/useHomeUniversityList.ts index d28f23853..d1ca2c60b 100644 --- a/apps/web/src/app/(home)/_ui/UniversityList/_hooks/useHomeUniversityList.ts +++ b/apps/web/src/app/(home)/_ui/UniversityList/_hooks/useHomeUniversityList.ts @@ -1,12 +1,12 @@ import { type Dispatch, type SetStateAction, useMemo, useState } from "react"; -import { HOME_UNIVERSITY_LIST, isMatchedHomeUniversityName } from "@/constants/university"; -import { type AllRegionsUniversityList, type ListUniversity, RegionEnumExtend } from "@/types/university"; +import { HOME_UNIVERSITY_LIST } from "@/constants/university"; +import { RegionEnumExtend } from "@/types/university"; +import type { HomeUniversityPreviewList } from "../types"; -const ALL_HOME_UNIVERSITY_CHOICE = "전체"; -const PREVIEW_UNIVERSITY_COUNT = 3; +const ALL_HOME_UNIVERSITY_CHOICE = RegionEnumExtend.ALL; -const useHomeUniversityList = (allRegionsUniversityList: AllRegionsUniversityList) => { +const useHomeUniversityList = (homeUniversityPreviews: HomeUniversityPreviewList) => { const [selectedHomeUniversity, setSelectedHomeUniversity] = useState(ALL_HOME_UNIVERSITY_CHOICE); const handleHomeUniversityChange: Dispatch> = (nextHomeUniversity) => { setSelectedHomeUniversity((prevHomeUniversity) => { @@ -21,21 +21,13 @@ const useHomeUniversityList = (allRegionsUniversityList: AllRegionsUniversityLis [], ); - const allUniversities = allRegionsUniversityList[RegionEnumExtend.ALL] ?? []; const selectedUniversityInfo = useMemo( () => HOME_UNIVERSITY_LIST.find((university) => university.shortName === selectedHomeUniversity), [selectedHomeUniversity], ); - const universities: ListUniversity[] = useMemo(() => { - if (!selectedUniversityInfo) return allUniversities; - - return allUniversities.filter((university) => - isMatchedHomeUniversityName(university.homeUniversityName, selectedUniversityInfo.name), - ); - }, [allUniversities, selectedUniversityInfo]); - - const previewUniversities = useMemo(() => universities.slice(0, PREVIEW_UNIVERSITY_COUNT), [universities]); + const previewUniversities = + homeUniversityPreviews[selectedUniversityInfo?.shortName ?? ALL_HOME_UNIVERSITY_CHOICE] ?? []; const moreHref = selectedUniversityInfo ? `/university/${selectedUniversityInfo.slug}` : "/university"; return { diff --git a/apps/web/src/app/(home)/_ui/UniversityList/_utils/getHomeUniversityPreviews.ts b/apps/web/src/app/(home)/_ui/UniversityList/_utils/getHomeUniversityPreviews.ts new file mode 100644 index 000000000..f79dafc5d --- /dev/null +++ b/apps/web/src/app/(home)/_ui/UniversityList/_utils/getHomeUniversityPreviews.ts @@ -0,0 +1,35 @@ +import { HOME_UNIVERSITY_LIST, isMatchedHomeUniversityName } from "@/constants/university"; +import { type ListUniversity, RegionEnumExtend } from "@/types/university"; +import type { HomeUniversityPreview, HomeUniversityPreviewList } from "../types"; + +const PREVIEW_UNIVERSITY_COUNT = 3; +const PREVIEW_LANGUAGE_REQUIREMENT_COUNT = 3; + +const getPreviewUniversities = (universities: ListUniversity[]): HomeUniversityPreview[] => { + return universities.slice(0, PREVIEW_UNIVERSITY_COUNT).map((university) => ({ + id: university.id, + koreanName: university.koreanName, + homeUniversityName: university.homeUniversityName, + region: university.region, + country: university.country, + logoImageUrl: university.logoImageUrl, + languageRequirements: university.languageRequirements + .slice(0, PREVIEW_LANGUAGE_REQUIREMENT_COUNT) + .map(({ languageTestType, minScore }) => ({ languageTestType, minScore })), + })); +}; + +export const getHomeUniversityPreviews = (allUniversities: ListUniversity[]): HomeUniversityPreviewList => { + const previews: HomeUniversityPreviewList = { + [RegionEnumExtend.ALL]: getPreviewUniversities(allUniversities), + }; + + for (const { name, shortName } of HOME_UNIVERSITY_LIST) { + const universities = allUniversities.filter((university) => + isMatchedHomeUniversityName(university.homeUniversityName, name), + ); + previews[shortName] = getPreviewUniversities(universities); + } + + return previews; +}; diff --git a/apps/web/src/app/(home)/_ui/UniversityList/index.tsx b/apps/web/src/app/(home)/_ui/UniversityList/index.tsx index 0472062d0..9bb07ffd9 100644 --- a/apps/web/src/app/(home)/_ui/UniversityList/index.tsx +++ b/apps/web/src/app/(home)/_ui/UniversityList/index.tsx @@ -5,16 +5,16 @@ import UniversityZoneLink from "@/components/ui/UniversityZoneLink"; import UniversityCards from "@/components/university/UniversityCards"; import { IconDirectionRight } from "@/public/svgs/mentor"; -import type { AllRegionsUniversityList } from "@/types/university"; import useHomeUniversityList from "./_hooks/useHomeUniversityList"; +import type { HomeUniversityPreviewList } from "./types"; interface UniversityListProps { - allRegionsUniversityList: AllRegionsUniversityList; + homeUniversityPreviews: HomeUniversityPreviewList; } -const UniversityList = ({ allRegionsUniversityList }: UniversityListProps) => { +const UniversityList = ({ homeUniversityPreviews }: UniversityListProps) => { const { selectedHomeUniversity, setSelectedHomeUniversity, homeUniversityChoices, previewUniversities, moreHref } = - useHomeUniversityList(allRegionsUniversityList); + useHomeUniversityList(homeUniversityPreviews); return (
diff --git a/apps/web/src/app/(home)/_ui/UniversityList/types.ts b/apps/web/src/app/(home)/_ui/UniversityList/types.ts new file mode 100644 index 000000000..0534a6645 --- /dev/null +++ b/apps/web/src/app/(home)/_ui/UniversityList/types.ts @@ -0,0 +1,4 @@ +import type { UniversityCardData } from "@/types/university"; + +export type HomeUniversityPreview = Omit; +export type HomeUniversityPreviewList = Record; diff --git a/apps/web/src/app/(home)/page.tsx b/apps/web/src/app/(home)/page.tsx index 5a400505b..a3d499606 100644 --- a/apps/web/src/app/(home)/page.tsx +++ b/apps/web/src/app/(home)/page.tsx @@ -9,6 +9,7 @@ import HomeEntrySection from "./_ui/HomeEntrySection"; import NewsSection from "./_ui/NewsSection"; import PopularUniversitySection from "./_ui/PopularUniversitySection"; import UniversityList from "./_ui/UniversityList"; +import { getHomeUniversityPreviews } from "./_ui/UniversityList/_utils/getHomeUniversityPreviews"; const pageUrl = createUrl("/"); const ogImageUrl = createUrl("/opengraph-image.png"); @@ -109,6 +110,7 @@ const HomePage = async () => { recommendedUniversities, allUniversities, ).filter(hasUniversityDetailRoute); + const homeUniversityPreviews = getHomeUniversityPreviews(allUniversities); return ( <> @@ -123,7 +125,7 @@ const HomePage = async () => {
- +
diff --git a/apps/web/src/components/ui/UniverSityCard/index.tsx b/apps/web/src/components/ui/UniverSityCard/index.tsx index 6a3e5842e..aae63b2ac 100644 --- a/apps/web/src/components/ui/UniverSityCard/index.tsx +++ b/apps/web/src/components/ui/UniverSityCard/index.tsx @@ -2,12 +2,12 @@ import Image from "@/components/ui/FallbackImage"; import CheveronRightFilled from "@/components/ui/icon/ChevronRightFilled"; import UniversityZoneLink from "@/components/ui/UniversityZoneLink"; import { getHomeUniversitySlugByName } from "@/constants/university"; -import type { ListUniversity } from "@/types/university"; +import type { UniversityCardData } from "@/types/university"; import { normalizeImageUrlToUploadCdn } from "@/utils/cdnUrl"; import shortenLanguageTestName from "@/utils/universityUtils"; type UniversityCardProps = { - university: ListUniversity; + university: UniversityCardData; showCapacity?: boolean; linkPrefix?: string; }; diff --git a/apps/web/src/components/university/UniversityCards/index.tsx b/apps/web/src/components/university/UniversityCards/index.tsx index 19d1fe05c..879a99fce 100644 --- a/apps/web/src/components/university/UniversityCards/index.tsx +++ b/apps/web/src/components/university/UniversityCards/index.tsx @@ -2,11 +2,11 @@ import clsx from "clsx"; -import type { ListUniversity } from "@/types/university"; +import type { UniversityCardData } from "@/types/university"; import UniversityCard from "../../ui/UniverSityCard"; type UniversityCardsProps = { - colleges: ListUniversity[]; + colleges: UniversityCardData[]; style?: React.CSSProperties; className?: string; showCapacity?: boolean; diff --git a/apps/web/src/types/university.ts b/apps/web/src/types/university.ts index 712175910..b4cd2aadd 100644 --- a/apps/web/src/types/university.ts +++ b/apps/web/src/types/university.ts @@ -90,6 +90,12 @@ export interface ListUniversity { languageRequirements: LanguageRequirement[]; } +export type UniversityCardData = Pick< + ListUniversity, + "id" | "koreanName" | "homeUniversityName" | "region" | "country" | "logoImageUrl" | "languageRequirements" +> & + Partial>; + /** * 권역별 대학 리스트 응답 타입 * - Enum 값(전체·미주·유럽·아시아·중국)을 key 로 사용한다.