Skip to content

[feat] 주제 제안 UI 및 기능 구현#68

Merged
haruyam15 merged 2 commits intodevelopfrom
feat/topics-propose-66
Feb 9, 2026
Merged

[feat] 주제 제안 UI 및 기능 구현#68
haruyam15 merged 2 commits intodevelopfrom
feat/topics-propose-66

Conversation

@haruyam15
Copy link
Contributor

@haruyam15 haruyam15 commented Feb 8, 2026

🚀 풀 리퀘스트 제안

📋 작업 내용

주제 제안 기능을 위한 페이지, API, 훅, 타입, 상수를 추가했습니다.

🔧 변경 사항

새로운 파일

  • TopicCreatePage.tsx` - 주제 제안 페이지 컴포넌트 (타입 선택, 제목, 설명 입력 폼)
  • useCreateTopic.ts` - 주제 생성 mutation 훅
  • topics.constants.ts` - TopicType 메타 정보 상수 (TOPIC_TYPE_META, TOPIC_TYPE_OPTIONS)

수정된 파일

  • topics.api.ts` - createTopic API 함수 추가
  • topics.endpoints.ts` - 주제 생성 엔드포인트 추가
  • topics.types.ts` - CreateTopicParams, CreateTopicRequest, CreateTopicResponse 타입 추가
  • src/shared/constants/routes.ts - 주제 제안 경로 상수 추가

📸 스크린샷 (선택 사항)

image

Summary by CodeRabbit

새로운 기능

  • 주제 제안 기능 추가: 사용자가 제목, 설명 및 주제 유형을 선택하여 모임 내에서 새로운 주제를 제안할 수 있습니다. 주제 유형에 따른 설명 및 가이드가 제공됩니다.

주제 제안 기능을 위한 페이지, API, 훅, 타입, 상수를 추가.
- TopicCreatePage 컴포넌트 구현 (타입 선택, 제목, 설명 입력)
- useCreateTopic mutation 훅 추가
- createTopic API 함수 및 엔드포인트 추가
- TopicType 메타 정보 상수화 (TOPIC_TYPE_META, TOPIC_TYPE_OPTIONS)
- 관련 타입 정의 추가 (CreateTopicParams, CreateTopicRequest, CreateTopicResponse)
- 라우트 및 경로 상수 추가
@haruyam15 haruyam15 self-assigned this Feb 8, 2026
@haruyam15 haruyam15 added the feat 새로운 기능 추가 label Feb 8, 2026
@haruyam15 haruyam15 linked an issue Feb 8, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Feb 8, 2026

Warning

Rate limit exceeded

@haruyam15 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

주제 제안 기능을 구현합니다. API 함수, React Query 훅, 페이지 컴포넌트, 라우팅, 타입, 상수를 추가하여 사용자가 새 주제를 생성하고 제안할 수 있도록 지원합니다.

Changes

Cohort / File(s) Summary
Topic Creation Types & API
src/features/topics/topics.types.ts, src/features/topics/topics.api.ts, src/features/topics/topics.endpoints.ts
CreateTopicParams, CreateTopicRequest, CreateTopicResponse 타입 추가. createTopic API 함수 구현 (mock 모드 지원). TOPICS_ENDPOINTS.CREATE 엔드포인트 추가.
Topic Creation Hook & Constants
src/features/topics/hooks/useCreateTopic.ts, src/features/topics/hooks/index.ts, src/features/topics/topics.constants.ts, src/features/topics/index.ts
useCreateTopic React Query 훅 추가. TOPIC_TYPE_META, TOPIC_TYPE_OPTIONS 상수 정의. 모듈 내보내기 업데이트.
Topic Create Page & Routing
src/pages/Topics/TopicCreatePage.tsx, src/pages/Topics/index.ts, src/pages/index.ts, src/routes/index.tsx, src/shared/constants/routes.ts
TopicCreatePage 컴포넌트 구현 (폼 검증, 상태 관리, 오류 처리). TOPICS_CREATE 라우트 패턴 /gatherings/:gatheringId/meetings/:meetingId/topic-create 추가.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Page as TopicCreatePage
    participant Hook as useCreateTopic
    participant API as createTopic API
    participant Server as Server/Mock
    participant Cache as Query Cache

    User->>Page: 주제 정보 입력 및 제출
    Page->>Page: validateForm() - 검증
    Page->>Hook: mutation.mutate(params)
    Hook->>API: createTopic({ gatheringId, meetingId, body })
    alt Mock Mode Enabled
        API-->>Server: Mock 응답 반환 (인위적 지연)
    else Real API
        API->>Server: POST /gatherings/{id}/meetings/{id}/topics
        Server-->>API: CreateTopicResponse
    end
    API-->>Hook: 응답 완료
    Hook->>Cache: queryClient.invalidateQueries(topicQueryKeys.proposedList)
    Cache->>Cache: 제안 주제 목록 캐시 무효화
    Hook-->>Page: onSuccess 콜백
    Page->>User: 토스트 표시 및 뒤로 이동
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • mgYang53
  • choiyoungae
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 명확하게 요약하고 있습니다. 주제 제안 기능의 UI와 구현을 추가하는 것이 정확히 표현되어 있습니다.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/topics-propose-66

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.

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

🤖 Fix all issues with AI agents
In `@src/features/topics/topics.types.ts`:
- Around line 217-224: Decide and finalize how to represent an absent topic
description in the API, then update the CreateTopicRequest type and remove the
TODO: if the API expects explicit null, keep description: string | null; if it
expects an empty string use description: string; if it expects omission use
description?: string (or description?: string | null for both omission and
null), and adjust any request serialization/validation code that references
CreateTopicRequest so it sends the correct form (null vs "" vs omitted). Ensure
the TypeScript type, any validators, and client-side serializer (code paths that
construct CreateTopicRequest) are all updated consistently.
- Around line 229-238: CreateTopicResponse currently leaves a TODO about how
description null/empty should be handled; make its description field consistent
with the request type (the CreateTopicRequest/CreateTopicPayload used at line
~220) by matching the exact union/optional type (e.g., string | null or optional
string) used in the request, update the CreateTopicResponse type signature
accordingly, and remove the TODO comment so both request and response types are
aligned.

In `@src/pages/Topics/TopicCreatePage.tsx`:
- Around line 76-79: The back navigation paragraph in TopicCreatePage lacks a
click handler, so add an onClick to the element rendering the back UI (the <p>
that contains <ChevronLeft />) to call navigate(-1) like the success flow;
ensure accessibility by setting role="button" and tabIndex={0} and reuse the
existing navigate function from the component scope so the back action behaves
identically to the existing success handler.
- Around line 45-71: In handleSubmit, avoid passing NaN to the API by converting
gatheringId and meetingId to numbers first and validating them (use Number(...)
-> const gathering = Number(gatheringId), const meeting = Number(meetingId)) and
check !Number.isNaN(gathering) && gathering > 0 and !Number.isNaN(meeting) &&
meeting > 0 before calling createMutation.mutate; if validation fails, abort and
surface an error (e.g., openError or a user-facing message) similar to the
pattern used in useProposedTopics so invalid or direct-URL accesses don't send
NaN to the backend.

In `@src/routes/index.tsx`:
- Around line 117-120: 현재 하드코딩된 경로를 ROUTES.TOPICS_CREATE 함수형 상수로 대체하세요: locate
the route entry using TopicCreatePage (the object with path
`${ROUTES.GATHERINGS}/:gatheringId/meetings/:meetingId/topic-create`) and
replace the inline template with a call to ROUTES.TOPICS_CREATE(':gatheringId',
':meetingId') so routing is centralized and consistent with
ROUTES.PRE_OPINIONS(':gatheringId', ':meetingId').
🧹 Nitpick comments (1)
src/features/topics/topics.endpoints.ts (1)

19-22: CREATEPROPOSED가 동일한 URL을 생성합니다 — 의도된 것이라면 OK.

HTTP 메서드(GET vs POST)로 구분되므로 기능상 문제는 없습니다. 다만 중복 로직이므로, 향후 경로 변경 시 양쪽 모두 수정해야 하는 점은 인지해 두세요.

Copy link
Contributor

@mgYang53 mgYang53 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다! 👍

<>
{/* 공통컴포넌트로 교체 예정 */}
<div className="sticky top-0 bg-white -mt-xlarge">
<p className="flex typo-body3 text-grey-600 gap-xtiny py-medium">
Copy link
Contributor

Choose a reason for hiding this comment

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

뒤로 가기 공통 컴포넌트는 제가 레이아웃 정리 작업할 때 같이 진행하면 되는건가요?

Copy link
Contributor

Choose a reason for hiding this comment

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

이거 제가 작업해둔 거 있어요 SubPageHeader

Copy link
Contributor Author

Choose a reason for hiding this comment

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

땡큐베리 감사합니다

@haruyam15 haruyam15 merged commit 5c5f43a into develop Feb 9, 2026
2 checks passed
@haruyam15 haruyam15 deleted the feat/topics-propose-66 branch February 9, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 주제 제안 UI 및 기능 구현

3 participants