Skip to content

feat: FM_SLD_01 뷰 구현 및 로직 수정 (#49)#65

Closed
gyogyo05 wants to merge 6 commits intodevelopfrom
feat/fm-sld-01-49
Closed

feat: FM_SLD_01 뷰 구현 및 로직 수정 (#49)#65
gyogyo05 wants to merge 6 commits intodevelopfrom
feat/fm-sld-01-49

Conversation

@gyogyo05
Copy link
Collaborator

📌 관련 이슈

✨ 변경 내용

  • 기존 pr에서의 coflict 해결
  • 목데이터 반영 코드
  • 다크모드 컴포넌트 반영

💡 참고 사항

image 모바일 뷰에서의 제목 수정 구현해야하고, 헤더의 info눌렀을 때 popover도 하드코딩이 아니라 데이터를 가져오도록 변경해야 함

@github-actions github-actions bot added component 컴포넌트 관련 변경 page 페이지 관련 변경 store 상태 관리 변경 config 설정 파일 변경 dependencies 의존성 변경 labels Jan 19, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gyogyo05, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 FM_SLD_01 뷰를 구현하고 관련 로직을 리팩토링합니다. 여러 UI 컴포넌트에 걸쳐 포괄적인 다크 모드 지원을 도입하고, 다크 테마 헤더 및 통합 피드백 입력과 같은 새로운 컴포넌트를 추가하며, FeedbackSlidePage를 데스크톱 및 모바일 반응형 레이아웃으로 크게 개선합니다. 주요 기능 추가 사항으로는 슬라이드 제목을 직접 편집하는 기능과 Zustand를 사용한 댓글 및 반응에 대한 더욱 견고한 상태 관리가 포함되어 슬라이드 전환 시 데이터 지속성을 보장합니다.

Highlights

  • 다크 모드 지원 확장: CommentInput, CommentItem, Layout, ReactionButtons 컴포넌트에 'theme' prop을 추가하고, clsx 유틸리티를 활용하여 다크 모드에 따른 스타일을 동적으로 적용하도록 업데이트되었습니다.
  • 새로운 UI 컴포넌트 추가: DarkHeader.tsx와 FeedbackInput.tsx 두 가지 새로운 컴포넌트가 추가되었습니다. DarkHeader는 다크 테마의 헤더를 제공하며, FeedbackInput은 댓글 입력과 반응 버튼을 통합하여 다양한 뷰 타입(전체, 반응 전용, 입력 전용)과 다크 모드를 지원합니다.
  • 피드백 슬라이드 페이지 리팩토링: FeedbackSlidePage.tsx가 데스크톱 및 모바일 레이아웃을 모두 지원하도록 대폭 리팩토링되었으며, 모바일 환경을 위한 스크립트/댓글 탭 시스템이 도입되었습니다. 새로운 DarkHeader 및 FeedbackInput 컴포넌트가 통합되었습니다.
  • 슬라이드 제목 편집 기능 구현: SlideViewer 내에서 슬라이드 제목을 직접 편집할 수 있는 기능이 추가되었으며, 즉각적인 UI 피드백을 위한 낙관적 업데이트(optimistic UI update)와 API 연동이 포함되었습니다.
  • Zustand 스토어 개선: slideStore.ts가 슬라이드 간 상태 지속성을 위해 globalOpinions 및 reactionMap을 관리하도록 업데이트되었으며, initSlide, deleteOpinion, addReply, toggleReaction, addOpinion 액션들이 새로운 상태 속성과 MOCK_CURRENT_USER를 사용하도록 수정되었습니다.
  • 의존성 추가 및 목킹 로직 개선: package.json에 @openai/codex 의존성이 추가되었고, main.tsx의 enableMocking 함수가 개발 환경에서 기본적으로 목킹을 활성화하도록 개선되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 피드백 페이지의 뷰를 구현하고 관련 로직을 수정한 중요한 변경사항을 담고 있네요. 특히 다크 모드 지원과 모바일/데스크탑 반응형 레이아웃을 구현한 점이 인상적입니다. ZustandReact Query를 사용한 상태 관리 및 낙관적 업데이트(Optimistic UI) 구현도 훌륭합니다.

몇 가지 개선점을 제안합니다.

  • package.json에 추가된 @openai/codex 의존성이 의도된 것인지 확인이 필요해 보입니다.
  • 일부 컴포넌트(DarkHeader, FeedbackSlidePage)에 하드코딩된 값들이 있는데, 이를 동적으로 처리하면 유지보수성이 향상될 것입니다.
  • FeedbackSlidePage 컴포넌트의 복잡도가 높아져서, 이를 더 작은 컴포넌트나 커스텀 훅으로 분리하는 리팩토링을 고려해볼 수 있습니다.

자세한 내용은 각 파일에 남긴 리뷰 코멘트를 참고해주세요. 전체적으로 완성도 높은 작업이라고 생각합니다. 수고 많으셨습니다!

onGoToSlideRef={goToSlideRef}
onDeleteComment={deleteComment}
<div className="fixed inset-0 z-[60] flex h-screen w-screen flex-col overflow-hidden bg-gray-900">
<DarkHeader title="Q4 마케팅 전략 발표" />
Copy link
Contributor

Choose a reason for hiding this comment

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

high

DarkHeader에 전달되는 title"Q4 마케팅 전략 발표"로 하드코딩되어 있습니다. 이 값은 projectId를 기반으로 API에서 동적으로 가져와야 합니다. 이는 사용자에게 올바른 정보를 보여주기 위해 중요합니다.

Suggested change
<DarkHeader title="Q4 마케팅 전략 발표" />
<DarkHeader title={currentSlide?.title ?? '발표 제목 로딩 중...'} />

"prepare": "husky"
},
"dependencies": {
"@openai/codex": "^0.87.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

@openai/codex 패키지가 추가되었는데, 이 프로젝트에서 사용될 예정인가요? 만약 의도치 않게 추가된 의존성이라면, 번들 크기를 줄이고 잠재적인 보안 위험을 피하기 위해 제거하는 것이 좋습니다.

Comment on lines +11 to +20
publisher?: string;
publishedAt?: string;
}

export const DarkHeader = ({
title,
renderRight,
publisher = '익명의 바다거북이',
publishedAt = '2025.11.25 21:10:34',
}: DarkHeaderProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

publisherpublishedAt이 선택적 프로퍼티로 정의되어 있고, 컴포넌트 내에서 하드코딩된 기본값을 가집니다. PR 설명에 언급된 대로 이 값들은 동적으로 받아와야 하므로, 필수 프로퍼티로 변경하고 기본값을 제거하여 부모 컴포넌트에서 명시적으로 값을 전달하도록 강제하는 것이 좋습니다.

Suggested change
publisher?: string;
publishedAt?: string;
}
export const DarkHeader = ({
title,
renderRight,
publisher = '익명의 바다거북이',
publishedAt = '2025.11.25 21:10:34',
}: DarkHeaderProps) => {
publisher: string;
publishedAt: string;
}
export const DarkHeader = ({
title,
renderRight,
publisher,
publishedAt,
}: DarkHeaderProps) => {

Comment on lines +117 to +122
className={[
'grid h-6 w-6 place-items-center rounded-full ',
isFirst
? 'bg-gray-800 opacity-30 cursor-not-allowed'
: 'bg-gray-800 hover:bg-gray-700 active:scale-95 transition',
].join(' ')}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

className을 동적으로 구성할 때 문자열 배열을 join(' ')으로 합치는 방식 대신, 프로젝트의 다른 부분에서 일관되게 사용하고 있는 clsx 유틸리티를 사용하는 것이 가독성과 유지보수성 측면에서 더 좋습니다. 이 버튼과 goNext 버튼 모두에 적용하는 것을 고려해보세요.

Suggested change
className={[
'grid h-6 w-6 place-items-center rounded-full ',
isFirst
? 'bg-gray-800 opacity-30 cursor-not-allowed'
: 'bg-gray-800 hover:bg-gray-700 active:scale-95 transition',
].join(' ')}
className={clsx(
'grid h-6 w-6 place-items-center rounded-full',
isFirst
? 'bg-gray-800 opacity-30 cursor-not-allowed'
: 'bg-gray-800 hover:bg-gray-700 active:scale-95 transition',
)}

<>
<Logo />
<span className="text-body-m-bold text-black">발표 피드백</span>
<span className="text-body-m-bold text-gray-100">?? ??</span>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

헤더의 발표 제목이 ?? ??로 하드코딩되어 있습니다. projectId를 사용하여 동적으로 발표 제목을 가져와 표시하도록 수정해야 합니다.

Suggested change
<span className="text-body-m-bold text-gray-100">?? ??</span>
<span className="text-body-m-bold text-gray-100">{/* TODO: 동적 제목 변수 */}</span>

import { useReactions } from '../hooks/useReactions';
import type { Slide } from '@/types/slide';

export default function FeedbackSlidePage() {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

FeedbackSlidePage 컴포넌트가 데이터 페칭, 여러 상태 관리(탭, 댓글, 제목 수정), 데스크탑/모바일 레이아웃 렌더링 등 너무 많은 책임을 가지고 있어 복잡도가 높습니다. 컴포넌트를 더 작은 단위로 분리하여 가독성과 유지보수성을 높이는 것을 고려해보세요. 예를 들어,

  • 제목 수정 관련 로직을 useTitleEditing과 같은 커스텀 훅으로 분리
  • 데스크탑과 모바일 레이아웃을 각각 DesktopLayout, MobileLayout 컴포넌트로 분리
  • commitTitle 함수의 낙관적 업데이트 로직은 복잡하므로, 로직의 흐름을 설명하는 주석을 추가하면 팀원들이 코드를 이해하는 데 도움이 될 것입니다.

globalOpinions: [],
reactionMap: {},

initSlide: (slide, slideIndex) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

initSlide 함수의 로직이 복잡해졌습니다. 상태를 복원할 때 globalOpinionsreactionMap을 우선적으로 사용하는 로직에 대해 주석을 추가하면, 다른 개발자가 코드를 이해하고 디버깅하는 데 큰 도움이 될 것입니다. 예를 들어, 각 단계에 대한 설명을 추가할 수 있습니다.

@github-actions
Copy link

Visit the preview URL for this PR (updated for commit 55f4cd8):

https://ttorang--pr65-feat-fm-sld-01-49-jvgz961m.web.app

(expires Mon, 26 Jan 2026 14:10:49 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: b554669f2531ae9a6954d553a841ad9a6c4ceb6d

@AndyH0ng AndyH0ng closed this Jan 19, 2026
@AndyH0ng AndyH0ng deleted the feat/fm-sld-01-49 branch January 19, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component 컴포넌트 관련 변경 config 설정 파일 변경 dependencies 의존성 변경 page 페이지 관련 변경 store 상태 관리 변경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: FM_SLD_01 화면 구현

2 participants