@@ -35,6 +35,29 @@ export default function ContestDetailsPage() {
3535 const [ contestData , setContestData ] = useState ( defaultContestData ) ;
3636 const [ isLoading , setIsLoading ] = useState ( true ) ;
3737 const [ error , setError ] = useState < string | null > ( null ) ;
38+ const [ userRole , setUserRole ] = useState < string | null > ( null ) ;
39+
40+ useEffect ( ( ) => {
41+ const fetchUserData = async ( ) => {
42+ try {
43+ const res = await fetch ( '/api/me' ) ;
44+ if ( ! res . ok ) {
45+ throw new Error ( 'Failed to fetch user data' ) ;
46+ }
47+ const userData = await res . json ( ) ;
48+
49+ // Find the user's role in the current organization
50+ const currentOrg = userData . orgs . find ( ( org : any ) => org . nameId === orgId ) ;
51+ if ( currentOrg ) {
52+ setUserRole ( currentOrg . role ) ;
53+ }
54+ } catch ( err ) {
55+ console . error ( 'Error fetching user data:' , err ) ;
56+ }
57+ } ;
58+
59+ fetchUserData ( ) ;
60+ } , [ orgId ] ) ;
3861
3962 useEffect ( ( ) => {
4063 const fetchContestData = async ( ) => {
@@ -122,6 +145,18 @@ export default function ContestDetailsPage() {
122145 } ;
123146
124147 const status = getContestStatus ( ) ;
148+
149+ // Determine if problems should be shown
150+ const shouldShowProblems = ( ) => {
151+ const now = new Date ( ) ;
152+ const startTime = new Date ( contestData . startTime ) ;
153+
154+ // If contest has started, show problems to everyone
155+ if ( now >= startTime ) return true ;
156+
157+ // For upcoming contests, only show problems to non-members (admins, instructors)
158+ return userRole !== 'member' ;
159+ } ;
125160
126161 if ( isLoading ) {
127162 return (
@@ -179,28 +214,33 @@ export default function ContestDetailsPage() {
179214 </ div >
180215 </ div >
181216
182- < div >
183- < h3 className = "text-lg font-semibold mb-2 flex items-center" >
184- { /* <ListIcon className="mr-2 h-5 w-5" /> */ }
185- Problems
186- </ h3 >
187- < ul className = "space-y-2 px-2" >
188- { contestData . problems . map (
189- ( problem : { id : string ; title : string } ) => (
190- < li key = { problem . id } >
191- < Link href = { `/${ orgId } /problems/${ problem . id } ` } >
192- < Button
193- variant = "link"
194- className = "p-0 h-auto text-primary hover:text-primary/80"
195- >
196- { problem . title }
197- </ Button >
198- </ Link >
199- </ li >
200- ) ,
201- ) }
202- </ ul >
203- </ div >
217+ { shouldShowProblems ( ) ? (
218+ < div >
219+ < h3 className = "text-lg font-semibold mb-2 flex items-center" >
220+ Problems
221+ </ h3 >
222+ < ul className = "space-y-2 px-2" >
223+ { contestData . problems . map (
224+ ( problem : { id : string ; title : string } ) => (
225+ < li key = { problem . id } >
226+ < Link href = { `/${ orgId } /problems/${ problem . id } ` } >
227+ < Button
228+ variant = "link"
229+ className = "p-0 h-auto text-primary hover:text-primary/80"
230+ >
231+ { problem . title }
232+ </ Button >
233+ </ Link >
234+ </ li >
235+ ) ,
236+ ) }
237+ </ ul >
238+ </ div >
239+ ) : (
240+ < div className = "text-muted-foreground italic" >
241+ Problems will be available when the contest starts.
242+ </ div >
243+ ) }
204244 </ CardContent >
205245 </ Card >
206246 </ div >
0 commit comments