Skip to content

feat: 홈페이지 개편 - #339

Merged
seong-hui merged 7 commits into
developfrom
feat/#337/home
Jan 21, 2026
Merged

feat: 홈페이지 개편#339
seong-hui merged 7 commits into
developfrom
feat/#337/home

Conversation

@seong-hui

@seong-hui seong-hui commented Jan 21, 2026

Copy link
Copy Markdown
Member

🛰️ 관련 이슈

해결한 이슈 번호를 작성해주세요
close #337

🧑‍💻 작업 내용

작업한 내용을 간략히 작성해주세요

  • 홈페이지 개편을 진행했어요
  • 기존 검색 및 필터링 로직을 홈페이지로 꺼내고 로그인 및 절비티아이 진행 여부에 따라서 추천 템플스테이를 보여주는 기능을 추가했어요
  • Vercel 빌드에서 Next.js 보안 취약점이 감지되어서 기존 15.2.4에서 15.2.8로 패치를 진행했어요
    • 취약점 스캔 결과 보안 문제가 해결된 것 확인했어요
    • image

📸 스크린샷 (선택)

image

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 사용자 맞춤형 및 랜덤 사찰 추천 기능 추가
    • 추천 카드에 찜하기 기능 추가 (로그인 필요)
    • 검색창 및 필터 박스 개선
  • 스타일

    • 사찰 카드 레이아웃 최적화 및 반응형 크기 조정
    • 검색창 너비 확대

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 21, 2026

Copy link
Copy Markdown

Walkthrough

홈페이지 재설계 관련: 추천 API·훅·타입 추가, 추천·검색·필터 클라이언트 컴포넌트 도입, TempleStayCard에 사이즈 변형 및 스타일 레시피 적용, 위시리스트 낙관적 업데이트 흐름을 추가합니다.

Changes

Cohort / File(s) 설명
추천 API 모듈
src/apis/recommend/axios.ts, src/apis/recommend/index.ts, src/apis/recommend/type.ts
타입 기반/무작위 추천을 위한 Axios 요청 함수, React Query 훅 및 관련 타입 추가
사용자 API 훅 변경
src/apis/user/index.ts
useGetMyPage(enabled?: boolean)로 시그니처 변경(쿼리 자동 실행 제어)
RecommendTempleClient 컴포넌트
src/app/RecommendTempleClient.tsx, src/app/page.tsx, src/app/homePage.css.ts
로그인 상태에 따라 타입별/무작위 추천 호출, 위시리스트 낙관적 업데이트 및 로그인 모달 처리, 제목 아이콘 스타일 추가, 페이지 구성 변경
RecommendCard 컴포넌트
src/components/card/recommendCard/RecommendCard.tsx, src/components/card/recommendCard/recommendCard.css.ts
무작위 추천 표시 컴포넌트 및 스타일 추가, 위시리스트 토글 처리
TempleStayCard 사이즈 확장 및 스타일 리팩토링
src/components/card/templeStayCard/TempleStayCard.tsx, src/components/card/templeStayCard/InfoSection.tsx, src/components/card/templeStayCard/templeStayCard.css.ts, src/components/card/templeStayCard/infoSection.css.ts
'default'/'small' 사이즈 옵션 추가 및 recipe 기반 스타일로 통합(레이아웃·사이즈 variants)
검색/필터 변경
src/components/search/searchBar/SearchBar.tsx, src/components/search/searchBar/searchBar.css.ts, src/components/filter/filterTypeBox/FilterTypeBoxClient.tsx
검색 입력 단순화, 스타일 너비 조정, 필터 클라이언트 초기화 컴포넌트 추가
DetailTitle 확장
src/components/detailTitle/DetailTitle.tsx, src/components/detailTitle/detailTitle.css.ts
title에 `string
패키지 버전
package.json
Next.js 버전 고정 패치 업그레이드 (15.2.8)

Sequence Diagram

sequenceDiagram
    participant User
    participant Client as RecommendTempleClient
    participant UserAPI as User API
    participant RecommendAPI as Recommend API
    participant Cache as ReactQuery Cache
    participant WishlistAPI as Wishlist API
    participant Modal as Login Modal

    User->>Client: 페이지 로드
    Client->>UserAPI: useGetMyPage(enabled)
    UserAPI-->>Client: 사용자 정보 (type, name, hasType)

    alt 사용자 타입 보유
        Client->>RecommendAPI: getTypeRecommend()
        RecommendAPI-->>Client: 타입별 추천 목록
    else 타입 미보유
        Client->>RecommendAPI: getTypeRandom()
        RecommendAPI-->>Client: 무작위 추천 목록
    end

    Client-->>User: 카드 3개 렌더링

    alt 위시리스트 토글
        User->>Client: 토글 클릭
        alt 로그인됨
            Client->>Cache: 낙관적 업데이트(로컬 변경)
            Client->>WishlistAPI: add/remove 요청
            WishlistAPI-->>Client: 성공
            Client->>Cache: 관련 쿼리 무효화
        else 미로그인
            Client->>Modal: 로그인 모달 표시
            Modal-->>User: 로그인 유도
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

👩🏻‍🦲FEAT👩🏻‍🦲

Suggested reviewers

  • maylh
  • Taew00k
  • bykbyk0401

Poem

🐇 햇살 아래 새 추천이 빛나네
카드 셋이 폴짝, 위시리스트 깜빡
로그인 문 두드리면 모달이 와서
선택은 곧 즐거움, 클릭은 춤이네
토끼가 축하해요 — 홧팅! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive PR 설명이 템플릿 구조를 따르고 있으나 필수 섹션인 '🗯️ PR 포인트'와 '🚀 알게된 점'이 비어있습니다. '🗯️ PR 포인트' 섹션에 리뷰어가 주의깊게 봐야 할 부분을 작성하고, '🚀 알게된 점' 섹션에 개발 과정에서 배운 내용을 추가해주세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목 '홈페이지 개편'은 변경사항의 주요 목표를 명확하게 반영하며, 홈페이지 리디자인이라는 핵심 변경을 잘 설명합니다.
Linked Issues check ✅ Passed 변경사항은 호메페이지 리디자인 목표(#337)와 일치합니다. 새로운 추천 기능, UI 컴포넌트, API 모듈이 추가되었으며 홈페이지 구성이 개편되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 홈페이지 리디자인 범위 내입니다. 추천 API, 필터 컴포넌트, 검색바 개선이 모두 홈페이지 개편의 일부입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@github-actions

github-actions Bot commented Jan 21, 2026

Copy link
Copy Markdown

🪷 Storybook 확인 🪷
🔗 https://677fa9af1269762b7858c29f-hdslirqiur.chromatic.com/

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/card/templeStayCard/TempleStayCard.tsx (1)

55-78: 호버 효과가 적용되지 않습니다.

CSS 파일에 verticalImage, horizontalImage 호버 스타일이 정의되어 있지만, 이 컴포넌트에서는 styles.image({ layout }) recipe만 사용하고 있습니다. 또한 컨테이너도 styles.container({ layout, size }) recipe를 사용하고 있어서, CSS의 호버 셀렉터(${verticalContainer}:hover &)가 동작하지 않습니다.

호버 효과를 적용하려면 다음 중 하나의 방법이 필요합니다:

  1. 컨테이너에 레이아웃별 hover target 클래스를 추가하고, 이미지에도 해당 hover 스타일 클래스를 추가
  2. 또는 image recipe 내에 호버 효과를 통합
🔧 제안하는 수정 방법 (방법 1)
     <a
       href={link}
-      className={styles.container({ layout, size })}
+      className={`${styles.container({ layout, size })} ${
+        layout === 'vertical'
+          ? size === 'small'
+            ? styles.verticalSmallContainer
+            : styles.verticalContainer
+          : styles.horizontalContainer
+      }`}
       onClick={() =>
         logClickEvent('click_card_detail', {
           label: String(item.templestayId),
         })
       }>
       {item.imgUrl ? (
         <section className={styles.imgSection({ layout, size })}>
           <img
-            className={styles.image({ layout })}
+            className={`${styles.image({ layout })} ${
+              layout === 'vertical' ? styles.verticalImage : styles.horizontalImage
+            }`}
             src={item.imgUrl}
             alt={item.templeName + ' 대표사진'}
           />
🤖 Fix all issues with AI agents
In `@src/components/detailTitle/DetailTitle.tsx`:
- Around line 31-37: The DetailTitle component currently renders the title prop
as a div when title is a ReactNode, losing heading semantics; change the
rendering so that the h2 element is always used and the ReactNode is rendered
inside the h2 (keeping titleStyle({ size })) so both string and ReactNode cases
use <h2> semantics; update the JSX in DetailTitle (where title, titleStyle, and
size are referenced) to always output an h2 with the title content and preserve
existing className/style logic.
🧹 Nitpick comments (4)
src/components/search/searchBar/SearchBar.tsx (1)

71-73: 주석 처리된 레거시 버튼 정리 권장.
사용하지 않는 JSX 주석은 유지보수 노이즈가 됩니다.

🧹 정리 제안
-      {/* <button className={styles.pointer} onClick={() => handleClearInput()}>
-        <Icon.IcnCloseLargeGray />
-      </button> */}
src/apis/recommend/type.ts (1)

11-17: 중복 응답 타입은 별칭으로 정리하면 유지보수에 유리합니다.
TypeRandomResponse와 동일하므로 한 곳만 변경해도 되도록 묶는 편이 깔끔합니다.

♻️ 제안 리팩터링
-export interface TypeRecommendResponse {
-  results: TypeRandomTemplestay[];
-}
+export type TypeRecommendResponse = TypeRandomResponse;
src/app/RecommendTempleClient.tsx (1)

24-24: import 경로 스타일 불일치

다른 import들은 @components alias를 사용하고 있는데, 이 라인만 상대 경로를 사용하고 있습니다. 일관성을 위해 alias 사용을 권장합니다.

♻️ 제안하는 수정
-import styles from '../components/card/recommendCard/recommendCard.css';
+import styles from '@components/card/recommendCard/recommendCard.css';
src/components/card/templeStayCard/templeStayCard.css.ts (1)

129-134: borderRadius 값 형식 불일치

Line 133에서 borderRadius: 4를 숫자로 사용하고 있는데, 다른 곳에서는 '4px' 문자열을 사용하고 있습니다 (예: line 24, 105, 110, 138). 일관성을 위해 통일하는 것을 권장합니다.

♻️ 제안하는 수정
       vertical: {
         width: '16.3rem',
         height: '17.2rem',
-        borderRadius: 4,
+        borderRadius: '4px',
       },

Comment on lines +31 to +37
<div className={detailTitleStyle}>
<div className={titleContainerStyle}>
<h2 className={titleStyle({ size })}>{title}</h2>
{typeof title === 'string' ? (
<h2 className={titleStyle({ size })}>{title}</h2>
) : (
<div className={titleStyle({ size })}>{title}</div>
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the DetailTitle.tsx file
fd DetailTitle.tsx

Repository: JEOLLOGA/JEOLLOGA-CLIENT

Length of output: 110


🏁 Script executed:

# Let's also check the overall structure of the detailTitle directory
fd -t f . src/components/detailTitle/ 2>/dev/null | head -20

Repository: JEOLLOGA/JEOLLOGA-CLIENT

Length of output: 156


🏁 Script executed:

# Search for how DetailTitle is being used in the codebase
rg "DetailTitle" --type tsx --type ts -A 3 -B 1 | head -100

Repository: JEOLLOGA/JEOLLOGA-CLIENT

Length of output: 95


🏁 Script executed:

# Let me read the DetailTitle.tsx file to verify the code
cat -n src/components/detailTitle/DetailTitle.tsx

Repository: JEOLLOGA/JEOLLOGA-CLIENT

Length of output: 1512


🏁 Script executed:

# Search for DetailTitle usage without specifying file type
rg "DetailTitle" -A 3 -B 1 | head -150

Repository: JEOLLOGA/JEOLLOGA-CLIENT

Length of output: 11553


ReactNode 전달 시 heading 시맨틱 손실

title prop이 ReactNode인 경우 div로 렌더링되어 스크린리더와 SEO에서 제목 계층이 깨집니다. h2 태그 내부에 ReactNode를 렌더링하도록 변경하여 시맨틱을 유지해야 합니다.

제안 수정안
-        {typeof title === 'string' ? (
-          <h2 className={titleStyle({ size })}>{title}</h2>
-        ) : (
-          <div className={titleStyle({ size })}>{title}</div>
-        )}
+        <h2 className={titleStyle({ size })}>
+          {title}
+        </h2>
📝 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
<div className={detailTitleStyle}>
<div className={titleContainerStyle}>
<h2 className={titleStyle({ size })}>{title}</h2>
{typeof title === 'string' ? (
<h2 className={titleStyle({ size })}>{title}</h2>
) : (
<div className={titleStyle({ size })}>{title}</div>
)}
<div className={detailTitleStyle}>
<div className={titleContainerStyle}>
<h2 className={titleStyle({ size })}>
{title}
</h2>
🤖 Prompt for AI Agents
In `@src/components/detailTitle/DetailTitle.tsx` around lines 31 - 37, The
DetailTitle component currently renders the title prop as a div when title is a
ReactNode, losing heading semantics; change the rendering so that the h2 element
is always used and the ReactNode is rendered inside the h2 (keeping titleStyle({
size })) so both string and ReactNode cases use <h2> semantics; update the JSX
in DetailTitle (where title, titleStyle, and size are referenced) to always
output an h2 with the title content and preserve existing className/style logic.

@maylh maylh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

마침내
드디어

@seong-hui
seong-hui merged commit 2775de3 into develop Jan 21, 2026
7 checks passed
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.

[FEAT] 홈페이지 개편

2 participants