Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] 네이버 검색 결과 태그 제거, 카테고리 대분류 추출 #86

Merged
merged 7 commits into from
Dec 5, 2024

Conversation

keemsebin
Copy link
Member

@keemsebin keemsebin commented Dec 4, 2024

관련 이슈

close #85

📑 작업 내용

  • 네이버 검색 결과 시 태그가 같이 검색 되는 경우, 태그 제거했습니다.
  • 검색 결과시 카테고리 대분류만 보여지도록 수정했습니다.
  • 입력시 띄어쓰기가 존재하는 경우 공백 제거했습니다.
as is to be
스크린샷 2024-12-04 오후 7 35 05 스크린샷 2024-12-04 오후 7 54 06

💬 리뷰 중점 사항/기타 참고 사항

Summary by CodeRabbit

  • 새로운 기능

    • 입력 처리 로직 개선: 입력값에서 공백이 제거되어 상태 업데이트 시 더 정확한 값이 반영됩니다.
    • 검색 결과 처리 방식 변경: 새로운 유틸리티 함수가 도입되어 검색 결과의 구조가 표준화됩니다.
    • 검색 결과에서 HTML 태그 제거 및 카테고리 추출 기능 추가.
    • 링크 입력 컴포넌트에 자동 포커스 기능 추가: 컴포넌트 렌더링 시 입력 필드가 자동으로 포커스됩니다.
  • 스타일

    • 사용자 정의 마커의 제목 표시 스타일 변경: 제목의 글꼴 두께가 변경되어 시각적 강조가 강화되었습니다.
    • 입력 컴포넌트의 헬퍼 메시지 스타일 변경: 새로운 Body4 컴포넌트로 교체되어 더 나은 시각적 표현을 제공합니다.

@keemsebin keemsebin added the fix label Dec 4, 2024
@keemsebin keemsebin self-assigned this Dec 4, 2024
@keemsebin keemsebin requested a review from houony as a code owner December 4, 2024 10:57
Copy link

coderabbitai bot commented Dec 4, 2024

Walkthrough

이 풀 리퀘스트는 useInput 훅의 입력 처리 로직을 개선하고, MapView 컴포넌트에서 검색 결과를 처리하는 방식을 변경하며, 새로운 유틸리티 함수 parseSearchResult를 추가합니다. useInput 훅의 onChange 이벤트 핸들러는 입력값의 앞뒤 공백을 제거하도록 수정되었고, MapView 컴포넌트는 검색 결과를 parseSearchResult를 통해 처리하도록 변경되었습니다. CustomMarker 컴포넌트의 HTML 구조는 약간 수정되어 스타일이 변경되었습니다.

Changes

파일 경로 변경 요약
src/hooks/common/useInput.tsx onChange 핸들러에서 입력값의 앞뒤 공백을 제거하도록 수정.
src/pages/MapView.tsx handleSearch 메서드에서 parseSearchResult 함수를 사용하여 검색 결과 처리 방식 변경.
src/utils/CustomMarker.ts <span> 요소의 글꼴 두께를 400에서 600으로 변경.
src/utils/parseSearchResult.ts 새로운 파일 추가: removeHtmlTagsextractCategory 함수 포함, parseSearchResult 함수 구현.

Assessment against linked issues

Objective Addressed Explanation
네이버 검색 결과 태그 제거 (#85)
카테고리 중분류 제거 (#85)

Possibly related PRs

Suggested labels

refactor

Suggested reviewers

  • houony

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 4

🧹 Outside diff range and nitpick comments (1)
src/utils/parseSearchResult.ts (1)

3-5: 정규식 패턴의 견고성 개선이 필요합니다

현재 HTML 태그 제거 정규식이 일부 복잡한 HTML 구조에서 문제를 일으킬 수 있습니다.

다음과 같이 더 견고한 정규식으로 개선하는 것을 추천드립니다:

-  return result.replace(/<\/?[^>]+(>|$)/g, '');
+  return result.replace(/<[^>]*>/g, '').trim();
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b712486 and a5a8f3b.

📒 Files selected for processing (4)
  • src/hooks/common/useInput.tsx (1 hunks)
  • src/pages/MapView.tsx (2 hunks)
  • src/utils/CustomMarker.ts (1 hunks)
  • src/utils/parseSearchResult.ts (1 hunks)
🔇 Additional comments (2)
src/pages/MapView.tsx (2)

19-19: 새로운 유틸리티 함수 import가 적절히 추가되었습니다.

검색 결과를 정제하기 위한 parseSearchResult 유틸리티 함수가 올바르게 import 되었습니다.


58-58: 검색 결과 처리 로직 검증이 필요합니다.

parseSearchResult 함수를 통한 데이터 정제 처리가 추가되었습니다. 다음 사항들을 확인해주세요:

  1. 빈 검색 결과에 대한 처리
  2. HTML 태그가 포함된 다양한 케이스에 대한 처리
  3. 카테고리 정보가 없는 경우의 처리

다음 스크립트를 실행하여 parseSearchResult 함수의 구현을 확인해보세요:

✅ Verification successful

parseSearchResult 함수의 구현이 안전하게 되어있습니다

parseSearchResult 함수의 구현을 검토한 결과, 우려했던 모든 엣지 케이스들이 적절히 처리되고 있습니다:

  1. HTML 태그 제거: removeHtmlTags 함수가 정규식을 사용하여 모든 HTML 태그를 안전하게 제거합니다
  2. 카테고리 처리:
    • 문자열 타입 체크로 잘못된 입력 방지
    • 카테고리가 문자열이 아닌 경우 빈 문자열 반환
    • split('>')으로 첫 번째 카테고리만 추출
  3. 데이터 구조 보존: spread 연산자로 원본 데이터의 다른 필드들은 유지
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# parseSearchResult 함수의 구현 확인
ast-grep --pattern 'export function parseSearchResult($_) {
  $$$
}'

# 함수의 테스트 코드 확인
fd -e test.ts -e spec.ts parseSearchResult

Length of output: 115


Script:

#!/bin/bash
# 전체 코드베이스에서 parseSearchResult 함수 검색
rg -A 10 "parseSearchResult" 

# 관련 파일 찾기
fd parseSearchResult

# utils 또는 helpers 디렉토리에서 검색
fd -t f . src/utils src/helpers

# 테스트 파일 검색 (다른 패턴)
fd -e test.tsx -e spec.tsx -e test.ts -e spec.ts

Length of output: 2120


Script:

#!/bin/bash
# parseSearchResult 관련 유틸리티 함수들 확인
rg -A 5 "removeHtmlTags|extractCategory" src/utils/

# Place 타입 정의 확인
rg -A 10 "type Place" 

# 실제 데이터 처리 로직 자세히 확인
cat src/utils/parseSearchResult.ts

Length of output: 1848

Comment on lines +11 to +17
export const parseSearchResult = (data: Place[]) => {
return data.map((item) => ({
...item,
title: removeHtmlTags(item.title),
category: typeof item.category === 'string' ? extractCategory(item.category) : '',
}));
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

타입 안전성 강화가 필요합니다

Place 타입의 필수 필드에 대한 검증이 부족합니다.

다음과 같이 타입 가드와 필수 필드 검증을 추가하는 것을 추천드립니다:

 export const parseSearchResult = (data: Place[]) => {
+  if (!Array.isArray(data)) return [];
   return data.map((item) => ({
     ...item,
-    title: removeHtmlTags(item.title),
+    title: item.title ? removeHtmlTags(item.title) : '',
     category: typeof item.category === 'string' ? extractCategory(item.category) : '',
   }));
 };
📝 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
export const parseSearchResult = (data: Place[]) => {
return data.map((item) => ({
...item,
title: removeHtmlTags(item.title),
category: typeof item.category === 'string' ? extractCategory(item.category) : '',
}));
};
export const parseSearchResult = (data: Place[]) => {
if (!Array.isArray(data)) return [];
return data.map((item) => ({
...item,
title: item.title ? removeHtmlTags(item.title) : '',
category: typeof item.category === 'string' ? extractCategory(item.category) : '',
}));
};

Comment on lines +7 to +9
const extractCategory = (category: string) => {
return category.split('>')[0];
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

카테고리 추출 시 예외 처리가 필요합니다

빈 문자열이나 구분자가 없는 경우에 대한 처리가 없습니다.

다음과 같이 예외 처리를 추가하는 것을 추천드립니다:

-  return category.split('>')[0];
+  return category?.split('>')?.[0]?.trim() ?? category ?? '';
📝 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 extractCategory = (category: string) => {
return category.split('>')[0];
};
const extractCategory = (category: string) => {
return category?.split('>')?.[0]?.trim() ?? category ?? '';
};

@@ -7,7 +7,7 @@ export const useInput = (initialValue = '', validation: string[] = ['https', 'ww

const onChange: ChangeEventHandler<HTMLInputElement> = useCallback((e) => {
const value = e.target.value;
setState(value);
setState(value.trim());
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

입력값 트리밍 시점 재고가 필요합니다

onChange 이벤트에서 즉시 트리밍하는 것은 사용자 경험을 해칠 수 있습니다. 사용자가 입력 중에 공백을 사용하는 것이 불가능해집니다.

다음과 같이 onBlur 이벤트에서 트리밍하는 것을 추천드립니다:

-    setState(value.trim());
+    setState(value);

그리고 onBlur 함수에서 트리밍을 수행:

   const onBlur = useCallback(() => {
+    setState(state.trim());
     if (state.length > 0) {
       setIsValid(validation.some((criteria) => state.includes(criteria)));
     }
   }, [state, validation]);

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +45 to 47
<span style="display: block; font-size: 12px; font-weight: 600; color: black; text-align: center; white-space: normal; margin-top: 4px;">
${shouldShowTitle ? title : ''}
</span>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

보안 취약점 개선이 필요합니다

문자열 템플릿을 통한 직접적인 HTML 삽입은 XSS 공격에 취약할 수 있습니다.

다음과 같이 HTML 이스케이프 함수를 추가하고 적용하는 것을 추천드립니다:

+const escapeHtml = (str: string) => {
+  return str
+    .replace(/&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;')
+    .replace(/"/g, '&quot;')
+    .replace(/'/g, '&#039;');
+};

   <span style="display: block; font-size: 12px; font-weight: 600; color: black; text-align: center; white-space: normal; margin-top: 4px;">
-    ${shouldShowTitle ? title : ''}
+    ${shouldShowTitle ? escapeHtml(title) : ''}
   </span>
📝 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
<span style="display: block; font-size: 12px; font-weight: 600; color: black; text-align: center; white-space: normal; margin-top: 4px;">
${shouldShowTitle ? title : ''}
</span>
const escapeHtml = (str: string) => {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
};
<span style="display: block; font-size: 12px; font-weight: 600; color: black; text-align: center; white-space: normal; margin-top: 4px;">
${shouldShowTitle ? escapeHtml(title) : ''}
</span>

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

🧹 Outside diff range and nitpick comments (1)
src/components/common/Input/index.tsx (1)

6-6: 사용하지 않는 Caption import 제거 필요

Caption 컴포넌트가 더 이상 사용되지 않으므로 import 문에서 제거하는 것이 좋습니다.

-import { Body4, Caption } from '../Typography';
+import { Body4 } from '../Typography';
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a5a8f3b and a38ff49.

📒 Files selected for processing (1)
  • src/components/common/Input/index.tsx (2 hunks)

Comment on lines +32 to +34
<Body4 className="text-[14px] text-primary mt-1">
{errorMessage || '유투브 링크 혹은 지도 링크만 가능합니다.'}
</Caption>
</Body4>
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Typography 스타일이 중복되어 있습니다

Body4 컴포넌트는 이미 text-body4 클래스를 통해 14px 폰트 크기를 정의하고 있습니다. Tailwind 설정에서 text-body414px로 정의되어 있으므로, text-[14px] 클래스는 불필요한 중복입니다. 해당 클래스를 제거하여 Typography 시스템의 일관성을 유지하시기 바랍니다.

🔗 Analysis chain

Typography 스타일 중복 확인 필요

Body4 컴포넌트가 이미 기본 폰트 크기를 정의하고 있다면, text-[14px] 클래스는 중복될 수 있습니다. Typography 시스템의 일관성을 위해 확인이 필요합니다.


Let me check the Tailwind configuration to see if text-body4 class defines a specific font size.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if Body4 component already defines font size
rg -A 5 "Body4" src/components/common/Typography

Length of output: 2007


Script:

#!/bin/bash
# Check Tailwind configuration for text-body4 class definition
fd -e js -e ts "tailwind.config" --exec cat {}

Length of output: 785

Copy link

github-actions bot commented Dec 4, 2024

Update: 2024년 12월 04일 22시 51분 25초
Storybook 미리보기: https://6709628f8a6eec04b29d4f39-nxinufkghv.chromatic.com/

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: 0

🧹 Outside diff range and nitpick comments (1)
src/components/features/LinkForm/LinkInput.tsx (1)

Based on the shell script results, I can now generate the final response. The code shows that the URL validation logic in useInput hook is using a simple string inclusion check with default validation criteria of ['https', 'www', 'youtu'], which may not be sufficient for properly validating Naver URLs.

네이버 URL 검증 로직 개선 필요

현재 URL 검증 로직이 너무 단순합니다. useInput 훅에서 단순히 'https', 'www', 'youtu'와 같은 문자열 포함 여부만 확인하고 있어, 네이버 검색 결과 URL에 대한 적절한 검증이 이루어지지 않을 수 있습니다.

  • src/hooks/common/useInput.tsx:
    • 현재 검증 로직: validation.some((criteria) => state.includes(criteria))
    • 네이버 도메인(naver.com)과 검색 결과 URL 패턴에 대한 구체적인 검증이 필요합니다.
    • URL 형식 자체에 대한 기본적인 유효성 검사도 추가되어야 합니다.
🔗 Analysis chain

Line range hint 28-38: 입력값 검증 로직 확인 필요

네이버 검색 결과와 관련된 링크 처리를 위해, 입력값 검증 로직이 적절한지 확인이 필요합니다.

다음 스크립트를 실행하여 입력값 검증 로직을 확인해주세요:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify input validation logic in useInput hook
# Expected: Find validation logic specific to Naver URLs

# Search for useInput hook implementation
ast-grep --pattern 'export const useInput = $_'

# Search for URL validation patterns
rg -A 5 'isValid|validation|validate'

Length of output: 10036

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c530a9c and 2eeec62.

📒 Files selected for processing (1)
  • src/components/features/LinkForm/LinkInput.tsx (1 hunks)
🔇 Additional comments (2)
src/components/features/LinkForm/LinkInput.tsx (2)

28-28: 자동 포커스 기능 추가 승인

사용자 경험 향상을 위한 autoFocus 속성 추가는 적절한 개선사항입니다. 사용자가 페이지에 진입했을 때 즉시 링크를 입력할 수 있게 되어 사용성이 향상됩니다.


Line range hint 31-37: 상태 관리 및 에러 처리 구현 승인

상태 관리와 에러 처리가 잘 구현되어 있습니다:

  • 입력값 유효성 검사
  • 컨텍스트와 로컬 상태의 동기화
  • 초기화 기능 구현

@keemsebin keemsebin merged commit 37df721 into main Dec 5, 2024
5 checks passed
@keemsebin keemsebin deleted the fix/#85-result branch December 5, 2024 07:10
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.

[FIX] 네이버 검색 결과 태그 제거
2 participants