Skip to content

투표 제작 시 투표 상세 페이지에서 게시글 공유 바텀시트 활성화 작업을 구현한다. - #487

Merged
YOOJS1205 merged 8 commits into
developfrom
feature-486/share-bottomsheet
Dec 19, 2025
Merged

YOOJS1205 merged 8 commits into
developfrom
feature-486/share-bottomsheet

Conversation

@Jeongchanyeong

@Jeongchanyeong Jeongchanyeong commented Dec 10, 2025 •

Copy link
Copy Markdown
Collaborator

Motivation

Reference Links
Issue #486

Modification

기존 바텀시트 구조 리펙토링하여 투표 생성 시 공유하기 바텀시트 올라오도록 구현하였습니다.

Poll 생성 공유 바텀시트를 PollCreatedShareBottomSheet로 따로 빼서 도메인 컴포넌트로 쓸지, 그냥 BottomSheet에 조합해서 사용할지 고민되더라구요. 이런 상황에서 준상님은 어떤 기준으로 고민하고 결정하시는지 궁금해용.


Result

스크린샷 2025-12-11 오전 1 28 01

close #486


@github-actions github-actions Bot added the feature 피쳐 개발에 사용합니다. label Dec 10, 2025
@github-actions

Copy link
Copy Markdown

🤖 AI Code Review (OpenAI)

  • src/components/common/BottomSheet/BottomSheet.tsx/renderHeader 함수 부분

    • 이유: renderHeader가 JSX를 반환하는 함수인데, 매 렌더링마다 새로 생성됨. 이 함수가 컴포넌트 내부에 선언되어 있어 불필요한 재생성이 발생할 수 있음.
    • 개선 제안: useMemo를 사용해 variant, title, description, topContent가 변경될 때만 재생성하도록 최적화하거나, 별도 컴포넌트로 분리해도 좋음.
  • src/components/common/BottomSheet/BottomSheet.tsx/motion.div 초기 애니메이션 설정

    • 이유: initial={{ y: '100%', opacity: 1 }}인데, opacity가 1로 고정되어 있어 애니메이션 효과가 제한적임. 보통 바텀시트는 등장 시 opacity가 0에서 1로 변하는 경우가 많음.
    • 개선 제안: initial={{ y: '100%', opacity: 0 }}으로 변경해 자연스러운 페이드인 효과를 줄 수 있음.
  • src/components/common/BottomSheet/BottomSheet.tsx/닫기 버튼 위치

    • 이유: 닫기 버튼이 absolute로 위치 지정되어 있는데, top-[24px] right-[24px] 고정값이 variant에 따라 적절한지 확인 필요. 특히 'centered' variant에서 레이아웃과 겹치거나 어색할 수 있음.
    • 개선 제안: variant에 따라 닫기 버튼 위치를 조정하거나, 스타일을 variant별로 분리해 관리하는 것이 유지보수에 유리함.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx/openBottomSheet 호출 위치

    • 이유: navigate 호출 후 바로 openBottomSheet를 호출하는데, navigate가 비동기적으로 라우팅을 처리하므로 BottomSheet가 이전 페이지에 렌더링될 가능성이 있음.
    • 개선 제안: navigate 후 BottomSheet를 띄우려면 라우팅 완료 후 처리하는 로직이 필요하거나, BottomSheet를 라우트 내에서 관리하는 방식으로 변경하는 것이 안전함.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx/shareUrl 생성 방식

    • 이유: shareUrl에 ?shareUrl=${data.shareUrl} 쿼리 파라미터를 붙였는데, data.shareUrl이 이미 URL일 경우 중복되거나 의도치 않은 URL이 될 수 있음.
    • 개선 제안: 쿼리 파라미터 이름과 값이 명확한지, 중복되지 않는지 확인하고, 필요하다면 URL 빌더 유틸을 사용해 안전하게 생성할 것.
  • nit: src/components/common/BottomSheet/BottomSheet.tsx/renderHeader 내부 h1 태그

    • 이유: 'centered' variant에서는 h1에 text-heading-1, 'default' variant에서는 text-headline-1 클래스를 사용 중인데, 스타일 일관성이 떨어질 수 있음.
    • 개선 제안: 제목 스타일을 통일하거나 variant별로 명확히 구분해 관리하는 것이 좋음.
  • nit: src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx/이미지 alt 속성

    • 이유: alt가 단순히 "Share"로 되어 있는데, 접근성 측면에서 조금 더 구체적인 설명이 필요함.
    • 개선 제안: 예를 들어 "투표 공유 아이콘" 등 컨텍스트에 맞는 설명으로 변경 권장.
  • nit: src/components/common/BottomSheet/BottomSheet.tsx/hr 태그 삭제

    • 이유: 기존에 있던 <hr className="border-gray-200" />가 삭제되었는데, 디자인 의도인지 확인 필요.
    • 개선 제안: 디자인 가이드에 따라 필요하면 다시 추가하거나, 불필요하면 주석으로 이유 명시하면 좋음.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@YOOJS1205

Copy link
Copy Markdown
Contributor

Poll 생성 공유 바텀시트를 PollCreatedShareBottomSheet로 따로 빼서 도메인 컴포넌트로 쓸지, 그냥 BottomSheet에 조합해서 사용할지

말씀하신 두 방법이 어떤 차이가 있는건가요?!
지금 구현해주신 방법이 디자인 시스템 컴포넌트를 잘 사용하신 것 같아서요~!

Comment thread src/components/common/BottomSheet/BottomSheet.tsx Outdated
const isCentered = variant === 'centered';

const renderHeader = () =>
isCentered ? (

@YOOJS1205 YOOJS1205 Dec 15, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

기존엔
title을 받고, 나머지 컨텐츠를 children으로 전달하는 형태인데,
왜 center 케이스에는 description, topContent를 별도로 받는 형태로 설계하셨나요?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

음 기존 설계와 일관성이 떨어지긴 하네요. children으로 넘기는 형태로 수정하겠습니다.

Co-authored-by: 유준상 (1팀 프론트) <89122773+YOOJS1205@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🤖 AI Code Review (OpenAI)

  • src/components/common/BottomSheet/BottomSheet.tsx + 상단:
    BottomSheetVariant 타입에 'left' | 'center'만 정의되어 있는데, 기본값으로 'default'가 설정되어 있음.
    → 타입과 기본값이 일치하지 않아 타입 안정성이 깨짐. 'default'를 'center' 혹은 'left' 중 하나로 변경하거나, 'default'를 타입에 추가하고 처리 로직도 추가하는 것이 좋음.

  • src/components/common/BottomSheet/BottomSheet.tsx + renderHeader 함수 내부:
    isCentered 변수는 variant === 'centered'로 비교하는데, 타입에는 'center'로 정의되어 있음.
    → 'centered'와 'center'가 불일치하여 조건이 항상 false가 됨. 타입과 비교값을 일치시켜야 함.

  • src/components/common/BottomSheet/BottomSheet.tsx + motion.div:
    initial prop에 opacity: 1이 지정되어 있는데, 보통 모션 초기 상태는 opacity: 0으로 시작해 자연스러운 페이드인 효과를 주는 경우가 많음.
    → 의도된 애니메이션 효과인지 확인 필요. 만약 페이드인 효과를 원한다면 opacity: 0으로 수정 권장.

  • src/components/common/BottomSheet/BottomSheet.tsx + 스타일링:
    h1 태그에 border-gray-400 클래스가 있으나, 실제로 border 속성이 지정되어 있지 않아 효과가 없음.
    → border 속성을 명시하거나 불필요하면 클래스 제거 권장.

  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + onSuccess 콜백:
    shareUrl 생성 시 쿼리 파라미터로 shareUrl을 다시 붙이고 있음 (?shareUrl=${data.shareUrl})
    → 중복되거나 불필요한 파라미터일 가능성이 있음. data.shareUrl 값이 무엇인지 확인하고, URL 생성 로직을 명확히 할 필요 있음.

  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + BottomSheet 사용:
    openBottomSheet에 JSX를 직접 넘기는데, BottomSheet 훅의 내부 구현에 따라 메모리 누수나 상태 관리 이슈가 발생할 수 있음.
    → BottomSheet 훅의 사용법 문서나 구현을 확인해, 컴포넌트를 직접 넘기는 방식이 적절한지 검토 필요.

  • nit:

    • src/components/common/BottomSheet/BottomSheet.tsx: renderHeader 함수는 컴포넌트 내부에서 선언되어 매 렌더링마다 새로 생성됨. 성능상 큰 문제는 아니지만, 필요시 useMemo로 최적화 가능.
    • src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx: alt 텍스트가 단순히 "Share"인데, 좀 더 구체적으로 이미지 의미를 설명하면 접근성 향상 가능.
    • src/components/common/BottomSheet/BottomSheet.tsx: motion.div에 className이 너무 길고 하드코딩된 픽셀 단위가 많음. Tailwind의 spacing scale을 활용해 유지보수성을 높일 수 있음.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions

Copy link
Copy Markdown

🤖 AI Code Review (OpenAI)

  • src/components/common/BottomSheet/BottomSheet.tsx + renderHeader 함수 분리 부분

    • 이유: renderHeader 함수가 JSX를 반환하는데, 함수 내부에 JSX가 직접 포함되어 있어 가독성은 괜찮으나, isCentered 변수와 함수가 컴포넌트 내부에 같이 선언되어 있어 재렌더링 시 매번 새로 생성됨.
    • 개선 제안: renderHeader를 컴포넌트 외부로 분리하거나 useMemo를 사용해 불필요한 재생성을 방지하면 성능 최적화에 도움이 됨.
  • src/components/common/BottomSheet/BottomSheet.tsx + motion.div 초기 애니메이션 설정

    • 이유: initial={{ y: '100%', opacity: 1 }}로 되어 있는데, opacity가 1로 고정되어 있어 초기 상태에서 투명도 변화가 없음. 만약 의도한 애니메이션이 투명도 변화라면 의미가 없고, 그렇지 않다면 불필요한 속성임.
    • 개선 제안: opacity 애니메이션이 필요 없다면 initial에서 opacity를 제거하거나, 투명도 변화가 필요하면 적절한 값으로 수정.
  • src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx + 이미지 import 및 alt 속성

    • 이유: 이미지 import는 잘 되어 있으나 alt 텍스트가 단순히 "Share"로 되어 있어 접근성 측면에서 구체적이지 않음.
    • 개선 제안: alt 텍스트를 "투표 공유 이미지" 등 더 구체적으로 작성해 접근성을 높일 것.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + openBottomSheet 호출 위치

    • 이유: navigate 호출 후 바로 openBottomSheet를 호출하는데, navigate가 비동기적으로 동작할 수 있어 BottomSheet가 이전 페이지에 렌더링될 가능성이 있음.
    • 개선 제안: navigate 후 BottomSheet를 띄우려면 페이지 전환 후에 띄우는 로직이 필요하거나, 페이지 전환 없이 BottomSheet를 띄우는 UX 검토가 필요함.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + shareUrl 생성 방식

    • 이유: shareUrl에 ?shareUrl=${data.shareUrl} 쿼리 파라미터가 중복되어 보임. data.shareUrl이 이미 URL인지 확인 필요.
    • 개선 제안: shareUrl 생성 로직을 명확히 하여 중복 쿼리 파라미터가 생기지 않도록 수정할 것.
  • nit: src/components/common/BottomSheet/BottomSheet.tsx + 클래스명 오타 및 일관성

    • 이유: text-heading-1과 text-headline-1이 혼용되고 있는데, 디자인 시스템에 따라 일관성 필요.
    • 개선 제안: 디자인 가이드에 맞게 클래스명 통일.
  • nit: src/components/common/BottomSheet/BottomSheet.tsx + 불필요한 빈 줄 제거

    • 이유: JSX 내 불필요한 빈 줄이 있어 코드가 다소 산만해 보임.
    • 개선 제안: 빈 줄 정리로 가독성 향상.
  • nit: src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx + 버튼과 일반 버튼 스타일 통일

    • 이유: 카카오 공유 버튼은 Button 컴포넌트를 사용하고, "나중에 하기"는 일반 button 태그로 스타일이 다름.
    • 개선 제안: 일관된 UI/UX를 위해 두 버튼 모두 Button 컴포넌트 사용 고려.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions

Copy link
Copy Markdown

🤖 AI Code Review (OpenAI)

  • src/components/common/BottomSheet/BottomSheet.tsx + 전체

    • align prop에 'centered'를 사용하는데, BottomSheetProps에 variant라는 이름으로 전달하는 곳이 있음 (PollCreatedShareBottomSheet에서 variant="centered" 사용). 실제 컴포넌트에서는 align을 받고 있어 prop 이름 불일치로 인해 의도한 정렬이 적용되지 않을 가능성이 큼.
    • 개선 제안: variant 대신 align으로 통일하거나, variant를 align으로 매핑하는 로직 추가 필요.
  • src/components/common/BottomSheet/BottomSheet.tsx + renderHeader 함수

    • renderHeader 함수 내 h1 태그에 border-gray-400 클래스가 있는데, border 스타일이 빠져 있어 의도한 스타일이 적용되지 않을 수 있음.
    • 개선 제안: border-b 등 구체적인 border 스타일 클래스를 명시해주기.
  • src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx + 전체

    • BottomSheet에 variant="centered" prop 전달 중인데, BottomSheet 컴포넌트에는 variant prop이 없고 align prop이 있음. 이로 인해 중앙 정렬이 적용되지 않을 가능성이 큼.
    • 개선 제안: variant → align으로 수정 필요.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + useBottomSheet 사용 부분

    • openBottomSheet에 JSX를 직접 넘기고 있는데, useBottomSheet 훅의 구현에 따라 컴포넌트가 제대로 렌더링되지 않을 수 있음. openBottomSheet가 JSX를 받는 API인지 확인 필요.
    • 개선 제안: openBottomSheet가 JSX를 받는 API가 아니라면, BottomSheet를 상태로 관리하거나 별도의 모달 관리 로직을 사용하는 것이 안전함.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + shareUrl 생성 부분

    • shareUrl에 쿼리 파라미터로 shareUrl을 중복해서 넣고 있음 (?shareUrl=${data.shareUrl}), 의도한 값인지 확인 필요.
    • 개선 제안: 쿼리 파라미터 이름과 값이 중복되어 혼란을 줄 수 있으니, 파라미터 이름을 명확히 하거나 불필요하면 제거.
  • nit (사소한 부분)

    • BottomSheet.tsx에서 renderHeader 함수 내 div와 h1 태그에 px-6이 중복 적용되어 있음. 스타일 중복 최소화 가능.
    • PollCreatedShareBottomSheet.tsx에서 alt 텍스트가 단순히 "Share"인데, 좀 더 구체적으로 "투표 공유 이미지" 등으로 의미를 명확히 하면 접근성 향상 가능.
    • PollCreatedShareBottomSheet.tsx 내 버튼과 텍스트 버튼 간 스타일링이 다소 다름. UI 일관성을 위해 스타일 가이드 점검 권장.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions

Copy link
Copy Markdown

🤖 AI Code Review (OpenAI)

  • src/components/common/BottomSheet/BottomSheet.tsx/헤더 렌더링 분리 및 align prop 추가 관련

    • renderHeader 함수가 컴포넌트 내부에 선언되어 매 렌더링마다 새로 생성됨. 성능상 큰 문제는 아니지만, 함수형 컴포넌트 밖으로 분리하거나 useMemo로 메모이제이션하는 것이 좋음.
    • align 타입에 'centered'만 있고 'right' 같은 다른 옵션이 없는데, 확장성을 고려한다면 enum 혹은 union 타입을 좀 더 명확히 관리하는 게 좋음.
  • src/components/common/BottomSheet/BottomSheet.tsx/클래스명 오타 및 스타일링 문제

    • 왼쪽 정렬 헤더의 클래스명에 text-headline-1과 border-gray-400이 있는데, border-gray-400만 있고 border 스타일(두께, 위치 등)이 빠져 있어 의도한 스타일이 아닐 수 있음. 실제로 border가 보이지 않을 가능성 있음.
    • pl-5 등 패딩 단위가 Tailwind 기본 단위(4px 단위)와 다를 수 있으니, 디자인 가이드와 맞는지 확인 필요.
  • src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx/불필요한 useBottomSheet import 및 사용

    • useBottomSheet에서 closeBottomSheet를 받아서 바로 버튼에 할당하는데, BottomSheet 컴포넌트에 hasCloseButton prop을 넘겨 닫기 버튼을 렌더링하고 있음. 닫기 버튼 클릭 시 closeBottomSheet가 호출되도록 내부에서 처리하는 게 더 일관적임. 현재는 닫기 버튼과 별개로 "나중에 하기" 버튼에만 closeBottomSheet가 연결되어 있음.
    • 닫기 버튼과 "나중에 하기" 버튼 모두 닫기 동작을 하므로, UX 측면에서 중복일 수 있음. 필요하다면 역할 분리 또는 하나로 통일하는 게 좋음.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx/BottomSheet 사용 시점 및 URL 생성

    • shareUrl 생성 시 window.location.origin을 직접 사용하고 있는데, SSR 환경이나 테스트 환경에서 문제가 될 수 있음. 가능하면 환경변수나 라우터의 base URL을 활용하는 게 안전함.
    • openBottomSheet에 JSX를 직접 넘기고 있는데, BottomSheet 훅이 내부적으로 어떻게 처리하는지 모르지만, 컴포넌트 인스턴스를 직접 넘기는 방식은 유지보수나 타입 안정성 측면에서 위험할 수 있음. 가능하면 BottomSheet 훅에서 컴포넌트 타입과 props를 받아 렌더링하는 방식을 권장.
    • navigate 호출 후 바로 openBottomSheet를 호출하는데, 페이지 이동과 모달 오픈이 동시에 일어나면 모달이 의도대로 동작하지 않을 수 있음. 페이지 이동 후 모달 오픈 로직을 분리하거나, 페이지 이동 없이 모달만 띄우는 UX를 고려해야 함.
  • nit

    • src/components/common/BottomSheet/BottomSheet.tsx: BottomSheetAlign 타입을 export하지 않아 외부에서 재사용 불가능. 필요하다면 export 고려.
    • src/components/common/PollCreatedShareBottomSheet/PollCreatedShareBottomSheet.tsx: 이미지 alt 텍스트가 단순히 "Share"인데, 좀 더 구체적인 설명(예: "투표 공유 이미지")이 접근성에 좋음.
    • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx: import 순서가 섞여 있음. 외부 라이브러리, 내부 훅, 컴포넌트 순으로 정리하면 가독성 향상.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@YOOJS1205
YOOJS1205 merged commit 475d094 into develop Dec 19, 2025
5 checks passed
@YOOJS1205
YOOJS1205 deleted the feature-486/share-bottomsheet branch December 19, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 피쳐 개발에 사용합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

투표 제작 시 투표 상세 페이지에서 게시글 공유 바텀시트 활성화 작업을 구현한다.

2 participants