Skip to content

feat: 프로그레스 바 구현#76

Merged
ljh130334 merged 6 commits intodevelopfrom
feat/progressbar
Aug 4, 2025
Merged

feat: 프로그레스 바 구현#76
ljh130334 merged 6 commits intodevelopfrom
feat/progressbar

Conversation

@ljh130334
Copy link
Member

@ljh130334 ljh130334 commented Aug 4, 2025

#️⃣ 연관된 이슈

따로 등록하지 않았습니다.

📝 작업 내용

기록 작성 및 투표 생성 후 기록장에서 업로드 진행 상황을 사용자에게 알리는 프로그레스 바를 구현했습니다. 기록 작성/투표 생성 완료 버튼을 누르면 즉시 기록장으로 이동하고, 기록 탭 바로 아래에 "기록을 게시 중입니다..." 텍스트와 함께 녹색 프로그레스 바가 표시됩니다. 프로그레스 바가 100% 완료되면 "기록이 게시되었습니다!" 메시지로 변경된 후 1초 뒤 자동으로 사라집니다. 전체 프로세스는 약 4초 소요되며, 완료 후 새로 작성된 기록이 목록에 정상적으로 표시됩니다.

✔️ 주요 변경사항

  • UploadProgressBar 컴포넌트 신규 생성 (탭 하단 프로그레스 바)
  • MemoryContent 컴포넌트에 프로그레스 바 표시 로직 추가
  • Memory 컴포넌트에서 업로드 상태 관리 및 완료 처리
  • RecordWrite, PollWrite 컴포넌트에서 업로드 중 상태로 기록 생성
  • PollCreationSection 컴포넌트 props 이름 통일 (content, options 등)

스크린샷 (선택)

2025-08-05.3.29.57.mov

💬 리뷰 요구사항(선택)

프로그레스 바의 지속 시간(현재 3초)이 적절한지, 사용자 경험 측면에서 더 나은 타이밍이 있을지 의견을 부탁드립니다.

Summary by CodeRabbit

  • 신규 기능

    • 업로드 진행 상황을 보여주는 업로드 진행 바가 메모리 화면에 추가되었습니다.
    • 새로운 업로드가 시작될 때 업로드 진행 바가 자동으로 표시되고, 완료 시 사라집니다.
  • 버그 수정

    • 필터 및 페이지 범위 선택 시 동작이 더욱 직관적으로 개선되었습니다.
    • 뒤로 가기 버튼이 그룹 페이지로 이동하도록 변경되었습니다.
  • 리팩터링

    • 투표 작성 및 옵션 관련 변수 명칭이 더 간결하게 변경되었습니다.
  • 스타일

    • 업로드 진행 바에 시각적 효과가 추가되었습니다.
  • 기타

    • 새 기록 및 투표 생성 시 사용자 정보와 시간 표시가 실제 값으로 업데이트되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Aug 4, 2025

Walkthrough

이 변경 사항은 업로드 진행 상태를 시각적으로 표시하는 UploadProgressBar 컴포넌트를 도입하고, 관련 prop 및 상태 관리를 MemoryContent와 메모리 페이지 전체에 통합합니다. 또한, 설문 작성 컴포넌트의 prop 명칭을 일관성 있게 변경하고, 레코드 생성 시 업로드 상태 플래그와 사용자 정보를 갱신합니다.

Changes

Cohort / File(s) Change Summary
Memory 업로드 진행 표시 통합
src/components/memory/MemoryContent/MemoryContent.tsx, src/components/memory/UploadProgressBar/UploadProgressBar.tsx, src/pages/memory/Memory.tsx
UploadProgressBar 컴포넌트 신설 및 통합. 업로드 진행 표시를 위한 prop(showUploadProgress, onUploadComplete) 추가 및 상태 관리. 업로드 중인 레코드 감지 및 진행 상태 표시, 완료 시 콜백 처리 추가.
설문 작성 prop 명칭 일관화
src/components/pollwrite/PollCreationSection.tsx, src/pages/pollwrite/PollWrite.tsx
설문 작성 관련 prop 및 변수명을 pollContent, pollOptions 등에서 content, options 등으로 일관되게 변경. 인터페이스 및 컴포넌트 시그니처, 내부 변수명 일괄 수정.
레코드/설문 생성 시 업로드 상태 및 사용자 정보 갱신
src/pages/recordwrite/RecordWrite.tsx, src/pages/pollwrite/PollWrite.tsx
새 레코드/설문 생성 시 isUploading 플래그 추가, 사용자명 및 포인트 필드 값을 실제 값으로 변경, 시간 정보 갱신. 업로드 중 상태를 네비게이션 state로 전달하도록 수정.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RecordWrite
    participant Memory
    participant MemoryContent
    participant UploadProgressBar

    User->>RecordWrite: 새 레코드 작성 후 저장
    RecordWrite->>Memory: /memory로 이동 (state에 isUploading 포함)
    Memory->>MemoryContent: showUploadProgress=true 전달
    MemoryContent->>UploadProgressBar: isVisible=true, onComplete 전달
    UploadProgressBar->>UploadProgressBar: 진행 바 애니메이션
    UploadProgressBar-->>MemoryContent: onComplete 콜백 호출
    MemoryContent-->>Memory: onUploadComplete 호출
    Memory->>MemoryContent: showUploadProgress=false 전달
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Suggested reviewers

  • ho0010

Poem

🐇
새하얀 바에 색이 차오르네,
업로드 진행이 한눈에 보이네!
이름도 반듯하게, prop도 정갈하게,
메모리 속 기록들이 환하게 웃네.
토끼는 오늘도 귀를 쫑긋 세우고,
새로운 변화에 깡충깡충 춤추네!

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62ceda4 and b1dec0c.

📒 Files selected for processing (2)
  • src/components/pollwrite/PollCreationSection.tsx (5 hunks)
  • src/pages/memory/Memory.tsx (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/pollwrite/PollCreationSection.tsx
🔇 Additional comments (10)
src/pages/memory/Memory.tsx (10)

35-41: 유틸리티 함수가 잘 구현되었습니다.

중복 레코드 추가를 방지하는 로직이 명확하고 효율적으로 구현되어 있습니다. 컴포넌트 외부로 추출하여 재사용성을 높인 점도 좋습니다.


55-56: 업로드 진행 상태 관리가 적절합니다.

업로드 프로그레스 바 표시를 위한 상태가 명확하게 정의되어 있습니다.


137-139: 업로드 완료 핸들러가 잘 구현되었습니다.

useCallback을 사용하여 메모이제이션한 점이 좋습니다.


180-183: 필터링 로직의 early return이 개선되었습니다.

페이지 타입이 아니거나 pageRange가 없는 경우 조기에 false를 반환하는 로직이 성능상 유리합니다.


196-198: 네비게이션 로직 변경을 확인해주세요.

navigate(-1)에서 navigate('/group')으로 변경되었는데, 이것이 의도된 동작인지 확인이 필요합니다. 사용자가 다른 경로에서 접근했을 때 예상과 다른 동작을 할 수 있습니다.

사용자 경험 관점에서 뒤로가기 동작이 항상 '/group'으로 이동하는 것이 적절한지 검토해보세요.


200-205: 탭 변경 시 필터 초기화 로직이 적절합니다.

탭을 변경할 때 필터와 페이지 범위를 초기화하는 것은 사용자 경험상 올바른 접근입니다.


207-219: 필터 토글 로직이 잘 구현되었습니다.

같은 필터를 다시 클릭했을 때 해제되는 기능이 직관적입니다. useCallback을 사용한 최적화도 적절합니다.


229-232: 페이지 범위 설정 시 자동 필터 변경이 좋은 UX입니다.

페이지 범위를 설정할 때 자동으로 '페이지별 보기'로 변경하는 것은 사용자의 의도를 잘 반영한 기능입니다.


252-260: MemoryContent 컴포넌트에 새로운 props 전달이 적절합니다.

업로드 프로그레스 관련 props(showUploadProgress, onUploadComplete)가 올바르게 전달되고 있습니다.


268-274: Snackbar 메시지 변경을 확인해주세요.

읽기 진행률 경고에서 성공적인 기록 저장 메시지로 변경되었는데, 이 Snackbar가 언제 표시되는지 확인이 필요합니다. 현재 코드에서는 showSnackbar 상태를 true로 설정하는 로직이 보이지 않습니다.

showSnackbar 상태를 true로 설정하는 트리거가 어디에 있는지 확인해주세요.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/progressbar

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@ljh130334 ljh130334 added ✨ Feature 기능 개발 🎨 Html&css 마크업 & 스타일링 labels Aug 4, 2025
@vercel
Copy link

vercel bot commented Aug 4, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thip ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 4, 2025 6:43pm

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

🧹 Nitpick comments (5)
src/pages/recordwrite/RecordWrite.tsx (1)

42-42: 타입 확장 방식을 개선하세요.

현재 인라인으로 타입을 확장하는 방식보다는 별도 인터페이스로 정의하는 것이 더 명확합니다.

파일 상단에 다음과 같이 정의하세요:

+ interface UploadingRecord extends Record {
+   isUploading?: boolean;
+ }

- const newRecord: Record & { isUploading?: boolean } = {
+ const newRecord: UploadingRecord = {
src/pages/pollwrite/PollWrite.tsx (1)

53-53: 타입 확장 방식을 일관되게 개선하세요.

RecordWrite.tsx와 동일한 타입 확장 방식을 사용하고 있습니다. 두 파일 모두에서 일관된 방식으로 개선하는 것이 좋겠습니다.

RecordWrite.tsx와 동일하게 별도 인터페이스로 정의하세요:

+ interface UploadingRecord extends Record {
+   isUploading?: boolean;
+ }

- const newPollRecord: Record & { isUploading?: boolean } = {
+ const newPollRecord: UploadingRecord = {
src/components/memory/UploadProgressBar/UploadProgressBar.tsx (1)

31-34: 완료 후 지연시간을 상수로 추출하는 것을 고려하세요.

1초 지연시간이 하드코딩되어 있습니다. duration과 interval처럼 상수로 추출하면 더 유지보수하기 좋을 것입니다.

  const duration = 3000; // 3초
  const interval = 50; // 50ms마다 업데이트
+ const completionDelay = 1000; // 완료 메시지 표시 시간
  const increment = (100 / duration) * interval;

  // ... 중간 코드 ...

  setTimeout(() => {
    onComplete();
- }, 1000); // 1초 후 완료 (완료 메시지를 보여주기 위해)
+ }, completionDelay); // 완료 메시지를 보여주기 위한 지연
src/pages/memory/Memory.tsx (2)

63-83: 테스트 데이터 개선을 고려해보세요.

반복되는 텍스트 패턴보다는 다양한 내용의 더 현실적인 테스트 데이터를 사용하는 것이 테스트와 개발에 도움이 될 것 같습니다.

- '공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다.',
+ '오늘 책을 읽으면서 느낀 점들을 정리해보았습니다. 특히 주인공의 성장 과정이 인상적이었고, 작가의 문체도 매우 흥미로웠습니다. 다음 챕터가 기대됩니다.',

210-242: 사용자 경험을 개선하는 좋은 변경사항들입니다.

탭 변경 시 필터 초기화, 필터 토글 기능, 페이지 범위 설정 시 자동 필터 활성화 등이 직관적으로 구현되었습니다.

하드코딩된 '/group' 경로를 상수나 props로 관리하면 더 유연한 구조가 될 것 같습니다:

+ const BACK_NAVIGATION_PATH = '/group';
+
  const handleBackClick = () => {
-   navigate('/group');
+   navigate(BACK_NAVIGATION_PATH);
  };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bef817f and 62ceda4.

📒 Files selected for processing (6)
  • src/components/memory/MemoryContent/MemoryContent.tsx (4 hunks)
  • src/components/memory/UploadProgressBar/UploadProgressBar.tsx (1 hunks)
  • src/components/pollwrite/PollCreationSection.tsx (5 hunks)
  • src/pages/memory/Memory.tsx (5 hunks)
  • src/pages/pollwrite/PollWrite.tsx (4 hunks)
  • src/pages/recordwrite/RecordWrite.tsx (2 hunks)
🔇 Additional comments (15)
src/components/pollwrite/PollCreationSection.tsx (1)

15-26: prop 이름 표준화가 잘 적용되었습니다.

더 일반적이고 재사용 가능한 prop 이름으로 변경한 것이 좋습니다. 컴포넌트의 재사용성과 일관성이 향상되었습니다.

src/pages/recordwrite/RecordWrite.tsx (1)

65-69: 업로드 상태와 네비게이션 로직이 잘 구현되었습니다.

업로드 중인 기록을 state로 전달하여 Memory 페이지에서 진행률 바를 표시할 수 있도록 하는 구조가 적절합니다.

src/components/memory/MemoryContent/MemoryContent.tsx (3)

8-8: 새로운 컴포넌트 import가 적절합니다.

UploadProgressBar 컴포넌트의 import 경로가 올바르고 일관된 패턴을 따릅니다.


19-26: props 인터페이스 확장이 깔끔합니다.

새로운 기능을 위한 props 추가가 기존 구조를 해치지 않고 자연스럽게 통합되었습니다.


55-57: 진행률 바 배치 위치가 적절합니다.

탭 바로 아래에 진행률 바를 배치한 것이 사용자 경험 측면에서 논리적입니다. 사용자가 기록 탭으로 이동했을 때 업로드 상태를 즉시 확인할 수 있습니다.

src/pages/pollwrite/PollWrite.tsx (2)

48-50: 데모용 데이터 설정이 명확합니다.

첫 번째 옵션을 90%로 설정하는 데모용 로직이 주석으로 명시되어 있어 좋습니다. 실제 구현 시 이 부분을 쉽게 찾아 수정할 수 있습니다.


115-119: props 이름 변경이 올바르게 적용되었습니다.

PollCreationSection 컴포넌트의 prop 인터페이스 변경에 맞춰 정확히 업데이트되었습니다.

src/components/memory/UploadProgressBar/UploadProgressBar.tsx (3)

21-24: 진행률 계산 로직이 정확합니다.

3초 동안 50ms 간격으로 업데이트하는 계산이 올바르게 구현되었습니다. 수학적으로 정확한 increment 값을 계산하고 있습니다.


25-40: 타이머 관리가 잘 구현되었습니다.

setInterval 사용과 cleanup, 그리고 완료 시 콜백 처리가 모두 적절합니다. 메모리 누수도 방지되고 있습니다.


76-82: 진행률에 따른 동적 스타일링이 잘 구현되었습니다.

transition 효과와 함께 부드러운 애니메이션이 적용되어 사용자 경험이 좋을 것 같습니다.

src/pages/memory/Memory.tsx (5)

47-48: 업로드 프로그레스 상태 관리가 적절하게 구현되었습니다.

상태 변수명이 명확하고, 주석도 이해하기 쉽게 작성되었습니다.


149-152: 업로드 완료 핸들러가 깔끔하게 구현되었습니다.

단일 책임 원칙을 잘 따르고 있고, 함수명도 명확합니다.


193-207: 필터링 로직이 명확하게 개선되었습니다.

주석이 더 명확해졌고, 조건문도 이해하기 쉽게 작성되었습니다. 코드의 가독성이 향상되었습니다.


262-270: 컴포넌트 props 전달이 적절하게 구현되었습니다.

새로운 업로드 프로그레스 관련 props가 명확하게 전달되고 있습니다.


278-284: 스낵바 구현이 적절합니다.

성공 메시지가 명확하고, 인라인 핸들러도 이 간단한 사용 사례에는 적합합니다.

Comment on lines 102 to 147
React.useEffect(() => {
if (location.state?.newRecord) {
const newRecord = location.state.newRecord as Record;

// 중복 확인을 위한 함수
const addRecordIfNotExists = (prevRecords: Record[]) => {
const exists = prevRecords.some(record => record.id === newRecord.id);
if (exists) {
return prevRecords;
}
return [newRecord, ...prevRecords];
};

// 내 기록에 추가
setMyRecords(prev => addRecordIfNotExists(prev));

// 그룹 기록에도 추가 (내가 작성한 기록도 그룹에 표시)
setGroupRecords(prev => addRecordIfNotExists(prev));
const newRecord = location.state.newRecord as Record & { isUploading?: boolean };

if (newRecord.isUploading) {
// 업로드 프로그레스 시작
setShowUploadProgress(true);

// 미리 기록을 추가해둠 (프로그레스 완료 후 표시됨)
const finalRecord: Record = {
id: newRecord.id,
user: newRecord.user,
userPoints: newRecord.userPoints,
content: newRecord.content,
likeCount: newRecord.likeCount,
commentCount: newRecord.commentCount,
timeAgo: newRecord.timeAgo,
createdAt: newRecord.createdAt,
type: newRecord.type,
recordType: newRecord.recordType,
pageRange: newRecord.pageRange,
pollOptions: newRecord.pollOptions,
};

// 중복 확인을 위한 함수
const addRecordIfNotExists = (prevRecords: Record[]) => {
const exists = prevRecords.some(record => record.id === finalRecord.id);
if (exists) {
return prevRecords;
}
return [finalRecord, ...prevRecords];
};

// 내 기록에 추가
setMyRecords(prev => addRecordIfNotExists(prev));
// 그룹 기록에도 추가
setGroupRecords(prev => addRecordIfNotExists(prev));
}

// 내 기록 탭으로 이동
setActiveTab('my');

// state 즉시 초기화 (중복 추가 방지)
navigate(location.pathname, { replace: true, state: null });
}
}, [location.state?.newRecord?.id, navigate, location.pathname]);
}, [location.state?.newRecord, navigate, location.pathname]);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

복잡한 로직을 리팩토링하고 성능 최적화를 고려해보세요.

이 useEffect는 여러 가지 개선점이 있습니다:

  1. 의존성 배열 최적화: location.pathname을 의존성에서 제거할 수 있습니다.
  2. 중복된 코드 제거: finalRecord 생성 시 spread operator를 활용하여 간소화할 수 있습니다.
  3. 함수 추출: addRecordIfNotExists를 useCallback으로 메모이제이션하거나 컴포넌트 외부로 추출할 수 있습니다.
+ // 컴포넌트 외부로 추출
+ const addRecordIfNotExists = (prevRecords: Record[], newRecord: Record) => {
+   const exists = prevRecords.some(record => record.id === newRecord.id);
+   return exists ? prevRecords : [newRecord, ...prevRecords];
+ };

  React.useEffect(() => {
    if (location.state?.newRecord) {
-     const newRecord = location.state.newRecord as Record & { isUploading?: boolean };
+     const { isUploading, ...recordData } = location.state.newRecord as Record & { isUploading?: boolean };

-     if (newRecord.isUploading) {
+     if (isUploading) {
        setShowUploadProgress(true);

-       const finalRecord: Record = {
-         id: newRecord.id,
-         user: newRecord.user,
-         userPoints: newRecord.userPoints,
-         content: newRecord.content,
-         likeCount: newRecord.likeCount,
-         commentCount: newRecord.commentCount,
-         timeAgo: newRecord.timeAgo,
-         createdAt: newRecord.createdAt,
-         type: newRecord.type,
-         recordType: newRecord.recordType,
-         pageRange: newRecord.pageRange,
-         pollOptions: newRecord.pollOptions,
-       };
+       const finalRecord: Record = recordData;

-       const addRecordIfNotExists = (prevRecords: Record[]) => {
-         const exists = prevRecords.some(record => record.id === finalRecord.id);
-         if (exists) {
-           return prevRecords;
-         }
-         return [finalRecord, ...prevRecords];
-       };

-       setMyRecords(prev => addRecordIfNotExists(prev));
-       setGroupRecords(prev => addRecordIfNotExists(prev));
+       setMyRecords(prev => addRecordIfNotExists(prev, finalRecord));
+       setGroupRecords(prev => addRecordIfNotExists(prev, finalRecord));
      }

      setActiveTab('my');
      navigate(location.pathname, { replace: true, state: null });
    }
- }, [location.state?.newRecord, navigate, location.pathname]);
+ }, [location.state?.newRecord, navigate]);
📝 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
React.useEffect(() => {
if (location.state?.newRecord) {
const newRecord = location.state.newRecord as Record;
// 중복 확인을 위한 함수
const addRecordIfNotExists = (prevRecords: Record[]) => {
const exists = prevRecords.some(record => record.id === newRecord.id);
if (exists) {
return prevRecords;
}
return [newRecord, ...prevRecords];
};
// 내 기록에 추가
setMyRecords(prev => addRecordIfNotExists(prev));
// 그룹 기록에도 추가 (내가 작성한 기록도 그룹에 표시)
setGroupRecords(prev => addRecordIfNotExists(prev));
const newRecord = location.state.newRecord as Record & { isUploading?: boolean };
if (newRecord.isUploading) {
// 업로드 프로그레스 시작
setShowUploadProgress(true);
// 미리 기록을 추가해둠 (프로그레스 완료 후 표시됨)
const finalRecord: Record = {
id: newRecord.id,
user: newRecord.user,
userPoints: newRecord.userPoints,
content: newRecord.content,
likeCount: newRecord.likeCount,
commentCount: newRecord.commentCount,
timeAgo: newRecord.timeAgo,
createdAt: newRecord.createdAt,
type: newRecord.type,
recordType: newRecord.recordType,
pageRange: newRecord.pageRange,
pollOptions: newRecord.pollOptions,
};
// 중복 확인을 위한 함수
const addRecordIfNotExists = (prevRecords: Record[]) => {
const exists = prevRecords.some(record => record.id === finalRecord.id);
if (exists) {
return prevRecords;
}
return [finalRecord, ...prevRecords];
};
// 내 기록에 추가
setMyRecords(prev => addRecordIfNotExists(prev));
// 그룹 기록에도 추가
setGroupRecords(prev => addRecordIfNotExists(prev));
}
// 내 기록 탭으로 이동
setActiveTab('my');
// state 즉시 초기화 (중복 추가 방지)
navigate(location.pathname, { replace: true, state: null });
}
}, [location.state?.newRecord?.id, navigate, location.pathname]);
}, [location.state?.newRecord, navigate, location.pathname]);
// 컴포넌트 외부로 추출
const addRecordIfNotExists = (prevRecords: Record[], newRecord: Record) => {
const exists = prevRecords.some(record => record.id === newRecord.id);
return exists ? prevRecords : [newRecord, ...prevRecords];
};
React.useEffect(() => {
if (location.state?.newRecord) {
const { isUploading, ...recordData } = location.state.newRecord as Record & { isUploading?: boolean };
if (isUploading) {
setShowUploadProgress(true);
const finalRecord: Record = recordData;
setMyRecords(prev => addRecordIfNotExists(prev, finalRecord));
setGroupRecords(prev => addRecordIfNotExists(prev, finalRecord));
}
setActiveTab('my');
navigate(location.pathname, { replace: true, state: null });
}
}, [location.state?.newRecord, navigate]);
🤖 Prompt for AI Agents
In src/pages/memory/Memory.tsx around lines 102 to 147, refactor the useEffect
by removing location.pathname from the dependency array since it is not needed,
simplify finalRecord creation using the spread operator to copy properties from
newRecord, and extract the addRecordIfNotExists function outside the useEffect,
memoizing it with useCallback to avoid recreating it on every render and improve
performance.

Comment on lines +44 to 50
user: 'user.01', // TODO: 실제 사용자 이름으로 변경
userPoints: 132, // TODO: 실제 사용자 포인트로 변경
content: content,
likeCount: 0,
commentCount: 0,
timeAgo: '방금 전',
timeAgo: '12시간 전',
createdAt: new Date(),
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

하드코딩된 값들의 일관성을 확인하세요.

사용자 정보와 시간 정보가 하드코딩되어 있습니다. TODO 주석이 있어 임시값임을 알 수 있지만, 다른 파일들과의 일관성을 확인해야 합니다.

다른 파일들에서도 동일한 하드코딩 값을 사용하는지 확인하겠습니다:


🏁 Script executed:

#!/bin/bash
# Description: 하드코딩된 사용자 정보의 일관성 확인

echo "=== user.01 검색 ==="
rg "user\.01" --type tsx --type ts -A 2 -B 2

echo "=== userPoints: 132 검색 ==="
rg "userPoints.*132" --type tsx --type ts -A 2 -B 2

echo "=== 12시간 전 검색 ==="
rg "12시간 전" --type tsx --type ts -A 2 -B 2

Length of output: 384


다른 파일에서도 하드코딩된 값이 사용되고 있는지 전체 파일을 대상으로 다시 확인해 보겠습니다.


🏁 Script executed:

#!/bin/bash
# Description: 전체 파일에서 하드코딩된 사용자 정보 및 시간 확인

echo "=== user.01 검색 ==="
rg "user\.01" -n -C2

echo "=== userPoints: 132 검색 ==="
rg "userPoints.*132" -n -C2

echo "=== 12시간 전 검색 ==="
rg "12시간 전" -n -C2

Length of output: 8519


하드코딩된 사용자·포인트·시간 정보 중앙화 및 일관성 확보 필요

현재 여러 파일에서 동일한 임시값(‘user.01’, 132, ‘12시간 전’, createdAt)이 반복 사용되고 있습니다. 유지보수성과 확장성을 위해 아래 위치들을 확인 후, 공통 모듈이나 Context/API로 추출해 주세요.

• src/pages/recordwrite/RecordWrite.tsx (44–50)
• src/pages/pollwrite/PollWrite.tsx (55–62)
• src/pages/memory/Memory.tsx (60–67, 74–80)
• src/pages/today-words/TodayWords.tsx (35–37)
• src/components/today-words/MessageList/MessageList.tsx (36)
• src/constants/today-constants.ts
• src/mocks/searchBook.mock.ts
• src/data/postData.ts

– 사용자 정보는 전역 상태(예: UserContext/API)에서 가져오고
– 포인트는 서버 응답 또는 전역 스토어에서 관리하며
– 시간 표시(timeAgo, createdAt)는 date-fns/dayjs 같은 유틸로 일관되게 포맷팅하세요.
– TODO 주석 제거 및 실제 값 주입 로직을 구현해 주세요.

🤖 Prompt for AI Agents
In src/pages/recordwrite/RecordWrite.tsx lines 44 to 50, the user, userPoints,
timeAgo, and createdAt values are hardcoded and duplicated across multiple
files. Refactor by removing these hardcoded values and instead retrieve user
information from a centralized global state like UserContext or an API. Manage
userPoints from server responses or a global store. Format timeAgo and createdAt
consistently using a date utility library such as date-fns or dayjs. Remove the
TODO comments and implement the logic to inject actual dynamic values
accordingly.

@ljh130334 ljh130334 merged commit e4f7cd9 into develop Aug 4, 2025
3 checks passed
Copy link
Collaborator

@heeeeyong heeeeyong left a comment

Choose a reason for hiding this comment

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

LGTM👍

Copy link
Collaborator

Choose a reason for hiding this comment

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

post API 연동할때, 지금처럼 임의로 3초동안 차오르게 해놓되 API 요청에 대한 응답이 200으로 들어오는 순간에 프로그레스바 퍼센트를 강제로 100%로 만드는건 어떤지 의견드립니다. 대용량 업로드를 하는게 아니라서 서버에서 진행도를 받거나하는건 숏폼 업로드가 도입되었을때 해도 충분하지 않나 생각이 됩니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발 🎨 Html&css 마크업 & 스타일링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants