Skip to content

Conversation

@mhojune
Copy link

@mhojune mhojune commented Dec 2, 2025

Describe your Pull Request

When a notice is clicked, instead of navigating to a link as before, it now opens a modal if the notice has content, and the content is displayed inside the modal.
Please describe the behavior or changes of your code specifically.

Additional content

Any additional comments? 😁

Summary by CodeRabbit

  • New Features

    • Added a dedicated Notice modal with a clear "공지사항" header; clicking a notice opens the modal showing its title and full content for inline reading.
    • Modal now conditionally displays a Notice header and renders notice title when provided.
  • Chores

    • Notice data now includes full content so items can display complete notice text in the modal.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

App adds noticeTitle/noticeContent state and a handler to open a "Notice" modal. Notice items call that handler (preventing navigation when content exists). Modal and ModalOpen accept a Notice target and render a "공지사항" header and the passed title/content. NoticeInfo type adds a content field.

Changes

Cohort / File(s) Summary
App state & wiring
src/App.tsx
Added noticeContent and noticeTitle state and handleNoticeModalOpen(content, title) to set them and set modal target to Notice. Passed handler to Notice and state to ModalOpen.
Notice component & item behavior
src/app/components/notice/Notice.tsx
Notice now accepts onModalOpen(content, title); Box items receive content and onModalOpen and call onModalOpen(content, title) while preventing default navigation when content is present or URL is empty.
Modal structure & header
src/app/components/modal/modal.tsx
ModalSection gains optional $mTarget prop; uses overflow-hidden when $mTarget === 'Notice' (otherwise overflow-auto). Adds explicit "공지사항" header when mTarget === 'Notice'.
Modal content rendering
src/app/components/modal/modalOpen.tsx
ModalOpen signature extended with noticeContent?: string and noticeTitle?: string. When mTarget === 'Notice' it renders an optional title and noticeContent as plain text.
Data model
src/app/data/notice/noticeInfo.ts
NoticeInfo type extended with new content: string property to carry notice body text.

Sequence Diagram

sequenceDiagram
    actor User
    participant Notice as Notice Component
    participant App as App Component
    participant Modal as Modal Component
    participant ModalOpen as ModalOpen Component

    User->>Notice: Click notice item
    Note over Notice: item has `content`
    Notice->>App: onModalOpen(content, title)
    App->>App: set noticeContent/noticeTitle, mTarget='Notice'
    App->>Modal: render with mTarget='Notice'
    App->>ModalOpen: pass noticeContent, noticeTitle
    Modal->>Modal: render "공지사항" header and set overflow-hidden
    ModalOpen->>ModalOpen: render title (if any) and noticeContent as plain text
    Modal->>User: display notice modal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify Notice click handler prevents navigation only when appropriate.
  • Check safe rendering of noticeContent (text vs. HTML injection).
  • Confirm modal overflow behavior and header rendering across other targets.
  • Ensure data sources populate the new content field to avoid undefined values.

Poem

🐰 I nudged the title, cradled the text,
Hopped props along and opened the next,
A click, a modal, words softly told,
Tiny rabbit cheer, gentle and bold,
Springing notices like carrots of gold. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Dev/announcement' is partially related to the changeset but is vague and overly broad, using a branch naming convention rather than clearly describing the main change of adding modal display functionality to notices. Use a more descriptive title that clearly conveys the primary change, such as 'Display notice content in modal instead of navigating to link' or 'Add modal display for notice content'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description adequately describes the main behavioral change (notices now open a modal with content instead of navigating), fulfilling the template's primary requirement to describe the behavior and changes of the code.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev/announcement

📜 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 e6cb4d4 and 069a423.

📒 Files selected for processing (3)
  • src/App.tsx (4 hunks)
  • src/app/components/modal/modal.tsx (3 hunks)
  • src/app/components/modal/modalOpen.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/App.tsx
  • src/app/components/modal/modalOpen.tsx
  • src/app/components/modal/modal.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Generate Lighthouse Report
  • GitHub Check: Cloudflare Pages

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.

@devITae devITae requested review from devITae and kcyoow December 2, 2025 11:45
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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/components/notice/Notice.tsx (1)

7-25: Tighten Notice click logic to avoid empty-modal edge cases

The click handler currently does:

if (props.content.trim() !== '' || props.url.trim() === '') {
  e.preventDefault()
  props.onModalOpen(props.content, props.title)
}

This means:

  • If content is non-empty: navigation is prevented and the modal opens (expected).
  • If both content and url are empty: navigation is still prevented but an empty modal opens.
  • If content is empty but url is non-empty: the link navigates as before, which may or may not match the “no longer navigates to a link” behavior described in the PR summary.

If the intended behavior is “open modal only when there is content; otherwise, navigate when a URL exists and do nothing when there isn’t”, a safer pattern would be:

const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
  const hasContent = props.content.trim() !== ''
  const hasUrl = props.url.trim() !== ''

  if (hasContent) {
    e.preventDefault()
    props.onModalOpen(props.content, props.title)
  } else if (!hasUrl) {
    e.preventDefault() // nothing to open or navigate to
  }
}

Also, since this is now primarily a “show modal” interaction, you may want to reconsider using cursor-default on the <a> so it still feels clickable, or switch to a <button>-like control for better semantics.

🧹 Nitpick comments (5)
src/app/data/notice/noticeInfo.ts (1)

3-8: Verify content is always present in notice data

Making content a required string means all producers of NoticeInfo (API responses, fixtures, etc.) must now supply it. If any item comes back without content, consumers like Notice.tsx calling item.content.trim() will throw at runtime.

Either ensure the backend/schema always returns a string (possibly '') for content, or consider typing this as content?: string and defaulting to '' at the edge when mapping the API response.

src/app/components/modal/modal.tsx (2)

31-38: ModalSection overflow behavior looks correct; consider tightening $mTarget type

The conditional overflow-hidden for 'Notice' vs overflow-auto for others matches the new design and avoids the previous always-on scroll.

For extra safety, you could narrow $mTarget (and mTarget on Modal) to a string union of known targets ('Fabs' | 'Info' | 'Christmas' | 'Spring' | 'Notice') instead of a generic string, so typos are caught at compile time.


95-111: Align Notice modal header with i18n usage

Other modal headers (Fabs, Info, Christmas, Spring) are localized via t(...), but the Notice header uses a hard-coded "공지사항" string. For consistency and future localization, consider adding a translation key (e.g. t('notice')) instead of the literal.

src/app/components/modal/modalOpen.tsx (1)

59-65: Consider moving inline overflow styles into styled-components

The conditional overflow logic for 'Notice' vs other targets is fine, but it duplicates intent with the ModalSection’s $mTarget-based overflow and uses inline styles.

If this grows more complex, consider expressing it via a styled wrapper that takes $mTarget (or a dedicated $scrollable flag) instead of inline style, to keep layout concerns co-located in styled-components.

src/App.tsx (1)

196-232: Notice modal state and open handler are straightforward

noticeContent / noticeTitle state plus handleNoticeModalOpen cleanly encapsulate the Notice modal behavior and reuse the existing modal infrastructure. The call order (setNotice*, setModalTarget('Notice'), openModal()) is fine given React’s batched updates.

If you expect more Notice-specific modal data later, you might eventually group these into a single noticeModal state object, but that’s not necessary right now.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7f80b9 and c93c246.

📒 Files selected for processing (5)
  • src/App.tsx (4 hunks)
  • src/app/components/modal/modal.tsx (3 hunks)
  • src/app/components/modal/modalOpen.tsx (3 hunks)
  • src/app/components/notice/Notice.tsx (3 hunks)
  • src/app/data/notice/noticeInfo.ts (1 hunks)
🧰 Additional context used
🪛 ast-grep (0.40.0)
src/app/components/modal/modalOpen.tsx

[warning] 119-119: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 Biome (2.1.2)
src/app/components/modal/modalOpen.tsx

[error] 120-120: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Generate Lighthouse Report
🔇 Additional comments (4)
src/app/components/modal/modalOpen.tsx (1)

31-39: Notice props extension is consistent

Adding noticeContent? and noticeTitle? here lines up cleanly with the new Notice modal flow from App.tsx and Notice.tsx. No functional concerns from the prop typing.

src/App.tsx (2)

405-407: Notice → App callback wiring looks good

Passing onModalOpen={handleNoticeModalOpen} into Notice cleanly delegates the “what to do on click” decision back to App, matching the new modal-driven behavior without coupling Notice to modal internals.


582-590: ModalOpen receives all required Notice props

ModalOpen now gets noticeContent and noticeTitle alongside mTarget, which matches its new prop signature and Notice branch. No additional wiring issues spotted here.

src/app/components/notice/Notice.tsx (1)

37-67: Notice component correctly forwards modal callback and content

Wiring onModalOpen through Notice down into Box, along with item.content, gives you a clean data flow from the fetched notices into the modal system without coupling to App internals. This matches the new modal-based UX for notices.

@devITae devITae added the feature Feature development label Dec 2, 2025
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 2, 2025

Deploying hybus-genesis with  Cloudflare Pages  Cloudflare Pages

Latest commit: 069a423
Status: ✅  Deploy successful!
Preview URL: https://389d50e4.hybus-genesis.pages.dev
Branch Preview URL: https://dev-announcement.hybus-genesis.pages.dev

View logs

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c93c246 and 1773727.

📒 Files selected for processing (1)
  • src/app/components/modal/modalOpen.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Generate Lighthouse Report
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
src/app/components/modal/modalOpen.tsx (2)

37-38: LGTM: Props are well-defined.

The optional noticeContent and noticeTitle props are properly typed and maintain backward compatibility.


111-122: Notice content renders as plain text (XSS-safe).

The implementation correctly renders notice content as plain text {props.noticeContent || ''}, which is safe from XSS attacks. The noticeContent prop is a simple string with no HTML formatting support, and React's default text escaping prevents injection attacks. The whitespace-pre-wrap CSS class appropriately preserves line breaks and spaces in the plain text content without enabling HTML rendering.

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 (1)
src/app/components/modal/modalOpen.tsx (1)

31-39: Notice props extension looks correct; consider tightening typing around mTarget.

The new optional noticeContent / noticeTitle props are wired cleanly and only used when mTarget === 'Notice'. For future robustness, you might later consider making mTarget a discriminated union (e.g. 'Fabs' | 'Info' | 'Christmas' | 'Spring' | 'Notice') and tying noticeContent/noticeTitle to the 'Notice' case so TS enforces correct usage, but this is non-blocking for now.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa7a1eb and e6cb4d4.

📒 Files selected for processing (1)
  • src/app/components/modal/modalOpen.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Generate Lighthouse Report
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
src/app/components/modal/modalOpen.tsx (2)

59-62: Unified scrollable content container improves long‑content handling.

Switching to a single style={{ overflow: 'auto', maxHeight: '450px' }} for all targets resolves the previous Notice scrolling issue while keeping other modals unchanged. This is a good, simple UX fix.


107-118: Notice body rendering is safe and matches the new behavior.

The Notice branch cleanly renders an optional title and uses whitespace-pre-wrap with a plain text {props.noticeContent || ''} node, which both preserves basic formatting and avoids XSS risks from HTML content. This aligns well with “open modal and show notice content” behavior.

@devITae
Copy link
Member

devITae commented Dec 2, 2025

LGTM

@devITae devITae closed this Dec 2, 2025
@devITae devITae reopened this Dec 2, 2025
@github-actions
Copy link

github-actions bot commented Dec 2, 2025

Check out your Lighthouse Report: https://lighthouse.hybus.app/app/projects/bushanyang-production/dashboard

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

Labels

feature Feature development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants