Skip to content

Conversation

@wwweric12
Copy link
Collaborator

@wwweric12 wwweric12 commented Feb 20, 2025

#️⃣ 연관된 이슈

📝 작업 내용

학생 반응하기 요청하기 로컬 스토리지 저장 기능 구현
학생이 요청과 반응에는 한번씩 누르게 되면 서버의 부하를 생각하여 60초.10초 동안 못하도록 막았습니다.
하지만 각각의 초 단위를 서버에서 받아오는것이 아니기 때문에 새로 고침을 하게 되면 초기화가 되는 문제가 생겨서
로컬스토리지에 저장하여 사용하도록 구현 했습니다!

Summary by CodeRabbit

  • New Features
    • Interactive cards for reactions and requests now include a dynamic, type-based timer that temporarily disables actions, helping prevent rapid repeated inputs.
    • Visual feedback has been enhanced to clearly indicate when an action is blocked until it becomes available again.
    • The handling of submitted questions has been streamlined to consistently display key details.

- useBlockTimer에서 로컬값 가져와서 비교하도록 구현
@wwweric12 wwweric12 added ✨ Feat 새로운 기능 추가 (기능 개발 및 신규 기능 구현) ⚛️ FE 프론트엔드 관련 labels Feb 20, 2025
@wwweric12 wwweric12 requested a review from DrCloy February 20, 2025 10:11
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2025

Walkthrough

This pull request revises the useBlockTimer hook by removing the external selection state and introducing a dynamic type parameter that drives localStorage access for an initial countdown. Components such as ReactCard and RequestCard now accept a new type prop, which alters how they invoke the hook and manage blocking behavior. In addition, minor adjustments in the repository layer streamline the returned question data. Overall, the changes centralize timer logic and integrate type-based control across related UI components.

Changes

File(s) Change Summary
front-end/src/hooks/useBlockTimer.ts Modified API: removed isSelected, added type parameter, encapsulated countdown logic in startCountdown, and introduced startBlock to trigger blocking behavior.
front-end/src/pages/.../react/StudentReact.tsx and front-end/src/pages/.../react/components/ReactCard.tsx Added a new type prop to the ReactCard component; updated hook invocation to use a dynamic key based on type and added a new useEffect to handle isBlocked state changes; modified click handler to call startBlock().
front-end/src/pages/.../request/StudentRequest.tsx and front-end/src/pages/.../request/components/RequestCard.tsx Introduced a new type prop to the RequestCard component; updated the useBlockTimer hook call to use a dynamic key; added useEffect to manage selection state based on isBlocked; updated click handling to incorporate startBlock().
front-end/src/repository/classroomRepository.ts Adjusted return values: removed JSON parsing from check methods, and streamlined sendQuestion and getQuestions responses to return only selected question fields.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant C as Card Component
    participant BT as useBlockTimer Hook
    participant LS as localStorage

    U->>C: Click on card
    C->>BT: Call startBlock()
    BT->>LS: Retrieve initialCountdown using type key
    BT->>BT: Initialize countdown and isBlocked state
    BT->>C: Update component state (isBlocked, countdown)
    C->>C: Handle UI feedback based on blocked state
Loading

Possibly related PRs

Suggested reviewers

  • DrCloy

Poem

I’m a hopping rabbit with glee,
Watching code dance so gracefully.
A timer now ticks with a new type key,
Blocking bugs and setting states free.
With carrots in hand and a joyful spree,
I hop through changes — so wild and merry!
Code transforms with every bit of carrot energy 🥕.

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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. (Beta)
  • @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.

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

🧹 Nitpick comments (8)
front-end/src/hooks/useBlockTimer.ts (2)

13-13: Check for multiple effect triggers and transitions
Because the effect at lines 16-26 re-invokes startCountdown if initialCountdown > 0, any changes to type, blockDuration, or delay might reset the countdown unexpectedly mid-block. Ensure that this is intentional, or consider memoizing these props to avoid unintended resets.

Also applies to: 15-20, 26-26, 28-51


63-63: Optionally expose a cancel or reset method
Returning { isBlocked, countdown, startBlock } is sufficient for most use cases. However, if you foresee the need to cancel an ongoing block or reset the countdown, returning additional functions (e.g., cancelBlock) could improve reusability.

front-end/src/pages/student/course/react/components/ReactCard.tsx (3)

1-1: Use consistent naming for reaction-based properties
Importing the Reaction type and adding the new type prop is clear. Just ensure future expansions stay consistent, e.g., use reactionType or another descriptive name if you add multiple similar props.

Also applies to: 4-4, 9-9


12-16: Encapsulate block duration constants
You're passing 10000 (block duration) and 2000 (delay) directly to the hook. Consider extracting these into a config or constant for better maintainability and clarity.


20-26: Consolidate state if feasible
You map isBlocked to isSelected inside a side effect. If your UI fully depends on isBlocked, you might simplify by relying solely on isBlocked instead of duplicating with isSelected. Keeping two states in sync can lead to confusion unless it’s truly necessary.

front-end/src/pages/student/course/request/components/RequestCard.tsx (2)

1-1: Adopt consistent naming & typing
Introducing RequestType in the props aligns with the approach for reactions. Ensure that the type strings for requests and reactions remain distinct if they share localStorage keys, to avoid collisions.

Also applies to: 4-4, 11-11, 19-19


28-34: Mirror isBlocked into isSelected
As with ReactCard, you’re toggling isSelected when isBlocked changes. Consider whether the UI needs both states, or if referencing isBlocked alone is sufficient.

front-end/src/repository/classroomRepository.ts (1)

108-108: Translate Korean comment to maintain consistency.

The comment "오류 처리" (error handling) should be in English to maintain consistency with the rest of the codebase.

-    await throwError(response); // 오류 처리
+    await throwError(response); // Error handling
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 23bef6c and 9bb309d.

📒 Files selected for processing (6)
  • front-end/src/hooks/useBlockTimer.ts (1 hunks)
  • front-end/src/pages/student/course/react/StudentReact.tsx (1 hunks)
  • front-end/src/pages/student/course/react/components/ReactCard.tsx (1 hunks)
  • front-end/src/pages/student/course/request/StudentRequest.tsx (1 hunks)
  • front-end/src/pages/student/course/request/components/RequestCard.tsx (1 hunks)
  • front-end/src/repository/classroomRepository.ts (2 hunks)
🔇 Additional comments (10)
front-end/src/hooks/useBlockTimer.ts (2)

3-10: Leverage fallback for missing or invalid keys in localStorage
The approach of retrieving and parsing the stored countdown from localStorage is a good way to persist the block state. However, consider additional safeguards if type could be null/undefined or if localStorage returns invalid data (e.g., non-numeric strings).


53-61: Clarify partial second rounding
When calling startCountdown(blockDuration / 1000), fractional remainders are truncated. If blockDuration is not always a clean multiple of 1000, consider rounding or adjusting the value to ensure more consistent block durations.

front-end/src/pages/student/course/react/components/ReactCard.tsx (2)

32-32: Trigger block only on success
Calling startBlock() immediately after setIsSelected(true) ensures the countdown runs exclusively for successful clicks. This is great for preventing user spamming. No concerns here.


38-39: Confirm button disabling logic
The button is disabled based on either isSelected or isBlocked. This ensures no repeated interactions. If the user flow changes so that isSelected can be reset, consider reevaluating whether users should be allowed multiple clicks within the block timeframe.

front-end/src/pages/student/course/request/components/RequestCard.tsx (2)

22-23: Match units for block duration
You’re calling the hook with 60000 for the block duration (in milliseconds) and dividing by 1000 inside the hook. Double-check that you’re aware of the difference between the internal “seconds” usage (countdown) and the external “milliseconds” usage.


40-40: Good practice to block on success
Calling startBlock() after confirming success is an effective way to prevent spammy requests. This logic is consistent with the approach in ReactCard.

front-end/src/pages/student/course/react/StudentReact.tsx (1)

66-66: LGTM! Type prop addition aligns with local storage implementation.

The addition of the type prop to ReactCard enables type-based localStorage persistence for reaction timers.

front-end/src/pages/student/course/request/StudentRequest.tsx (1)

84-84: LGTM! Type prop addition enables request-specific timer persistence.

The addition of the type prop to RequestCard enables localStorage persistence for request timers, consistent with the implementation in ReactCard.

front-end/src/repository/classroomRepository.ts (2)

68-72: LGTM! Streamlined question data structure.

The return value has been optimized to include only the necessary fields (id, createdAt, content), improving type safety and reducing data transfer.


111-118: LGTM! Consistent data transformation.

The mapping of question data follows the same streamlined structure as sendQuestion, ensuring consistency across the repository.

Copy link
Collaborator

@DrCloy DrCloy left a comment

Choose a reason for hiding this comment

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

수고하셨어요

@DrCloy DrCloy merged commit 007c42c into dev Feb 20, 2025
2 checks passed
@DrCloy DrCloy deleted the feat/fe/student-block branch February 20, 2025 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚛️ FE 프론트엔드 관련 ✨ Feat 새로운 기능 추가 (기능 개발 및 신규 기능 구현)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants