Skip to content
2 changes: 1 addition & 1 deletion src/components/common/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const Input = forwardRef<HTMLInputElement, Props>(
value={value}
ref={ref}
placeholder="링크를 입력해주세요."
className="w-full h-11 text-body3 bg-gray-100 pl-5 pr-10 rounded-lg outline-none focus:outline-1 focus:outline-offset-0 focus:outline-gray-400 transition-colors"
className="w-full h-12 text-body3 bg-gray-100 pl-5 pr-10 rounded-lg outline-none focus:outline-1 focus:outline-offset-0 focus:outline-gray-400 transition-colors"
{...props}
/>
{value && (
Expand Down
10 changes: 4 additions & 6 deletions src/components/common/PlaceItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Props } from './PlaceItem.types';

import { Chip } from '../Chip';
import { Icon } from '../Icon';
import { Body1, Body4 } from '../Typography';
import { Body2, Body3 } from '../Typography';

export const PlaceItem = forwardRef<HTMLDivElement, Props>(
({ place, isSelected, isEditing, onToggleSelect, isLast, ...props }, ref) => (
Expand All @@ -16,16 +16,14 @@ export const PlaceItem = forwardRef<HTMLDivElement, Props>(
>
<div className="flex flex-col gap-1 py-2">
<div className="flex flex-row gap-3 items-center">
<Body1 weight="semibold" className="text-primary">
{place.title}
</Body1>
<Body2 className="text-primary">{place.title}</Body2>
<Chip variant="medium">
{typeof place.category === 'object' ? place.category.majorCategory : place.category}
</Chip>
</div>
Comment on lines 20 to 23
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

모바일 대응을 위한 레이아웃 개선이 필요합니다.

코드 분석 결과, 다음과 같은 사항들이 확인되었습니다:

  • 카테고리는 '음식점', '카페', '교육', '병원' 등 다양한 길이의 텍스트가 포함될 수 있습니다
  • Chip 컴포넌트는 min-w-7로 최소 너비가 지정되어 있어 긴 텍스트의 경우 모바일에서 레이아웃 문제가 발생할 수 있습니다
  • 현재 PlaceItem의 레이아웃은 gap-3으로 고정되어 있어 모바일 화면에서 유연하지 않습니다

제안된 수정사항:

- <div className="flex flex-row gap-3 items-center">
+ <div className="flex flex-row gap-2 items-center flex-wrap xs:gap-3">

이 변경으로:

  • 모바일에서는 더 작은 gap으로 공간을 효율적으로 사용
  • flex-wrap으로 긴 카테고리명이 있을 경우 자연스럽게 줄바꿈
  • 데스크톱에서는 기존 여백(gap-3) 유지
🔗 Analysis chain

카테고리 칩의 모바일 대응이 필요해 보입니다.

긴 카테고리명이 있을 경우 모바일 화면에서 레이아웃이 깨질 수 있습니다. 다음과 같은 개선을 제안드립니다:

- <div className="flex flex-row gap-3 items-center">
+ <div className="flex flex-row gap-2 items-center flex-wrap xs:gap-3">
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 카테고리명의 최대 길이 확인
ast-grep --pattern 'category: $_' | rg -A 1 'category'

Length of output: 54


Script:

#!/bin/bash
# 카테고리 관련 타입 정의와 실제 데이터 확인
rg -g '*.ts*' -A 5 'type.*Place.*{' 
rg -g '*.ts*' -A 5 'interface.*Place.*{'

Length of output: 274


Script:

#!/bin/bash
# 실제 사용되는 카테고리 데이터 확인
rg -g '*.ts*' -g '*.js*' -B 2 -A 2 'category.*:.*'

Length of output: 8333


Script:

#!/bin/bash
# PlaceItem 컴포넌트의 전체 구현 확인
cat src/components/common/PlaceItem/index.tsx

Length of output: 1356


Script:

#!/bin/bash
# 카테고리 데이터의 실제 값과 길이 확인
rg -g '*.ts*' -g '*.js*' 'majorCategory.*:.*' -B 2 -A 2
rg -g '*.ts*' -g '*.js*' 'CATEGORY_REGEX_MAPPING' -B 2 -A 10

Length of output: 2486


Script:

#!/bin/bash
# Chip 컴포넌트 구현 확인
cat src/components/common/Chip/index.tsx

Length of output: 303


Script:

#!/bin/bash
# Chip 컴포넌트의 variants 확인
cat src/components/common/Chip/Chip.variants.ts

Length of output: 453


Script:

#!/bin/bash
# 실제 카테고리 데이터 예시 확인
rg -g '*.stories.tsx' -B 2 -A 2 'category.*:.*'

Length of output: 1022

<Body4 className="pt-1" weight="normal">
<Body3 className="pt-1" weight="normal">
{place.address}
</Body4>
</Body3>
</div>
{isEditing && (
<Icon
Expand Down
10 changes: 5 additions & 5 deletions src/components/common/Typography/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { cn } from '@/lib/core';

import { Props, TypographyVariant } from './Typography.types';

const variantClasses = cva('whitespace-pre-wrap select-none', {
const variantClasses = cva('whitespace-pre-line select-none', {
variants: {
type: {
Title1: 'text-title1 leading-140',
Title2: 'text-title2 leading-140',
Title3: 'text-title3 leading-140',
Body1: 'text-body1 leading-140',
Body2: 'text-body2 leading-140',
Body3: 'text-body3 leading-140',
Body4: 'text-title4 leading-140',
Body1: 'text-body2 leading-140 xs:text-body1',
Body2: 'text-body3 leading-140 xs:text-body2',
Body3: 'text-body4 leading-140 xs:text-body3',
Body4: 'text-body4 leading-140',
Caption: 'text-caption leading-140 inline-block',
},
weight: {
Expand Down
8 changes: 2 additions & 6 deletions src/components/features/BookmarkList/BookmarkList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,14 @@ export const BookmarkList = ({ onNext }: Props) => {

return (
<>
<Body1 className="my-4 mx-3" weight="semibold">
나의 핀디 리스트
</Body1>
<Body1 className="my-4 mx-3">나의 핀디 리스트</Body1>
<ListCard>
<div
className="w-full flex flex-row items-center gap-4 pb-4 cursor-pointer"
onClick={() => setIsNewBookmarkMode(true)}
>
<IconButton name="bookMark" />
<Body2 weight="medium" className="text-gray-400">
새 장소 추가하기
</Body2>
<Body2 className="text-gray-400">새 장소 추가하기</Body2>
</div>
<hr className="border-dashed pt-2" />
{data?.pages
Expand Down
16 changes: 7 additions & 9 deletions src/components/features/LinkForm/ExtractionStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ export const ExtractionStatus = ({
return (
<div className="flex flex-col items-center justify-between">
<Header left={<Icon name="home" size={20} onClick={onHomeClick} />} />
<div className="w-full flex flex-col items-start gap-12 my-36 px-6 overflow-hidden">
<div className="w-full flex flex-col items-start gap-12 my-28 px-6 overflow-hidden xs:my-36">
<Body1>
<Body1>
{isLoading
? `현재 장소 정보를 추출 중입니다.\n조금만 더 기다려 주세요, 곧 완료됩니다!`
: place?.length > 0
? `장소 정보가 성공적으로 추출되었습니다!\n지금 바로 확인하고, 원하는 장소를 방문해보세요!`
: `추출된 장소가 없어요.\n다른 링크를 입력해주시겠어요?`}
</Body1>
{isLoading
? `현재 장소 정보를 추출 중입니다.\n조금만 더 기다려 주세요, 곧 완료됩니다!`
: place?.length > 0
? `장소 정보가 성공적으로 추출되었습니다!\n지금 바로 확인하고, 원하는 장소를 방문해보세요!`
: `추출된 장소가 없어요.\n다른 링크를 입력해주시겠어요?`}
</Body1>
{videoId ? (
<m.div
Expand All @@ -50,7 +48,7 @@ export const ExtractionStatus = ({
transition={isLoading ? THUMBNAIL_ANIMATION.transition : undefined}
className="flex items-center w-full h-2/4 my-3"
>
<img src={thumbnailUrl} alt="YouTube Thumbnail" className="w-full h-full rounded-md" />
<img src={thumbnailUrl} alt="YouTubeThumbnail" className="w-full h-full rounded-md" />
</m.div>
) : (
<m.div
Expand Down
2 changes: 1 addition & 1 deletion src/components/features/LinkForm/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Landing = ({ onNext, onHomeClick }: LinkFormProps) => {
<Body1>핀디와 함께, 특별한 순간을 찾아보세요</Body1>
</div>
<div className="absolute bottom-3 w-full max-w-[30rem] px-4 mb-5">
<Button variant="primary" size="large" onClick={() => onNext} className="w-full">
<Button variant="primary" size="large" onClick={() => onNext()} className="w-full">
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

onClick 핸들러 최적화 필요

불필요한 화살표 함수 래퍼를 제거하여 성능을 개선할 수 있습니다. 매개변수가 필요하지 않으므로 함수 참조를 직접 전달하는 것이 좋습니다.

다음과 같이 수정하는 것을 추천드립니다:

-<Button variant="primary" size="large" onClick={() => onNext()} className="w-full">
+<Button variant="primary" size="large" onClick={onNext} className="w-full">
📝 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
<Button variant="primary" size="large" onClick={() => onNext()} className="w-full">
<Button variant="primary" size="large" onClick={onNext} className="w-full">

다음
</Button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/features/LoginModal/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Props } from './Login.types';

export const Login = ({ isOpen, setIsOpen }: Props) => {
const handleAuth = async (auth: 'kakao' | 'naver') => {
window.location.href = `${ENV.API_BASE_URL}oauth2/authorization/${auth}`;
window.location.href = `${ENV.API_BASE_URL}api/oauth/${auth}`;
};
return (
<Modal isOpen={isOpen} onClickOutside={() => setIsOpen(false)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ export const BookmarkSelectionList = ({ selectedPlace, onNext }: Props) => {

return (
<div className="flex flex-col gap-4">
<Body1 weight="semibold" className="my-3 mx-3">
북마크 리스트
</Body1>
<Body1 className="mt-2 mx-3">북마크 리스트</Body1>
<ListCard>
{data?.pages
.flatMap((page) => page.data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ export const SearchResultsList = ({ places, onNext, onSelect }: Props) => {

return (
<div className="flex flex-col gap-4">
<Body1 weight="semibold" className="my-3 mx-3">
검색 결과
</Body1>
<Body1 className="mt-2 mx-3">검색 결과</Body1>
<ListCard>
{places.map((item, index) => (
<PlaceItem
Expand Down
14 changes: 7 additions & 7 deletions src/constants/motions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ export const FADE_IN_ANIMATION = {
export const FIDIES_ANIMATION = {
initial: { opacity: 1, scale: 1, rotate: 0, y: 0 },
animate: {
scale: [1, 0.95, 1.05, 1],
scale: [1, 0.95, 1.1, 1],
rotate: [0, 5, -5, 0],
y: [0, -5, -10, -5, 0],
y: [0, -15, -15, 0],
},
transition: {
duration: 3,
ease: 'easeInOut',
ease: 'linear',
repeat: Infinity,
repeatType: 'loop' as const,
},
Expand All @@ -22,13 +22,13 @@ export const FIDIES_ANIMATION = {
export const THUMBNAIL_ANIMATION = {
initial: { y: 0 },
animate: {
y: [0, -10, 0, 10, 0],
y: [0, -13, 0, 13, 0],
},
transition: {
duration: 1,
duration: 2,
repeat: Infinity,
repeatType: 'mirror' as const,
ease: 'easeInOut',
repeatType: 'loop' as const,
ease: 'linear',
},
};

Expand Down
7 changes: 4 additions & 3 deletions src/pages/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ export const MapView = () => {
const [isInputDisabled, setIsInputDisabled] = useState(false);

const handleDataUpdate = useCallback(
(newData: Place[], type: BottomSheetType) => {
(newData: ExtractResponse | Place[], type: BottomSheetType) => {
clearMarkers();
newData?.forEach(addMarker);
if ('places' in newData) newData.places.forEach(addMarker);
if (Array.isArray(newData)) newData.forEach((place) => addMarker(place));
setState({ data: newData, type }, token);
},
Comment on lines +36 to 41
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

타입 처리 로직 개선이 필요합니다.

타입 가드를 사용하여 더 안전하게 타입을 처리할 수 있습니다. 현재 구현은 런타임 에러가 발생할 수 있습니다.

다음과 같이 개선하는 것을 제안합니다:

-(newData: ExtractResponse | Place[], type: BottomSheetType) => {
+(newData: ExtractResponse | Place[], type: BottomSheetType) => {
   clearMarkers();
-  if ('places' in newData) newData.places.forEach(addMarker);
-  if (Array.isArray(newData)) newData.forEach((place) => addMarker(place));
+  if ('places' in newData && Array.isArray(newData.places)) {
+    newData.places.forEach(addMarker);
+  } else if (Array.isArray(newData)) {
+    newData.forEach((place) => addMarker(place));
+  }
   setState({ data: newData, type }, token);
 }
📝 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
(newData: ExtractResponse | Place[], type: BottomSheetType) => {
clearMarkers();
newData?.forEach(addMarker);
if ('places' in newData) newData.places.forEach(addMarker);
if (Array.isArray(newData)) newData.forEach((place) => addMarker(place));
setState({ data: newData, type }, token);
},
(newData: ExtractResponse | Place[], type: BottomSheetType) => {
clearMarkers();
if ('places' in newData && Array.isArray(newData.places)) {
newData.places.forEach(addMarker);
} else if (Array.isArray(newData)) {
newData.forEach((place) => addMarker(place));
}
setState({ data: newData, type }, token);
},

[clearMarkers, addMarker, setState, token]
Expand All @@ -44,7 +45,7 @@ export const MapView = () => {
useEffect(() => {
const extractedData = location.state?.data;
if (extractedData?.places.length) {
handleDataUpdate(extractedData.places, 'extract');
handleDataUpdate(extractedData, 'extract');
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

데이터 유효성 검사가 필요합니다.

extractedData가 undefined일 경우나 places 배열이 없는 경우에 대한 처리가 필요합니다.

다음과 같이 수정하는 것을 제안합니다:

-      handleDataUpdate(extractedData, 'extract');
+      if (extractedData && Array.isArray(extractedData.places)) {
+        handleDataUpdate(extractedData, 'extract');
+      }
📝 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
handleDataUpdate(extractedData, 'extract');
if (extractedData && Array.isArray(extractedData.places)) {
handleDataUpdate(extractedData, 'extract');
}

}
}, [handleDataUpdate, location.state, setState, token]);

Expand Down
3 changes: 3 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export default {
zIndex: {
modal: '100',
},
screens: {
xs: '450px',
},
},
},
plugins: [],
Expand Down