@@ -17,19 +17,25 @@ const Home = () => {
1717 const [ isLoading , setIsLoading ] = useState ( true ) ;
1818 const [ areButtonsDisabled , setAreButtonsDisabled ] = useState ( false ) ;
1919 const [ isAdmin , setIsAdmin ] = useState ( false ) ;
20+ const [ canSwapScenes , setCanSwapScenes ] = useState < boolean > ( false ) ;
2021 const [ scenes , setScenes ] = useState < { id : string ; name : string ; description : string ; previewImgUrl : string } [ ] > ( [ ] ) ;
2122 const [ selectedSceneId , setSelectedSceneId ] = useState ( "" ) ;
22- const [ title , setTitle ] = useState ( "Scene Swapper" ) ;
23- const [ description , setDescription ] = useState ( ) ;
24- const [ showConfirmationModal , setShowConfirmationModal ] = useState ( false ) ;
23+ const [ title , setTitle ] = useState < string > ( "Scene Swapper" ) ;
24+ const [ description , setDescription ] = useState < string > ( "" ) ;
25+ const [ allowNonAdmins , setAllowNonAdmins ] = useState < boolean > ( false ) ;
26+ const [ message , setMessage ] = useState < string > ( "" ) ;
27+ const [ showConfirmationModal , setShowConfirmationModal ] = useState < boolean > ( false ) ;
2528
2629 useEffect ( ( ) => {
2730 if ( hasSetupBackend ) {
2831 backendAPI
2932 . get ( "/game-state" )
3033 . then ( ( response ) => {
31- const { isAdmin, scenes, selectedSceneId, title, description } = response . data ;
34+ const { allowNonAdmins, isAdmin, lastSwappedDate, scenes, selectedSceneId, title, description } =
35+ response . data ;
36+ updateLastSwappedDate ( lastSwappedDate ) ;
3237 setIsAdmin ( isAdmin ) ;
38+ setAllowNonAdmins ( allowNonAdmins ) ;
3339 setScenes ( scenes ) ;
3440 setSelectedSceneId ( selectedSceneId ) ;
3541 if ( title ) setTitle ( title ) ;
@@ -46,13 +52,42 @@ const Home = () => {
4652 setAreButtonsDisabled ( true ) ;
4753 backendAPI
4854 . post ( "/replace-scene" , { selectedSceneId } )
49- . then ( ( ) => { } )
55+ . then ( ( ) => {
56+ updateLastSwappedDate ( new Date ( ) ) ;
57+ } )
5058 . catch ( ( error ) => setErrorMessage ( dispatch , error ) )
5159 . finally ( ( ) => {
5260 setAreButtonsDisabled ( false ) ;
5361 } ) ;
5462 } ;
5563
64+ const updateAllowNonAdmins = ( value : boolean ) => {
65+ setAllowNonAdmins ( value ) ;
66+ backendAPI
67+ . post ( "/allow-non-admins" , { allowNonAdmins : value } )
68+ . then ( ( ) => { } )
69+ . catch ( ( error ) => setErrorMessage ( dispatch , error ) ) ;
70+ } ;
71+
72+ const updateLastSwappedDate = ( lastSwappedDate ?: Date ) => {
73+ if ( ! isAdmin && lastSwappedDate ) {
74+ const lastSwappedDateObj = new Date ( lastSwappedDate ) ;
75+ const currentDate = new Date ( ) ;
76+ const timeDifference = currentDate . getTime ( ) - lastSwappedDateObj . getTime ( ) ;
77+ const minutesDifference = Math . floor ( timeDifference / ( 1000 * 60 ) ) ;
78+ if ( minutesDifference >= 30 ) {
79+ setCanSwapScenes ( true ) ;
80+ setMessage ( "" ) ;
81+ } else {
82+ setCanSwapScenes ( false ) ;
83+ setMessage ( "Hang tight! Scenes can only be updated every 30 minutes. Please try again soon." ) ;
84+ // setMessage(`Scene recently swapped. Please wait ${30 - minutesDifference} minutes before swapping again.`);
85+ }
86+ } else {
87+ setCanSwapScenes ( true ) ;
88+ }
89+ } ;
90+
5691 if ( ! hasSetupBackend ) return < div /> ;
5792
5893 return (
@@ -63,16 +98,16 @@ const Home = () => {
6398
6499 < PageContainer isLoading = { isLoading } >
65100 < >
66- { isAdmin ? (
101+ { isAdmin || allowNonAdmins ? (
67102 < >
68103 { title && < h1 className = "h2" > { title } </ h1 > }
69104 { description && < p > { description } </ p > }
70- < div className = "mt-4" >
105+ < div className = "mt-4 mb-10 " >
71106 { scenes ?. map ( ( scene ) => (
72107 < div key = { scene . id } className = "mb-2" onClick = { ( ) => setSelectedSceneId ( scene . id ) } >
73108 < div className = { `card small ${ selectedSceneId === scene . id ? "success" : "" } ` } >
74- < div className = "card-image" style = { { height : "auto" } } >
75- < img src = { scene . previewImgUrl } alt = { scene . name } />
109+ < div className = "card-image" >
110+ < img src = { scene . previewImgUrl } alt = { scene . name } style = { { maxHeight : "100%" } } />
76111 </ div >
77112 < div className = "card-details" >
78113 < h4 className = "card-title h4" > { scene . name } </ h4 >
@@ -81,19 +116,42 @@ const Home = () => {
81116 </ div >
82117 </ div >
83118 ) ) }
119+ { message && < p className = "text-danger py-4" > { message } </ p > }
84120 </ div >
85121
86122 < PageFooter >
87- < button className = "btn mb-2" disabled = { areButtonsDisabled || ! selectedSceneId } onClick = { replaceScene } >
88- Update Scene
89- </ button >
123+ { isAdmin && (
124+ < label className = "label text-center mb-4" >
125+ < input
126+ checked = { allowNonAdmins }
127+ className = "input-checkbox mr-2"
128+ type = "checkbox"
129+ onChange = { ( event ) => updateAllowNonAdmins ( event . target . checked ) }
130+ />
131+ Allow all users to swap scenes?
132+ </ label >
133+ ) }
90134 < button
91- className = "btn btn-danger "
92- disabled = { areButtonsDisabled }
93- onClick = { ( ) => setShowConfirmationModal ( true ) }
135+ className = "btn mb-2 "
136+ disabled = { areButtonsDisabled || ! selectedSceneId || ! canSwapScenes }
137+ onClick = { replaceScene }
94138 >
95- Clear Current Scene
139+ < div className = { ! canSwapScenes ? "tooltip" : "" } style = { { width : "100%" } } >
140+ < div className = "tooltip-content" style = { { width : "100%" , top : "-60px" } } >
141+ { message }
142+ </ div >
143+ Update Scene
144+ </ div >
96145 </ button >
146+ { isAdmin && (
147+ < button
148+ className = "btn btn-danger"
149+ disabled = { areButtonsDisabled }
150+ onClick = { ( ) => setShowConfirmationModal ( true ) }
151+ >
152+ Clear Current Scene
153+ </ button >
154+ ) }
97155 </ PageFooter >
98156 </ >
99157 ) : (
0 commit comments