Skip to content

#279 Rebuild components/rating/rating-modal.tsx with shadcn Dialog pr… - #289

Merged
Benjtalkshow merged 2 commits into
boundlessfi:mainfrom
Chigybillionz:rebuild-components
Jun 28, 2026
Merged

#279 Rebuild components/rating/rating-modal.tsx with shadcn Dialog pr…#289
Benjtalkshow merged 2 commits into
boundlessfi:mainfrom
Chigybillionz:rebuild-components

Conversation

@Chigybillionz

@Chigybillionz Chigybillionz commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Rebuild rating-modal.tsx with shadcn Dialog primitives

closes #279

Summary
components/rating/rating-modal.tsx was the only dialog in the repo using raw HTML and inline styles instead of the project's design system. This PR rebuilds it on the shadcn primitives that every other dialog uses, with semantic design tokens throughout. Props and behavior are unchanged, so the existing caller in components/bounty/bounty-sidebar.tsx keeps working without modification.

What changed
components/rating/rating-modal.tsx rebuilt with:
Dialog + DialogContent + DialogHeader + DialogTitle + DialogDescription + DialogFooter from components/ui/dialog
Button from components/ui/button — variant="ghost" for Cancel/Close, default variant for Submit
Textarea from components/ui/textarea
All style={{...}} replaced with Tailwind utility classes
Error text now uses the text-destructive token instead of color: 'red'
Open/close wired through Dialog's onOpenChange, preserving the existing onClose contract
components/rating/rating-stars.tsx updated to drop inline styles in favor of Tailwind classes / semantic tokens (text-muted-foreground, text-yellow-400) as part of removing all inline styling from this surface.
Props & behavior preserved
Props unchanged: contributor, bounty, onSubmit, onClose — no caller changes required (components/bounty/bounty-sidebar.tsx still works as-is).
Submit validates the 1–5 rating, calls onSubmit, shows a loading state, and renders the success state on resolve.
Error state renders correctly with the destructive token; Cancel/Close behave identically to before.

Acceptance criteria
No raw
, raw , raw <textarea>, or style={{...}} in the file
Modal matches the visual treatment of other AlertDialogs in the bounty surface
Submit and Cancel buttons behave identically to before
Success and error states render correctly
pnpm tsc --noEmit passes (no new errors from these files)
pnpm lint passes (0 errors)

Testing
pnpm tsc --noEmit — clean for the rating components (the only remaining error is a pre-existing, unrelated @jest/globals types issue in components/reputation/tests/my-claims.test.ts).
pnpm lint — 0 errors (1 pre-existing unused-var warning in lib/server-graphql.ts, unrelated to this change).
npx eslint components/rating/rating-modal.tsx components/rating/rating-stars.tsx — exit 0.

Files
components/rating/rating-modal.tsx
components/rating/rating-stars.tsx

please kindly review and if there is any update regarding the task, please do let know!

Summary by CodeRabbit

  • New Features

    • Updated the rating popup to use a polished dialog layout with clearer header, footer, and success state.
    • Improved the rating control styling for more consistent interactive and read-only presentation.
  • Bug Fixes

    • Enhanced rating submission error handling with clearer failure messaging and reliable loading-state cleanup.
    • Improved dialog dismissal behavior for more consistent closing interactions.

Pushed the requested polish:

  • Bounty/Contributor/Current Reputation now use the muted-label + value pattern (matches tier-upgrade-dialog.tsx)
  • Removed the unnecessary explicit React.ChangeEvent annotation on the Textarea onChange

Screenshots attached below for both the default form and success state. initial
image
success
image

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

@Chigybillionz is attempting to deploy a commit to the Threadflow Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 26, 2026

Copy link
Copy Markdown

@Chigybillionz Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The rating modal now uses dialog primitives and shared form components, with updated success and error rendering. The rating stars component now relies on Tailwind class names instead of inline styles.

Changes

Rating UI refresh

Layer / File(s) Summary
Star rendering classes
components/rating/rating-stars.tsx
Replaces inline style objects with conditional class names for the star container and icons while preserving hover, click, and keyboard behavior.
Dialog-based rating modal
components/rating/rating-modal.tsx
Converts the modal to a client-side Dialog, keeps rating validation and submission state, logs submission errors, and renders success, error, textarea, and footer actions with shared UI components.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A bunny hopped through stars so bright,
Then dialog moons lit up the night.
With Tailwind ears and buttons neat,
I nibbled errors into treat.
A soft UI burrow, crisp and true 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and clearly reflects the main change to rebuild the rating modal with shadcn Dialog primitives.
Linked Issues check ✅ Passed The PR appears to satisfy #279 by replacing raw modal markup, inline styles, and raw controls with shadcn dialog and design-system components.
Out of Scope Changes check ✅ Passed The rating-stars refactor is part of the stated objectives, so no unrelated or out-of-scope changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/rating/rating-stars.tsx`:
- Around line 26-27: Honor the disabled state in RatingStars so it is not
focusable and does not react to hover previews when disabled. Update the
focus/ARIA logic around tabIndex and role, and gate the hover handlers and
preview state updates in the RatingStars component so disabled behaves like
displayOnly for interaction while preserving the existing click/keyboard
blocking.
- Around line 46-53: The read-only branch in rating-stars.tsx is forcing every
star to the muted style, which hides the stored rating in displayOnly mode.
Update the className logic in the RatingStars rendering so the displayOnly path
still compares the current star against value and applies the filled/yellow
class for rated stars, while keeping the non-interactive styling separate; use
the existing displayOnly, hovered, value, and star symbols to preserve the
component’s read-only behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d2d72b0-eee3-4a2a-be09-9a8178cad8a2

📥 Commits

Reviewing files that changed from the base of the PR and between 9e5dc91 and d872110.

📒 Files selected for processing (2)
  • components/rating/rating-modal.tsx
  • components/rating/rating-stars.tsx

Comment on lines 26 to +27
tabIndex={displayOnly ? -1 : 0}
role={displayOnly ? 'img' : 'slider'}
role={displayOnly ? "img" : "slider"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Honor disabled in focus and hover handling.

disabled still leaves the slider focusable and still updates the hover preview, so the control looks interactive even though click/keyboard changes are blocked.

Suggested fix
-      tabIndex={displayOnly ? -1 : 0}
+      tabIndex={displayOnly || disabled ? -1 : 0}
       role={displayOnly ? "img" : "slider"}
+      aria-disabled={disabled || undefined}
       aria-valuenow={value}
@@
-          ? "flex items-center gap-1 outline-none"
-          : "flex items-center gap-1 cursor-pointer outline-none"
+          ? "flex items-center gap-1 outline-none"
+          : `flex items-center gap-1 outline-none ${disabled ? "cursor-default" : "cursor-pointer"}`
@@
-          onMouseEnter={() => !displayOnly && setHovered(star)}
-          onMouseLeave={() => !displayOnly && setHovered(null)}
+          onMouseEnter={() => !displayOnly && !disabled && setHovered(star)}
+          onMouseLeave={() => !displayOnly && !disabled && setHovered(null)}

Also applies to: 32-35, 41-45

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/rating/rating-stars.tsx` around lines 26 - 27, Honor the disabled
state in RatingStars so it is not focusable and does not react to hover previews
when disabled. Update the focus/ARIA logic around tabIndex and role, and gate
the hover handlers and preview state updates in the RatingStars component so
disabled behaves like displayOnly for interaction while preserving the existing
click/keyboard blocking.

Comment on lines +46 to +53
className={
displayOnly
? "select-none text-2xl text-muted-foreground"
: "select-none text-2xl transition-colors duration-200 " +
((hovered ?? value) >= star
? "text-yellow-400"
: "text-muted-foreground")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve filled stars in displayOnly mode.

This branch now renders every read-only star with the muted class, so a stored rating like 4 no longer shows four filled stars. That breaks the component’s read-only behavior.

Suggested fix
-          className={
-            displayOnly
-              ? "select-none text-2xl text-muted-foreground"
-              : "select-none text-2xl transition-colors duration-200 " +
-                ((hovered ?? value) >= star
-                  ? "text-yellow-400"
-                  : "text-muted-foreground")
-          }
+          className={
+            "select-none text-2xl " +
+            (!displayOnly ? "transition-colors duration-200 " : "") +
+            ((displayOnly ? value : hovered ?? value) >= star
+              ? "text-yellow-400"
+              : "text-muted-foreground")
+          }
📝 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
className={
displayOnly
? "select-none text-2xl text-muted-foreground"
: "select-none text-2xl transition-colors duration-200 " +
((hovered ?? value) >= star
? "text-yellow-400"
: "text-muted-foreground")
}
className={
"select-none text-2xl " +
(!displayOnly ? "transition-colors duration-200 " : "") +
((displayOnly ? value : hovered ?? value) >= star
? "text-yellow-400"
: "text-muted-foreground")
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/rating/rating-stars.tsx` around lines 46 - 53, The read-only
branch in rating-stars.tsx is forcing every star to the muted style, which hides
the stored rating in displayOnly mode. Update the className logic in the
RatingStars rendering so the displayOnly path still compares the current star
against value and applies the filled/yellow class for rated stars, while keeping
the non-interactive styling separate; use the existing displayOnly, hovered,
value, and star symbols to preserve the component’s read-only behavior.

@Benjtalkshow Benjtalkshow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice cleanup, all acceptance criteria from #279 are met and tsc + lint pass
locally. Two small polishes before merge: replace the three Bounty:
/ Contributor: / Current Reputation:
labels with the muted-label + value pattern other dialogs in the
bounty surface use, and drop the unnecessary explicit React.ChangeEvent
annotation on the Textarea onChange. Also please attach a screenshot of the
rating modal (both the default form and the success state) so I can verify
the visual result before merging.

@Chigybillionz

Copy link
Copy Markdown
Contributor Author

Nice cleanup, all acceptance criteria from #279 are met and tsc + lint pass locally. Two small polishes before merge: replace the three **Bounty: ** / Contributor: / **Current Reputation: ** labels with the muted-label + value pattern other dialogs in the bounty surface use, and drop the unnecessary explicit React.ChangeEvent annotation on the Textarea onChange. Also please attach a screenshot of the rating modal (both the default form and the success state) so I can verify the visual result before merging.

Alright..

I'll make the correction and give you a feedback on the outcome today!

@Chigybillionz

Copy link
Copy Markdown
Contributor Author

Nice cleanup, all acceptance criteria from #279 are met and tsc + lint pass locally. Two small polishes before merge: replace the three **Bounty: ** / Contributor: / **Current Reputation: ** labels with the muted-label + value pattern other dialogs in the bounty surface use, and drop the unnecessary explicit React.ChangeEvent annotation on the Textarea onChange. Also please attach a screenshot of the rating modal (both the default form and the success state) so I can verify the visual result before merging.

good day, you can now make the review please

@Benjtalkshow Benjtalkshow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@Benjtalkshow
Benjtalkshow merged commit b555563 into boundlessfi:main Jun 28, 2026
4 of 5 checks passed
@Chigybillionz

Chigybillionz commented Jun 28, 2026 via email

Copy link
Copy Markdown
Contributor Author

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rebuild components/rating/rating-modal.tsx with shadcn Dialog primitives

2 participants