feat: enhance user feedback and expand community experience - #150
Conversation
|
Deployment failed for project black-rose with the following error: View Documentation: https://vercel.com/docs/accounts/team-members-and-roles |
📝 WalkthroughWalkthroughThe pull request adds Sonner notifications across management and registration flows, mounts the global Toaster, simplifies Discord OAuth routing, adds tournament notification navigation, expands the community page into extracted tabs, updates game subtitles and server statistics, and protects referenced games from deletion. ChangesToast feedback
Discord OAuth routing
Community page restructuring
Route-linked UI updates
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant LoginRoute
participant DiscordOAuth
participant BrowserOrCapacitor
LoginRoute->>DiscordOAuth: startDiscordOAuth()
alt Capacitor native
DiscordOAuth->>BrowserOrCapacitor: Start PKCE OAuth
else Non-Capacitor
DiscordOAuth->>BrowserOrCapacitor: Navigate to browser authorization URL
end
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 `@src/components/ui/sonner.tsx`:
- Around line 13-18: Update the custom Sonner class strings in the toast
configuration to use important utilities for properties that conflict with
Sonner defaults, including shadow/background, borders, and action/cancel button
font size, colors, backgrounds, and borders. Preserve the existing custom theme
and apply the stronger utilities to both general and button-specific styles.
In `@src/features/admin/features/games/components/CreateGameModal.tsx`:
- Line 224: Update the success handling in the CreateGameModal submission flow
to account for failures caught by the image-upload and role-creation blocks.
Track whether either setup step fails, and avoid the unconditional success
toast; instead show the appropriate partial-success/error message or return
before reporting success when setup is incomplete.
In `@src/features/game-servers/components/GameServersOverlay.tsx`:
- Around line 28-30: Update the game route mapping in GameServersOverlay by
removing quotes from the palworld and valorant keys, while keeping
where-winds-meet quoted because its hyphens require a string key.
In `@src/features/teams/components/EditTeamDialog.tsx`:
- Around line 87-92: Handle the undefined gameId path in the save flow by
ensuring users receive the same error toast before the early return, or by
disabling the Save button until gameId is available. Update the relevant gameId
guard and the Save button’s disabled condition, preserving the existing inline
error state and successful submission behavior.
In `@src/routes/login.tsx`:
- Line 161: Fix the Prettier formatting for the descriptive text near the login
route’s Discord sign-in content by wrapping the line according to the project’s
configured formatter. Preserve the existing wording and behavior.
🪄 Autofix
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 2dda9db3-ecd5-433b-9765-f8a731ce3568
📒 Files selected for processing (21)
src/components/ui/sonner.tsxsrc/features/admin/features/games/components/CreateGameModal.tsxsrc/features/admin/features/games/components/EditGameModal.tsxsrc/features/admin/features/games/components/GamesManagement.tsxsrc/features/admin/features/games/services/games.service.tssrc/features/admin/features/members/components/MembersManagement.tsxsrc/features/admin/features/tournaments/components/CreateTournamentModal.tsxsrc/features/admin/features/tournaments/components/EditTournamentModal.tsxsrc/features/admin/features/tournaments/components/TournamentsManagement.tsxsrc/features/auth/services/discord.tssrc/features/game-servers/components/GameServersOverlay.tsxsrc/features/notifications/components/NotificationBell.tsxsrc/features/teams/components/CreateTeamDialog.tsxsrc/features/teams/components/EditTeamDialog.tsxsrc/features/teams/components/InviteMemberDialog.tsxsrc/features/tournaments/components/RequestTournamentRegistrationDialog.tsxsrc/features/tournaments/components/SelectTeamRegistrationDialog.tsxsrc/lib/discord-url.tssrc/routes/__root.tsxsrc/routes/login.tsxsrc/routes/servers.index.tsx
| "palworld": "/servers", | ||
| "where-winds-meet": "/guilds", | ||
| "valorant": "/tournaments", |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the reported Prettier errors.
The configured prettier/prettier rule rejects the quoted palworld and valorant keys. Remove those quotes. Keep "where-winds-meet" quoted because its hyphens require a string key.
Proposed fix
const hardcodedHrefs: Record<string, CommunityGame["href"]> = {
- "palworld": "/servers",
+ palworld: "/servers",
"where-winds-meet": "/guilds",
- "valorant": "/tournaments",
+ valorant: "/tournaments",
};📝 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.
| "palworld": "/servers", | |
| "where-winds-meet": "/guilds", | |
| "valorant": "/tournaments", | |
| palworld: "/servers", | |
| "where-winds-meet": "/guilds", | |
| valorant: "/tournaments", |
🧰 Tools
🪛 ESLint
[error] 28-28: Replace "palworld" with palworld
(prettier/prettier)
[error] 30-30: Replace "valorant" with valorant
(prettier/prettier)
🤖 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 `@src/features/game-servers/components/GameServersOverlay.tsx` around lines 28
- 30, Update the game route mapping in GameServersOverlay by removing quotes
from the palworld and valorant keys, while keeping where-winds-meet quoted
because its hyphens require a string key.
Source: Linters/SAST tools
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@src/features/admin/features/games/components/CreateGameModal.tsx`:
- Around line 225-242: The partial-failure toast in the game creation flow
should use operation-neutral wording because failures may involve roles, image
updates, or persistence rather than uploads. Update the message built in the
failures branch around headerImageFailed, iconImageFailed, and rolesFailed to
say “failed during setup,” while preserving the existing failure labels and
success behavior.
In `@src/routes/community.index.tsx`:
- Around line 345-346: Update the community copy near the honesty and integrity
statement so the compound subject “Trust and loyalty” uses a plural verb, while
preserving the sentence’s meaning and surrounding wording.
In `@src/routes/login.tsx`:
- Around line 161-162: Adjust the JSX text line break in the login page
description so “Black” ends the first line and “Rose.” begins the second line,
matching Prettier’s approved formatting.
🪄 Autofix
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 03e60f5b-e89e-4055-81dc-2ff757255653
📒 Files selected for processing (7)
src/components/ui/sonner.tsxsrc/features/admin/features/games/components/CreateGameModal.tsxsrc/features/community/components/CommunityPortrait.tsxsrc/features/game-servers/components/GameServersOverlay.tsxsrc/features/teams/components/EditTeamDialog.tsxsrc/routes/community.index.tsxsrc/routes/login.tsx
💤 Files with no reviewable changes (1)
- src/features/game-servers/components/GameServersOverlay.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- src/components/ui/sonner.tsx
- src/features/teams/components/EditTeamDialog.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (7)
src/features/community/components/EventCard.tsx (4)
30-36: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winLazy-load the YouTube embed and use the no-cookie domain.
EventsTabrenders several cards at once, and each embed loads third-party scripts immediately. Addloading="lazy"to defer offscreen embeds. Usewww.youtube-nocookie.comto reduce tracking before the visitor plays the video.♻️ Proposed change
<iframe - src={`https://www.youtube.com/embed/${youtubeVideoId}`} + src={`https://www.youtube-nocookie.com/embed/${youtubeVideoId}`} title={title} className="h-full w-full" + loading="lazy" + referrerPolicy="strict-origin-when-cross-origin" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />🤖 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 `@src/features/community/components/EventCard.tsx` around lines 30 - 36, Update the YouTube iframe in EventCard to use the www.youtube-nocookie.com embed host and add lazy loading via the iframe’s loading attribute, while preserving the existing video ID, title, permissions, and fullscreen behavior.
9-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the unused
accentLineprop.
accentLineis required inEventCardPropsand destructured at Line 21, but no JSX in this component consumes it. OnlyaccentTagis applied, at Line 51. Every caller must pass a value that has no effect. Remove the prop, or apply it as an accent line likeGameCard.tsxdoes at Line 61.♻️ Proposed removal
/** Image source for static events (when youtubeVideoId is not provided) */ imageSrc?: string; - accentLine: string; accentTag: string;imageSrc, - accentLine, accentTag,Then drop
accentLinefrom theEventCardcall insrc/features/community/components/EventsTab.tsxat Line 70. TheaccentLinevalues in theEVENTSarray become unused as well.Also applies to: 21-21
🤖 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 `@src/features/community/components/EventCard.tsx` at line 9, Remove the unused accentLine property from EventCardProps and its destructuring in EventCard, then stop passing accentLine from EventsTab and remove the now-unused accentLine values from the EVENTS data. Keep the existing accentTag behavior unchanged.
1-13: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winModel the media props as a discriminated union.
The current type allows a card with neither
youtubeVideoIdnorimageSrc. In that case Line 40 renders<img src={undefined}>, which produces a broken image. Make the two media modes mutually exclusive so the compiler rejects the invalid combination.♻️ Proposed typing
-interface EventCardProps { - title: string; - date: string; - description: string; - /** YouTube video ID for embed, or null for image-only events */ - youtubeVideoId?: string; - /** Image source for static events (when youtubeVideoId is not provided) */ - imageSrc?: string; +type EventCardMedia = + | { youtubeVideoId: string; imageSrc?: never } + | { youtubeVideoId?: never; imageSrc: string }; + +type EventCardProps = EventCardMedia & { + title: string; + date: string; + description: string; accentTag: string; /** Index for numbered marker (1-based) */ index?: number; -} +};Also applies to: 39-43
🤖 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 `@src/features/community/components/EventCard.tsx` around lines 1 - 13, Update EventCardProps to use a discriminated union for its media fields, requiring either a youtubeVideoId for video cards or an imageSrc for image-only cards while disallowing both fields from being omitted or provided together. Adjust the EventCard rendering logic around the media branch to narrow on the selected property and preserve the existing video and image behavior.
45-45: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse the v4 gradient utility name for consistency.
EventCard.tsx:45usesbg-gradient-to-t, whileGameCard.tsx:50usesbg-linear-to-t. Tailwind v4 names linear gradients withbg-linear-*; use that class here if legacy gradient aliases are not intentionally needed.♻️ Proposed change
- <div className="absolute inset-0 bg-gradient-to-t from-[oklch(0.055_0_0)] via-[oklch(0.055_0_0/0.35)] to-transparent" /> + <div className="absolute inset-0 bg-linear-to-t from-[oklch(0.055_0_0)] via-[oklch(0.055_0_0/0.35)] to-transparent" />🤖 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 `@src/features/community/components/EventCard.tsx` at line 45, Update the gradient class on the overlay div in EventCard to use Tailwind v4’s bg-linear-to-t utility instead of bg-gradient-to-t, matching the existing GameCard convention while preserving the current gradient colors and direction.src/features/community/components/EventsTab.tsx (1)
35-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe pagination path is currently unreachable.
INITIAL_VISIBLEis 3 andEVENTShas 3 items, sohasMoreat Line 39 is alwaysfalseand the "Load More Events" button at Lines 77-90 never renders. If you keep the control for future events, increment by a page size instead of jumping to the full list.♻️ Proposed change
-const INITIAL_VISIBLE = 3; +const PAGE_SIZE = 2; export function EventsTab() { - const [visibleCount, setVisibleCount] = useState(INITIAL_VISIBLE); + const [visibleCount, setVisibleCount] = useState(PAGE_SIZE); const hasMore = EVENTS.length > visibleCount; const handleLoadMore = () => { - setVisibleCount(EVENTS.length); + setVisibleCount((count) => Math.min(count + PAGE_SIZE, EVENTS.length)); };🤖 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 `@src/features/community/components/EventsTab.tsx` around lines 35 - 43, Update EventsTab’s handleLoadMore to increase visibleCount by a page-sized increment rather than setting it directly to EVENTS.length, preserving the hasMore-driven “Load More Events” path for future items.src/features/community/components/GameCard.tsx (1)
40-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReduce the redundant tab stops per card.
Each card contains three
Linkelements that all navigate toctaHref. Keyboard and screen reader users must move through three identical destinations per card. Keep the title and the CTA focusable, and remove the banner link from the tab order.♻️ Proposed change
<Link to={ctaHref} + tabIndex={-1} + aria-hidden="true" className="relative block h-48 overflow-hidden focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40 sm:h-56" >Also applies to: 82-87, 94-106
🤖 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 `@src/features/community/components/GameCard.tsx` around lines 40 - 43, Update the banner Link alongside the title and CTA Links in GameCard so it remains clickable but is removed from sequential keyboard focus using the appropriate tabIndex value. Keep the title and CTA Links focusable and preserve their existing navigation to ctaHref.src/features/community/components/GameGuildsTab.tsx (1)
4-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the shared tab section shell.
This component and
GameServersTab.tsxshare the same markup: the<main>wrapper, the grid background overlay, the container, the eyebrow/heading/description block, and the card grid. Only the text and theGameCardprops differ. Extract aCommunitySectioncomponent that acceptseyebrow,heading,description, andchildren, then render each tab as a thin wrapper. The same shell would also serveEventsTab.tsxLines 46-59.🤖 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 `@src/features/community/components/GameGuildsTab.tsx` around lines 4 - 39, Extract the duplicated section markup from GameGuildsTab and GameServersTab into a shared CommunitySection component accepting eyebrow, heading, description, and children. Move the main wrapper, background overlay, container, intro block, and card-grid layout into that component, then make GameGuildsTab, GameServersTab, and the corresponding EventsTab section thin wrappers that provide their text and card content.
🤖 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.
Nitpick comments:
In `@src/features/community/components/EventCard.tsx`:
- Around line 30-36: Update the YouTube iframe in EventCard to use the
www.youtube-nocookie.com embed host and add lazy loading via the iframe’s
loading attribute, while preserving the existing video ID, title, permissions,
and fullscreen behavior.
- Line 9: Remove the unused accentLine property from EventCardProps and its
destructuring in EventCard, then stop passing accentLine from EventsTab and
remove the now-unused accentLine values from the EVENTS data. Keep the existing
accentTag behavior unchanged.
- Around line 1-13: Update EventCardProps to use a discriminated union for its
media fields, requiring either a youtubeVideoId for video cards or an imageSrc
for image-only cards while disallowing both fields from being omitted or
provided together. Adjust the EventCard rendering logic around the media branch
to narrow on the selected property and preserve the existing video and image
behavior.
- Line 45: Update the gradient class on the overlay div in EventCard to use
Tailwind v4’s bg-linear-to-t utility instead of bg-gradient-to-t, matching the
existing GameCard convention while preserving the current gradient colors and
direction.
In `@src/features/community/components/EventsTab.tsx`:
- Around line 35-43: Update EventsTab’s handleLoadMore to increase visibleCount
by a page-sized increment rather than setting it directly to EVENTS.length,
preserving the hasMore-driven “Load More Events” path for future items.
In `@src/features/community/components/GameCard.tsx`:
- Around line 40-43: Update the banner Link alongside the title and CTA Links in
GameCard so it remains clickable but is removed from sequential keyboard focus
using the appropriate tabIndex value. Keep the title and CTA Links focusable and
preserve their existing navigation to ctaHref.
In `@src/features/community/components/GameGuildsTab.tsx`:
- Around line 4-39: Extract the duplicated section markup from GameGuildsTab and
GameServersTab into a shared CommunitySection component accepting eyebrow,
heading, description, and children. Move the main wrapper, background overlay,
container, intro block, and card-grid layout into that component, then make
GameGuildsTab, GameServersTab, and the corresponding EventsTab section thin
wrappers that provide their text and card content.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c3a3e467-e176-4260-b460-a20a33f22113
⛔ Files ignored due to path filters (1)
src/assets/blackrose-valorant-event.jpgis excluded by!**/*.jpg
📒 Files selected for processing (8)
src/features/community/components/CommunityTabs.tsxsrc/features/community/components/EventCard.tsxsrc/features/community/components/EventsTab.tsxsrc/features/community/components/GameCard.tsxsrc/features/community/components/GameGuildsTab.tsxsrc/features/community/components/GameServersTab.tsxsrc/features/community/components/OverviewTab.tsxsrc/routes/community.index.tsx
Changes
Included