55import useSWR , { SWRResponse } from 'swr'
66
77import { handleError } from '~/libs/shared'
8+ import { UserRole } from '~/libs/core'
89
910import { BackendSubmission , BackendSubmissionStatus } from '../models'
1011import { fetchSubmissions } from '../services'
@@ -22,13 +23,20 @@ interface ChallengeSubmissionsMemoResult {
2223 filteredSubmissions : BackendSubmission [ ]
2324}
2425
26+ export interface ChallengeSubmissionsViewer {
27+ roles ?: Array < string | undefined | null >
28+ tokenRoles ?: Array < string | undefined | null >
29+ userId ?: string | number | null
30+ }
31+
2532/**
2633 * Fetch challenge submissions
2734 * @param challengeId challenge id
2835 * @returns challenge submissions
2936 */
3037export function useFetchChallengeSubmissions (
3138 challengeId ?: string ,
39+ viewer ?: ChallengeSubmissionsViewer ,
3240) : useFetchChallengeSubmissionsProps {
3341 // Use swr hooks for submissions fetching
3442 const {
@@ -46,6 +54,92 @@ export function useFetchChallengeSubmissions(
4654 isPaused : ( ) => ! challengeId ,
4755 } )
4856
57+ const normalizedRoles = useMemo < string [ ] > (
58+ ( ) => ( viewer ?. roles ?? [ ] )
59+ . map ( role => ( role ? `${ role } ` . toLowerCase ( )
60+ . trim ( ) : '' ) )
61+ . filter ( Boolean ) ,
62+ [ viewer ?. roles ] ,
63+ )
64+ const normalizedTokenRoles = useMemo < string [ ] > (
65+ ( ) => ( viewer ?. tokenRoles ?? [ ] )
66+ . map ( role => ( typeof role === 'string' ? role . toLowerCase ( )
67+ . trim ( ) : '' ) )
68+ . filter ( Boolean ) ,
69+ [ viewer ?. tokenRoles ] ,
70+ )
71+ const hasSubmitterRole = useMemo < boolean > (
72+ ( ) => normalizedRoles . some ( role => role . includes ( 'submitter' ) ) ,
73+ [ normalizedRoles ] ,
74+ )
75+ const hasCopilotRole = useMemo < boolean > (
76+ ( ) => normalizedRoles . some ( role => role . includes ( 'copilot' ) ) ,
77+ [ normalizedRoles ] ,
78+ )
79+ const hasReviewerRole = useMemo < boolean > (
80+ ( ) => normalizedRoles . some ( role => role . includes ( 'reviewer' ) ) ,
81+ [ normalizedRoles ] ,
82+ )
83+ const hasManagerRole = useMemo < boolean > (
84+ ( ) => normalizedRoles . some ( role => role . includes ( 'manager' ) ) ,
85+ [ normalizedRoles ] ,
86+ )
87+ const hasScreenerRole = useMemo < boolean > (
88+ ( ) => normalizedRoles . some ( role => role . includes ( 'screener' ) ) ,
89+ [ normalizedRoles ] ,
90+ )
91+ const hasApproverRole = useMemo < boolean > (
92+ ( ) => normalizedRoles . some ( role => role . includes ( 'approver' ) ) ,
93+ [ normalizedRoles ] ,
94+ )
95+ const isProjectManager = useMemo < boolean > (
96+ ( ) => normalizedTokenRoles . some (
97+ role => role === UserRole . projectManager . toLowerCase ( ) ,
98+ )
99+ || normalizedRoles . some ( role => role . includes ( 'project manager' ) ) ,
100+ [ normalizedRoles , normalizedTokenRoles ] ,
101+ )
102+ const isAdmin = useMemo < boolean > (
103+ ( ) => normalizedTokenRoles . some (
104+ role => role === UserRole . administrator . toLowerCase ( ) ,
105+ )
106+ || normalizedRoles . some ( role => role . includes ( 'admin' ) ) ,
107+ [ normalizedRoles , normalizedTokenRoles ] ,
108+ )
109+ const canViewAllSubmissions = useMemo < boolean > (
110+ ( ) => ( viewer ? (
111+ isAdmin
112+ || hasCopilotRole
113+ || hasReviewerRole
114+ || hasManagerRole
115+ || hasScreenerRole
116+ || hasApproverRole
117+ || isProjectManager
118+ ) : true ) ,
119+ [
120+ viewer ,
121+ isAdmin ,
122+ hasCopilotRole ,
123+ hasReviewerRole ,
124+ hasManagerRole ,
125+ hasScreenerRole ,
126+ hasApproverRole ,
127+ isProjectManager ,
128+ ] ,
129+ )
130+ const viewerMemberId = useMemo < string | undefined > (
131+ ( ) => {
132+ const raw = viewer ?. userId
133+ if ( raw === undefined || raw === null ) {
134+ return undefined
135+ }
136+
137+ const normalized = `${ raw } ` . trim ( )
138+ return normalized . length ? normalized : undefined
139+ } ,
140+ [ viewer ?. userId ] ,
141+ )
142+
49143 // Show backend error when fetching data fail
50144 useEffect ( ( ) => {
51145 if ( error ) {
@@ -69,6 +163,10 @@ export function useFetchChallengeSubmissions(
69163 const normalizedDeletedIds = new Set < string > ( )
70164 const normalizedDeletedLegacyIds = new Set < string > ( )
71165 const activeSubmissions : BackendSubmission [ ] = [ ]
166+ const shouldRestrictToCurrentMember = Boolean (
167+ hasSubmitterRole
168+ && ! canViewAllSubmissions ,
169+ )
72170
73171 const normalizeStatus = ( status : unknown ) : string => {
74172 if ( typeof status === 'string' ) {
@@ -105,12 +203,23 @@ export function useFetchChallengeSubmissions(
105203 activeSubmissions . push ( submission )
106204 } )
107205
206+ const visibleSubmissions = shouldRestrictToCurrentMember
207+ ? activeSubmissions . filter ( submission => ( viewerMemberId
208+ ? `${ submission ?. memberId ?? '' } ` === viewerMemberId
209+ : false ) )
210+ : activeSubmissions
211+
108212 return {
109213 deletedLegacySubmissionIds : normalizedDeletedLegacyIds ,
110214 deletedSubmissionIds : normalizedDeletedIds ,
111- filteredSubmissions : activeSubmissions ,
215+ filteredSubmissions : visibleSubmissions ,
112216 }
113- } , [ challengeSubmissions ] )
217+ } , [
218+ challengeSubmissions ,
219+ canViewAllSubmissions ,
220+ hasSubmitterRole ,
221+ viewerMemberId ,
222+ ] )
114223
115224 return {
116225 challengeSubmissions : filteredSubmissions ,
0 commit comments