Conversation
…sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources.
…ment, and dynamic tab visibility.
…ance messaging features across hackathon components
|
@Benjtalkshow is attempting to deploy a commit to the Threadflow Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThis PR adds search and type filtering to participant lists with client-side debouncing, introduces search filtering for submissions, refactors submission pagination using TanStack React Table, shifts participant filtering responsibility to the backend, and widens avatar fields across types to allow null values for improved image handling. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant ParticipantsUI as Participants Component
participant DebounceHook as Debounce Hook
participant QueryHook as use-hackathon-queries
participant API as Backend API
participant State as Local State
User->>ParticipantsUI: Enter search term
ParticipantsUI->>DebounceHook: Trigger debounce (500ms)
Note over DebounceHook: Waiting for user to stop typing
User->>ParticipantsUI: Stop typing
DebounceHook->>State: Update debouncedSearch
State->>QueryHook: Pass search & type params
QueryHook->>API: Fetch with search + type filters
API->>QueryHook: Return filtered participants
QueryHook->>ParticipantsUI: Update participants list
ParticipantsUI->>User: Display filtered results
sequenceDiagram
participant Page as Submissions Page
participant TanStackTable as TanStack React Table
participant State as Pagination State
participant QueryHook as use-organizer-submissions
participant API as Backend API
Page->>TanStackTable: Initialize with allSubmissions data
Page->>State: Set initial pagination (page, limit)
User->>TanStackTable: Click next page button
TanStackTable->>State: Trigger updateLimit or goToPage
State->>QueryHook: Update pagination state
QueryHook->>API: Fetch submissions with new page/limit
API->>QueryHook: Return paginated results
QueryHook->>State: Update allSubmissions & pagination metadata
State->>TanStackTable: Trigger re-render with new data
TanStackTable->>Page: Display next page of submissions
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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
🧹 Nitpick comments (4)
app/(landing)/hackathons/[slug]/components/tabs/contents/Participants.tsx (1)
157-163: Use namedhandle*callbacks for the new control events.The added
onChange/onClickhandlers are inline. Please extract them to named handlers (handleSearchChange,handleParticipationTypeChange) to match project conventions.As per coding guidelines: "Event handlers should start with 'handle' prefix (e.g., handleClick, handleSubmit)".
Also applies to: 219-229
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/`(landing)/hackathons/[slug]/components/tabs/contents/Participants.tsx around lines 157 - 163, Extract inline event handlers into named functions: replace the inline onChange on the search input that uses setSearchQuery with a new handleSearchChange(e: React.ChangeEvent<HTMLInputElement>) that calls setSearchQuery(e.target.value) and use handleSearchChange in the JSX; likewise replace the inline onClick/onChange used for the participation type control (lines around the participationType selection) with handleParticipationTypeChange(newType: string | ChangeEvent) that updates the corresponding state. Add these new functions near the top of the Participants component (next to existing state hooks like searchQuery and setSearchQuery) and update the JSX to reference handleSearchChange and handleParticipationTypeChange to follow the project's "handle*" event naming convention.app/(landing)/organizations/[id]/hackathons/[hackathonId]/submissions/page.tsx (1)
4-4: Remove unuseduseMemoimport.
useMemois imported but not used in this file.♻️ Remove unused import
-import { useEffect, useState, useMemo } from 'react'; +import { useEffect, useState } from 'react';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/`(landing)/organizations/[id]/hackathons/[hackathonId]/submissions/page.tsx at line 4, Remove the unused React import useMemo from the top of the submissions page component; edit the import statement that currently reads "import { useEffect, useState, useMemo } from 'react';" and remove useMemo so it becomes "import { useEffect, useState } from 'react';" (this affects the module that defines the submissions page component in this file).hooks/use-hackathons.ts (1)
33-37: Consider preserving stricter filter types.Broadening
statusandtypefrom specific union types to genericstringreduces compile-time type safety. If the allowed filter values are known and stable, keeping the union types helps catch typos and invalid values at compile time.♻️ Optional: Preserve type safety with unions
participantFilters?: { - status?: string; - type?: string; + status?: 'submitted' | 'not_submitted' | 'shortlisted' | 'disqualified'; + type?: 'individual' | 'team'; search?: string; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@hooks/use-hackathons.ts` around lines 33 - 37, The participantFilters type has widened status and type to generic string which loses compile-time safety; revert these fields to their specific union types (or existing enums) instead of string by updating the participantFilters declaration in use-hackathons.ts so that status and type use the known allowed literal unions (e.g., "active" | "pending" | "archived") or reuse existing types/enums from your domain (e.g., ParticipantStatus, ParticipantType), and update any call sites to conform to those unions.hooks/hackathon/use-organizer-submissions.ts (1)
108-117:fetchSubmissionsin dependency array creates indirect coupling.Including
fetchSubmissionsin the dependency array means the effect runs wheneverfetchSubmissionsis recreated (due to its own dependencies changing). SincedebouncedSearch,filters.status,filters.type, andpagination.limitare also direct dependencies of this effect AND infetchSubmissions's dependencies, there's redundancy that makes the data flow harder to trace.Consider removing
fetchSubmissionsfrom the dependency array and calling the fetch logic directly, or using a ref to avoid the coupling.♻️ Simpler approach using a fetch ref
+ const fetchRef = useRef(fetchSubmissions); + fetchRef.current = fetchSubmissions; + // Sync with backend on filter/pagination changes useEffect(() => { - fetchSubmissions(1); - }, [ - fetchSubmissions, - debouncedSearch, - filters.status, - filters.type, - pagination.limit, - ]); + fetchRef.current(1); + }, [debouncedSearch, filters.status, filters.type, pagination.limit]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@hooks/hackathon/use-organizer-submissions.ts` around lines 108 - 117, The effect is indirectly coupled to fetchSubmissions because it's included in the dependency array; remove fetchSubmissions from the useEffect deps and instead call the fetch logic via a stable ref or inline the call to avoid redundant reruns. Concretely, create a ref (e.g., fetchSubmissionsRef) and set fetchSubmissionsRef.current = fetchSubmissions wherever fetchSubmissions is defined/updated, then in the useEffect (which should depend only on debouncedSearch, filters.status, filters.type, pagination.limit) call fetchSubmissionsRef.current(1); alternatively, move the minimal fetch logic used by fetchSubmissions directly into the useEffect so the deps are only debouncedSearch, filters.status, filters.type, pagination.limit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/organization/hackathons/ParticipantsTable.tsx`:
- Around line 113-116: The status narrowing in ParticipantsTable incorrectly
casts submission.status to only 'SHORTLISTED'|'DISQUALIFIED'|'SUBMITTED',
causing other upstream values (e.g., WITHDRAWN) to be misrendered and action
logic to misbehave; update the status handling to be exhaustive by deriving
status from the real upstream enum/type (or using a safe switch/map over
submission.status) and add an explicit case/default for other statuses (e.g.,
'WITHDRAWN' -> 'Withdrawn', unknown -> 'Unknown' or a disabled state). Apply
this change wherever status is used (the initial cast of submission.status, the
rendering branch around 121-133, and the action logic that reads status for
deciding actions like at the current action handler) so display labels and
allowed actions remain consistent for all possible upstream values.
In `@components/organization/hackathons/submissions/SubmissionsManagement.tsx`:
- Line 57: The onPageSizeChange prop declared in the component props interface
is never used; update the SubmissionsManagement component by either removing
onPageSizeChange from the props interface to eliminate dead API, or add it to
the function parameter destructuring for SubmissionsManagement and wire it to
the page-size change logic (e.g., call onPageSizeChange(size) from the existing
page size change handler or pass it into the Pagination/PageSize selector you
use) so the external callback is invoked when page size changes.
In `@hooks/hackathon/use-register-hackathon.ts`:
- Line 125: The hasSubmitted boolean currently only checks for
participant?.submission?.status === 'SUBMITTED' which will be false for
participants whose submissions are in SHORTLISTED or DISQUALIFIED states; update
the logic in use-register-hackathon.ts (the hasSubmitted property) to treat
those statuses as submitted — e.g. check if participant?.submission?.status is
in the accepted set ['SUBMITTED','SHORTLISTED','DISQUALIFIED'] or,
alternatively, check that a submission exists and its status is not a
draft/incomplete state, then return true.
In `@lib/api/hackathon.ts`:
- Around line 109-115: The getHackathonSubmissions call is appending unsupported
filters (search) to the request causing silent unfiltered results; remove any
code that appends params.search (and other unsupported filters like sort) when
building the query so only page and limit are sent, update the params
type/signature to only expose page?: number and limit?: number, and ensure
callers (e.g., submissions page/hooks) perform client-side filtering instead of
relying on server-side search.
In `@lib/api/hackathons.ts`:
- Around line 697-702: The participant.image property is declared as optional
string (image?: string) but the backend can return null; update the participant
type so image allows null (e.g., image?: string | null) wherever the participant
shape is defined (the participant property in the hackathons API types) so the
generated types match backend responses.
---
Nitpick comments:
In `@app/`(landing)/hackathons/[slug]/components/tabs/contents/Participants.tsx:
- Around line 157-163: Extract inline event handlers into named functions:
replace the inline onChange on the search input that uses setSearchQuery with a
new handleSearchChange(e: React.ChangeEvent<HTMLInputElement>) that calls
setSearchQuery(e.target.value) and use handleSearchChange in the JSX; likewise
replace the inline onClick/onChange used for the participation type control
(lines around the participationType selection) with
handleParticipationTypeChange(newType: string | ChangeEvent) that updates the
corresponding state. Add these new functions near the top of the Participants
component (next to existing state hooks like searchQuery and setSearchQuery) and
update the JSX to reference handleSearchChange and handleParticipationTypeChange
to follow the project's "handle*" event naming convention.
In
`@app/`(landing)/organizations/[id]/hackathons/[hackathonId]/submissions/page.tsx:
- Line 4: Remove the unused React import useMemo from the top of the submissions
page component; edit the import statement that currently reads "import {
useEffect, useState, useMemo } from 'react';" and remove useMemo so it becomes
"import { useEffect, useState } from 'react';" (this affects the module that
defines the submissions page component in this file).
In `@hooks/hackathon/use-organizer-submissions.ts`:
- Around line 108-117: The effect is indirectly coupled to fetchSubmissions
because it's included in the dependency array; remove fetchSubmissions from the
useEffect deps and instead call the fetch logic via a stable ref or inline the
call to avoid redundant reruns. Concretely, create a ref (e.g.,
fetchSubmissionsRef) and set fetchSubmissionsRef.current = fetchSubmissions
wherever fetchSubmissions is defined/updated, then in the useEffect (which
should depend only on debouncedSearch, filters.status, filters.type,
pagination.limit) call fetchSubmissionsRef.current(1); alternatively, move the
minimal fetch logic used by fetchSubmissions directly into the useEffect so the
deps are only debouncedSearch, filters.status, filters.type, pagination.limit.
In `@hooks/use-hackathons.ts`:
- Around line 33-37: The participantFilters type has widened status and type to
generic string which loses compile-time safety; revert these fields to their
specific union types (or existing enums) instead of string by updating the
participantFilters declaration in use-hackathons.ts so that status and type use
the known allowed literal unions (e.g., "active" | "pending" | "archived") or
reuse existing types/enums from your domain (e.g., ParticipantStatus,
ParticipantType), and update any call sites to conform to those unions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d13e7d13-2915-41fc-b2b4-442226aaf4e5
📒 Files selected for processing (15)
app/(landing)/hackathons/[slug]/components/tabs/contents/Participants.tsxapp/(landing)/organizations/[id]/hackathons/[hackathonId]/participants/page.tsxapp/(landing)/organizations/[id]/hackathons/[hackathonId]/submissions/page.tsxcomponents/hackathons/submissions/SubmissionDetailModal.tsxcomponents/organization/cards/Participant.tsxcomponents/organization/hackathons/ParticipantsGrid.tsxcomponents/organization/hackathons/ParticipantsTable.tsxcomponents/organization/hackathons/submissions/SubmissionsManagement.tsxhooks/hackathon/use-hackathon-queries.tshooks/hackathon/use-organizer-submissions.tshooks/hackathon/use-register-hackathon.tshooks/use-hackathons.tshooks/use-submission-actions.tslib/api/hackathon.tslib/api/hackathons.ts
| loading: boolean; | ||
| onFilterChange: (filters: SubmissionFilters) => void; | ||
| onPageChange: (page: number) => void; | ||
| onPageSizeChange?: (size: number) => void; |
There was a problem hiding this comment.
onPageSizeChange prop is defined but never used.
The onPageSizeChange prop is added to the interface but is not destructured in the component function parameters (lines 69-81), making it dead API surface. Either remove it from the interface or add it to the destructured parameters and wire it up.
🔧 Proposed fix: Remove unused prop or wire it up
Option A: Remove the unused prop
interface SubmissionsManagementProps {
...
onPageChange: (page: number) => void;
- onPageSizeChange?: (size: number) => void;
onRefresh: () => void;Option B: Destructure and use it
export function SubmissionsManagement({
...
onPageChange,
+ onPageSizeChange,
onRefresh,📝 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.
| onPageSizeChange?: (size: number) => void; | |
| interface SubmissionsManagementProps { | |
| organizationId: string; | |
| hackathonId: string; | |
| onPageChange: (page: number) => void; | |
| onRefresh: () => void; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/organization/hackathons/submissions/SubmissionsManagement.tsx` at
line 57, The onPageSizeChange prop declared in the component props interface is
never used; update the SubmissionsManagement component by either removing
onPageSizeChange from the props interface to eliminate dead API, or add it to
the function parameter destructuring for SubmissionsManagement and wire it to
the page-size change logic (e.g., call onPageSizeChange(size) from the existing
page size change handler or pass it into the Pagination/PageSize selector you
use) so the external callback is invoked when page size changes.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
lib/api/hackathons.ts (1)
642-680: Inconsistent avatar nullability in related types.While
ParticipantTeamMember.avatarandParticipant.user.profile.imagehave been widened tostring | null, the following nested avatar fields remain asavatar?: string:
- Line 651:
ParticipantVote.user.profile.avatar- Line 668:
ParticipantComment.user.profile.avatar- Line 710:
ParticipantSubmission.reviewedBy.avatarIf the backend can return
nullfor these avatars as well, consider widening them for consistency.🔧 Suggested consistency fix
export interface ParticipantVote { id: string; userId: string; user: { id: string; profile: { firstName: string; lastName: string; username: string; - avatar?: string; + avatar?: string | null; }; email: string; }; // ... } export interface ParticipantComment { id: string; userId: string; user: { id: string; profile: { firstName: string; lastName: string; username: string; - avatar?: string; + avatar?: string | null; }; email: string; }; // ... }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/api/hackathons.ts` around lines 642 - 680, The nested avatar fields are inconsistently optional strings while other related types use string | null; update the avatar types to match by changing ParticipantVote.user.profile.avatar and ParticipantComment.user.profile.avatar from avatar?: string to avatar: string | null, and also update ParticipantSubmission.reviewedBy.avatar to avatar: string | null (ensure the ParticipantVote, ParticipantComment, and ParticipantSubmission interfaces and any nested reviewedBy type are adjusted so consumers handle null consistently).types/hackathon/participant.ts (1)
24-97: Consolidate duplicate type definitions to a single source.This file defines
ParticipantTeamMember,ParticipantVote,ParticipantComment,ParticipantSubmission, andParticipantinterfaces that are also defined inlib/api/hackathons.ts. Type inconsistencies exist across these duplicates:
ParticipantVoteandParticipantComment:avatar?: string | nullin types/ vsavatar?: stringin lib/api/ParticipantSubmission: Similar avatar nullability difference, plus additional structural divergence (lib/api version includessubmittedAt,participationType,participantfields)- Additional duplication:
ParticipantsDataandParticipantinterfaces are also defined in both locationsThis duplication increases type drift risk. Since
lib/api/hackathons.tsis imported by significantly more files across the codebase, consider either:
- Consolidating all types in
types/hackathon/participant.tsand importing inlib/api/hackathons.ts- Ensuring both files stay strictly synchronized
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@types/hackathon/participant.ts` around lines 24 - 97, This file duplicates participant-related interfaces already defined in lib/api/hackathons.ts (ParticipantTeamMember, ParticipantVote, ParticipantComment, ParticipantSubmission, Participant and ParticipantsData) causing nullability and shape drift (e.g. avatar?: string | null vs avatar?: string, and fields like submittedAt/participationType/participant missing). Fix by consolidating to a single source of truth: remove the duplicate interfaces from types/hackathon/participant.ts and import the canonical types from lib/api/hackathons.ts (or vice-versa if you choose the types file as canonical), update all references to use the imported types, and reconcile nullability/extra fields so ParticipantVote, ParticipantComment, ParticipantSubmission and ParticipantTeamMember align exactly with the canonical definitions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/`(landing)/hackathons/[slug]/components/header/ActionButtons.tsx:
- Around line 41-42: Replace the unsafe cast in the participant identity check:
in the arrow predicate that currently uses "(p as any).userId === user.id ||
p.user?.id === user.id", remove the any cast and use the typed property
"p.userId" instead (i.e., "p.userId === user.id || p.user?.id === user.id") so
the Participant type is respected; ensure the predicate parameter remains typed
as Participant and that optional chaining on p.user?.id is preserved.
In `@components/hackathons/submissions/submissionCard.tsx`:
- Line 31: The header avatar currently constructs `url(${submitterAvatar})` even
when `submitterAvatar` can be null; update the component (submissionCard / the
header avatar rendering) to use a safe fallback image or initials when
`submitterAvatar` is null or empty—e.g., compute a resolvedAvatar =
submitterAvatar ?? '<fallback-url-or-empty>' (or conditionally render a
placeholder/avatar-initials) and use that value wherever
`url(${submitterAvatar})` is used so the UI never attempts to load a null URL.
In `@components/organization/cards/ReviewSubmissionModal/types.ts`:
- Line 5: SubmissionCommentsTab passes comment.author.avatar (now typed string |
null) directly to AvatarImage; make it null-safe by normalizing to undefined
like the other tabs—replace the direct prop with comment.author.avatar ||
undefined in SubmissionCommentsTab (the prop passed to AvatarImage around the
current line 41) so it matches the pattern used in TeamSection.tsx and
SubmissionVotesTab.tsx.
---
Nitpick comments:
In `@lib/api/hackathons.ts`:
- Around line 642-680: The nested avatar fields are inconsistently optional
strings while other related types use string | null; update the avatar types to
match by changing ParticipantVote.user.profile.avatar and
ParticipantComment.user.profile.avatar from avatar?: string to avatar: string |
null, and also update ParticipantSubmission.reviewedBy.avatar to avatar: string
| null (ensure the ParticipantVote, ParticipantComment, and
ParticipantSubmission interfaces and any nested reviewedBy type are adjusted so
consumers handle null consistently).
In `@types/hackathon/participant.ts`:
- Around line 24-97: This file duplicates participant-related interfaces already
defined in lib/api/hackathons.ts (ParticipantTeamMember, ParticipantVote,
ParticipantComment, ParticipantSubmission, Participant and ParticipantsData)
causing nullability and shape drift (e.g. avatar?: string | null vs avatar?:
string, and fields like submittedAt/participationType/participant missing). Fix
by consolidating to a single source of truth: remove the duplicate interfaces
from types/hackathon/participant.ts and import the canonical types from
lib/api/hackathons.ts (or vice-versa if you choose the types file as canonical),
update all references to use the imported types, and reconcile nullability/extra
fields so ParticipantVote, ParticipantComment, ParticipantSubmission and
ParticipantTeamMember align exactly with the canonical definitions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 01d9be19-fa16-4a02-8d14-b69cad9cfb64
📒 Files selected for processing (14)
app/(landing)/hackathons/[slug]/components/header/ActionButtons.tsxapp/(landing)/hackathons/[slug]/components/tabs/contents/Participants.tsxcomponents/hackathons/submissions/submissionCard.tsxcomponents/hackathons/submissions/submissionCard2.tsxcomponents/organization/cards/ParticipantInfo.tsxcomponents/organization/cards/ReviewSubmissionModal/SubmissionVotesTab.tsxcomponents/organization/cards/ReviewSubmissionModal/TeamSection.tsxcomponents/organization/cards/ReviewSubmissionModal/types.tscomponents/organization/cards/TeamModal.tsxcomponents/organization/hackathons/ParticipantsTable.tsxhooks/hackathon/use-register-hackathon.tshooks/use-participant-submission.tslib/api/hackathons.tstypes/hackathon/participant.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- components/organization/hackathons/ParticipantsTable.tsx
- hooks/hackathon/use-register-hackathon.ts
| (p: Participant) => | ||
| (p as any).userId === user.id || p.user?.id === user.id |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify there are no `any` escapes left in this component.
rg -nP --type=tsx '\bas\s+any\b|:\s*any\b' 'app/(landing)/hackathons/[slug]/components/header/ActionButtons.tsx'Repository: boundlessfi/boundless
Length of output: 92
🏁 Script executed:
#!/bin/bash
# Read the file around the flagged lines
cat -n 'app/(landing)/hackathons/[slug]/components/header/ActionButtons.tsx' | head -60 | tail -30
echo "---"
# Search for 'any' in the file without type restrictions
rg -n 'as any|: any' 'app/(landing)/hackathons/[slug]/components/header/ActionButtons.tsx'
echo "---"
# Find the Participant type definition
rg -n 'type Participant|interface Participant' --no-headingRepository: boundlessfi/boundless
Length of output: 4586
🏁 Script executed:
#!/bin/bash
# Read the Participant interface definition
cat -n 'types/hackathon/participant.ts' | sed -n '99,128p'Repository: boundlessfi/boundless
Length of output: 879
Remove any cast in participant check.
Line 42 uses (p as any).userId, which drops type safety and is unnecessary since the Participant interface already defines userId as a direct property.
Suggested fix
- (hackathon?.participants || []).some(
- (p: Participant) =>
- (p as any).userId === user.id || p.user?.id === user.id
- )
+ (hackathon?.participants || []).some(
+ (p: Participant) => p.userId === user.id || p.user?.id === user.id
+ )📝 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.
| (p: Participant) => | |
| (p as any).userId === user.id || p.user?.id === user.id | |
| (hackathon?.participants || []).some( | |
| (p: Participant) => p.userId === user.id || p.user?.id === user.id | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/`(landing)/hackathons/[slug]/components/header/ActionButtons.tsx around
lines 41 - 42, Replace the unsafe cast in the participant identity check: in the
arrow predicate that currently uses "(p as any).userId === user.id || p.user?.id
=== user.id", remove the any cast and use the typed property "p.userId" instead
(i.e., "p.userId === user.id || p.user?.id === user.id") so the Participant type
is respected; ensure the predicate parameter remains typed as Participant and
that optional chaining on p.user?.id is preserved.
| description: string; | ||
| submitterName: string; | ||
| submitterAvatar?: string; | ||
| submitterAvatar?: string | null; |
There was a problem hiding this comment.
Add a null-avatar fallback in the header avatar UI.
Line 31 now allows null, but the current header avatar still builds url(${submitterAvatar}) unconditionally, which can render a broken avatar for missing images.
Suggested fix
- <div
- style={{ backgroundImage: `url(${submitterAvatar})` }}
- className={`size-8 rounded-full border-2 bg-white bg-cover bg-center ${isPinned ? 'border-primary' : 'border-[`#2B2B2B`]'}`}
- ></div>
+ {submitterAvatar ? (
+ <div
+ style={{ backgroundImage: `url(${submitterAvatar})` }}
+ className={`size-8 rounded-full border-2 bg-white bg-cover bg-center ${isPinned ? 'border-primary' : 'border-[`#2B2B2B`]'}`}
+ />
+ ) : (
+ <div
+ className={`flex size-8 items-center justify-center rounded-full border-2 bg-zinc-800 text-xs font-bold text-zinc-300 ${isPinned ? 'border-primary' : 'border-[`#2B2B2B`]'}`}
+ >
+ {submitterName.charAt(0).toUpperCase()}
+ </div>
+ )}📝 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.
| submitterAvatar?: string | null; | |
| {submitterAvatar ? ( | |
| <div | |
| style={{ backgroundImage: `url(${submitterAvatar})` }} | |
| className={`size-8 rounded-full border-2 bg-white bg-cover bg-center ${isPinned ? 'border-primary' : 'border-[`#2B2B2B`]'}`} | |
| /> | |
| ) : ( | |
| <div | |
| className={`flex size-8 items-center justify-center rounded-full border-2 bg-zinc-800 text-xs font-bold text-zinc-300 ${isPinned ? 'border-primary' : 'border-[`#2B2B2B`]'}`} | |
| > | |
| {submitterName.charAt(0).toUpperCase()} | |
| </div> | |
| )} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/hackathons/submissions/submissionCard.tsx` at line 31, The header
avatar currently constructs `url(${submitterAvatar})` even when
`submitterAvatar` can be null; update the component (submissionCard / the header
avatar rendering) to use a safe fallback image or initials when
`submitterAvatar` is null or empty—e.g., compute a resolvedAvatar =
submitterAvatar ?? '<fallback-url-or-empty>' (or conditionally render a
placeholder/avatar-initials) and use that value wherever
`url(${submitterAvatar})` is used so the UI never attempts to load a null URL.
| name: string; | ||
| role: string; | ||
| avatar?: string; | ||
| avatar?: string | null; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check nullable avatar usage patterns in ReviewSubmissionModal components.
rg -nP --type=tsx 'src=\{comment\.author\.avatar\}' components/organization/cards/ReviewSubmissionModal
rg -nP --type=tsx 'src=\{(member|voter)\.avatar\s*(\|\||\?\?)\s*undefined\}' components/organization/cards/ReviewSubmissionModalRepository: boundlessfi/boundless
Length of output: 120
🏁 Script executed:
#!/bin/bash
# First, explore the ReviewSubmissionModal directory structure
echo "=== Directory structure ==="
find components/organization/cards/ReviewSubmissionModal -type f | head -20
echo ""
echo "=== Search for avatar usage without type restriction ==="
rg -n 'src.*avatar' components/organization/cards/ReviewSubmissionModal
echo ""
echo "=== Search for comment.author.avatar specifically ==="
rg -n 'comment\.author\.avatar' components/organization/cards/ReviewSubmissionModal
echo ""
echo "=== Check types.ts file content ==="
cat -n components/organization/cards/ReviewSubmissionModal/types.tsRepository: boundlessfi/boundless
Length of output: 3076
Fix avatar null-safety in SubmissionCommentsTab after type widening.
After widening the avatar fields to string | null (lines 5, 13, 24 in types.ts), SubmissionCommentsTab.tsx still passes comment.author.avatar directly to AvatarImage without normalization. Update line 41 to use comment.author.avatar || undefined to match the null-safe pattern already applied in TeamSection.tsx (line 41) and SubmissionVotesTab.tsx (line 46).
Also applies to: 13-13, 24-24
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/organization/cards/ReviewSubmissionModal/types.ts` at line 5,
SubmissionCommentsTab passes comment.author.avatar (now typed string | null)
directly to AvatarImage; make it null-safe by normalizing to undefined like the
other tabs—replace the direct prop with comment.author.avatar || undefined in
SubmissionCommentsTab (the prop passed to AvatarImage around the current line
41) so it matches the pattern used in TeamSection.tsx and
SubmissionVotesTab.tsx.
* fix: fix prize teirs place * fix: fix prize teirs place * Pr 486 (#488) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> * Pr 486 (#490) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type * fix: enhanced filtering for organizations * fix: fix coderabbit corrections --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com>
* fix: fix prize teirs place * fix: fix prize teirs place * Pr 486 (#488) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> * Pr 486 (#490) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type * fix: enhanced filtering for organizations * fix: fix coderabbit corrections --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> * fix: sync production with main changes --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com>
* Pr 486 (#488) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> * Pr 486 (#490) * feat: Implement comprehensive hackathon detail page with new header, sidebar, and tabbed content sections including teams, announcements, winners, participants, and resources. * fix: update coderabit * feat: Enhance hackathon team invitation flow, recruitment post management, and dynamic tab visibility. * feat: Integrate AuthModalProvider for authentication handling and enhance messaging features across hackathon components * fix: fix pagination issues in particiapants and submissions page for organizers * fix: remove any type * fix: enhanced filtering for organizations * fix: fix coderabbit corrections --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com> --------- Co-authored-by: Collins Ikechukwu <collinschristroa@gmail.com>
Summary by CodeRabbit
New Features
Bug Fixes