1- import React , { useState , useEffect } from 'react' ;
1+ import React , { useState , useEffect , useMemo } from 'react' ;
22import PropTypes from 'prop-types' ;
33import { Modal , Button } from 'react-bootstrap' ;
4- import { connect } from 'react-redux' ;
4+ import { connect , useSelector } from 'react-redux' ;
55import axios from 'axios' ;
66import { ENDPOINTS } from '~/utils/URL' ;
77import styles from './HelpModal.module.css' ;
@@ -12,22 +12,43 @@ function HelpModal({ show, onHide, auth }) {
1212 const [ options , setOptions ] = useState ( [ ] ) ;
1313 const [ loading , setLoading ] = useState ( true ) ;
1414 const [ error , setError ] = useState ( null ) ;
15+ const [ teams , setTeams ] = useState ( [ ] ) ;
16+
17+ const darkMode = useSelector ( state => state . theme . darkMode ) ;
18+
19+ const userId = auth ?. user ?. userid ;
1520
16- // Fetch Help Categories
1721 useEffect ( ( ) => {
1822 const fetchHelpCategories = async ( ) => {
1923 try {
20- const response = await axios . get ( ENDPOINTS . HELP_CATEGORIES ) ;
21- setOptions ( response . data . map ( category => category . name ) ) ;
22- setLoading ( false ) ;
23- } catch ( err ) {
24+ const categoriesResponse = await axios . get ( ENDPOINTS . HELP_CATEGORIES ) ;
25+ setOptions ( categoriesResponse . data . map ( category => category . name ) ) ;
26+ } catch {
2427 setError ( 'Failed to load help categories' ) ;
28+ } finally {
2529 setLoading ( false ) ;
2630 }
2731 } ;
32+
2833 fetchHelpCategories ( ) ;
2934 } , [ ] ) ;
3035
36+ useEffect ( ( ) => {
37+ if ( ! userId ) return ;
38+
39+ const fetchUserProfile = async ( ) => {
40+ try {
41+ const profileResponse = await axios . get ( ENDPOINTS . USER_PROFILE ( userId ) ) ;
42+ setTeams ( profileResponse . data ?. teams || [ ] ) ;
43+ } catch ( err ) {
44+ console . error ( 'Failed to fetch user profile' , err ) ;
45+ setTeams ( [ ] ) ;
46+ }
47+ } ;
48+
49+ fetchUserProfile ( ) ;
50+ } , [ userId ] ) ;
51+
3152 const handleSelect = option => {
3253 setSelectedOption ( option ) ;
3354 setIsOpen ( false ) ;
@@ -44,32 +65,59 @@ function HelpModal({ show, onHide, auth }) {
4465 onHide ( ) ;
4566 } ;
4667
68+ /* ---------------- Access Logic ---------------- */
69+ const role = auth ?. user ?. role ?. trim ( ) . toLowerCase ( ) || '' ;
70+
71+ const allowedRoles = useMemo ( ( ) => new Set ( [ 'owner' , 'administrator' ] ) , [ ] ) ;
72+
73+ const isSoftwareDevMember = useMemo ( ( ) => {
74+ return (
75+ allowedRoles . has ( role ) ||
76+ teams . some ( team => team . teamName ?. trim ( ) . toLowerCase ( ) === 'software development team' )
77+ ) ;
78+ } , [ allowedRoles , teams , role ] ) ;
79+
4780 const renderContent = ( ) => {
4881 if ( loading ) return < div > Loading categories...</ div > ;
4982 if ( error ) return < div className = "text-danger" > { error } </ div > ;
5083
5184 return (
5285 < >
5386 < div
54- className = { styles . selectButton }
87+ className = { ` ${ styles . selectButton } ${ darkMode ? styles . selectButtonDark : '' } ` }
5588 onClick = { ( ) => setIsOpen ( ! isOpen ) }
5689 role = "button"
5790 tabIndex = { 0 }
5891 onKeyDown = { e => {
5992 if ( e . key === 'Enter' || e . key === ' ' ) setIsOpen ( ! isOpen ) ;
6093 } }
6194 >
62- < span className = { `${ styles . selectButtonText } ${ selectedOption ? styles . selected : '' } ` } >
95+ < span
96+ className = { `${ styles . selectButtonText }
97+ ${ selectedOption ? styles . selected : '' }
98+ ${ darkMode ? styles . selectButtonTextDark : '' }
99+ ${ darkMode && selectedOption ? styles . selectedDark : '' }
100+ ` }
101+ >
63102 { selectedOption || 'Select an option' }
64103 </ span >
65- < span className = { `${ styles . selectButtonArrow } ${ isOpen ? styles . open : '' } ` } />
104+
105+ < span
106+ className = { `${ styles . selectButtonArrow } ${ isOpen ? styles . open : '' } ${
107+ darkMode ? styles . selectButtonArrowDark : ''
108+ } `}
109+ />
66110 </ div >
111+
67112 { isOpen && (
68- < div className = { styles . selectOptions } role = "listbox" >
113+ < div
114+ className = { `${ styles . selectOptions } ${ darkMode ? styles . selectOptionsDark : '' } ` }
115+ role = "listbox"
116+ >
69117 { options . map ( option => (
70118 < div
71119 key = { option }
72- className = { styles . selectOption }
120+ className = { ` ${ styles . selectOption } ${ darkMode ? styles . selectOptionDark : '' } ` }
73121 onClick = { ( ) => handleSelect ( option ) }
74122 role = "option"
75123 tabIndex = { 0 }
@@ -87,52 +135,38 @@ function HelpModal({ show, onHide, auth }) {
87135 ) ;
88136 } ;
89137
90- // ---- Access Logic ----
91- const user = auth ?. user || { } ;
92- const role = user . role ?. trim ( ) . toLowerCase ( ) || '' ;
93-
94- const allowedRoles = [ 'owner' , 'administrator' ] ;
95-
96- // User must be in Software Development Team OR have one of the allowed roles
97- const isSoftwareDevMember =
98- user . teams ?. some ( team => team . teamName ?. trim ( ) . toLowerCase ( ) === 'software development team' ) ||
99- allowedRoles . includes ( role ) ;
100-
101- console . log ( 'User Role:' , role ) ;
102- console . log ( 'Teams:' , user . teams ) ;
103- console . log ( 'isSoftwareDevMember:' , isSoftwareDevMember ) ;
104-
105- // ---- Modal Layout ----
106138 return (
107- < Modal show = { show } onHide = { onHide } className = { styles . helpModal } centered >
139+ < Modal
140+ show = { show }
141+ onHide = { onHide }
142+ centered
143+ className = { `${ styles . helpModal } ${ darkMode ? styles . darkMode : '' } ` }
144+ >
108145 < Modal . Header closeButton >
109146 < Modal . Title > What do you need help with?</ Modal . Title >
110147 </ Modal . Header >
148+
111149 < Modal . Body >
112150 < div className = { styles . selectContainer } > { renderContent ( ) } </ div >
113151
114152 { ! isSoftwareDevMember && (
115153 < div className = "alert alert-warning mt-3" >
116- Only members from the software development team can seek help
154+ Only members of the Software Development Team can submit requests.
117155 </ div >
118156 ) }
119157
120- < p className = { styles . textMuted } >
121- If you have any suggestions please click
158+ < p className = { ` ${ styles . textMuted } ${ darkMode ? styles . textMutedDark : '' } ` } >
159+ If you have any suggestions please click{ ' ' }
122160 < button
123161 type = "button"
124- className = "btn btn-link p-0 border-0 align-baseline"
162+ className = "p-0 border-0 align-baseline"
125163 onClick = { handleSuggestionsClick }
126- style = { {
127- color : '#0066CC' ,
128- textDecoration : 'none' ,
129- marginLeft : '4px' ,
130- } }
131164 >
132165 here
133166 </ button >
134167 </ p >
135168 </ Modal . Body >
169+
136170 < Modal . Footer >
137171 < Button
138172 variant = "primary"
@@ -146,18 +180,14 @@ function HelpModal({ show, onHide, auth }) {
146180 ) ;
147181}
148182
149- // ---- PropTypes ----
183+ /* ---------------- PropTypes ---------------- */
150184HelpModal . propTypes = {
151185 show : PropTypes . bool . isRequired ,
152186 onHide : PropTypes . func . isRequired ,
153187 auth : PropTypes . shape ( {
154188 user : PropTypes . shape ( {
189+ userid : PropTypes . string ,
155190 role : PropTypes . string ,
156- teams : PropTypes . arrayOf (
157- PropTypes . shape ( {
158- teamName : PropTypes . string ,
159- } ) ,
160- ) ,
161191 } ) ,
162192 } ) . isRequired ,
163193} ;
0 commit comments