11import React , { useState , useEffect } from 'react' ;
22import { healthCheck , updateSignText } from '../../APIFunctions/LedSign' ;
3+ import { getPermissionRequest , createPermissionRequest } from '../../APIFunctions/PermissionRequest' ;
34import { useSCE } from '../../Components/context/SceContext' ;
5+ import { membershipState } from '../../Enums' ;
46
57import './ledsign.css' ;
68
@@ -20,6 +22,9 @@ function LedSign() {
2022 const [ awaitingSignResponse , setAwaitingSignResponse ] = useState ( false ) ;
2123 const [ requestSuccessful , setRequestSuccessful ] = useState ( ) ;
2224 const [ stopRequestSuccesful , setStopRequestSuccesful ] = useState ( ) ;
25+ const [ permissionRequest , setPermissionRequest ] = useState ( null ) ;
26+ const [ checkingPermission , setCheckingPermission ] = useState ( false ) ;
27+ const [ requestingPermission , setRequestingPermission ] = useState ( false ) ;
2328 const inputArray = [
2429 {
2530 title : 'Sign Text:' ,
@@ -211,11 +216,24 @@ function LedSign() {
211216 }
212217 setLoading ( false ) ;
213218 }
219+
220+ async function checkPermission ( ) {
221+ if ( user . accessLevel < membershipState . OFFICER ) {
222+ setCheckingPermission ( true ) ;
223+ const result = await getPermissionRequest ( 'LED_SIGN' , user . token ) ;
224+ if ( ! result . error && result . responseData ) {
225+ setPermissionRequest ( result . responseData ) ;
226+ }
227+ setCheckingPermission ( false ) ;
228+ }
229+ }
230+
214231 checkSignHealth ( ) ;
232+ checkPermission ( ) ;
215233 // eslint-disable-next-line
216234 } , [ ] )
217235
218- if ( loading ) {
236+ if ( loading || checkingPermission ) {
219237 return (
220238 < svg className = "animate-spin h-5 w-5 mr-3 ..." viewBox = "0 0 24 24" >
221239 </ svg >
@@ -231,6 +249,60 @@ function LedSign() {
231249 ) ;
232250 }
233251
252+ async function handleRequestAccess ( ) {
253+ setRequestingPermission ( true ) ;
254+ const result = await createPermissionRequest ( 'LED_SIGN' , user . token ) ;
255+ if ( ! result . error ) {
256+ setPermissionRequest ( result . responseData ) ;
257+ }
258+ setRequestingPermission ( false ) ;
259+ }
260+
261+ function renderPermissionRequestUI ( ) {
262+ if ( user . accessLevel >= membershipState . OFFICER ) {
263+ return null ;
264+ }
265+
266+ if ( checkingPermission ) {
267+ return (
268+ < div className = "w-2/3 lg:w-1/2 text-center py-4" >
269+ < p > Checking access...</ p >
270+ </ div >
271+ ) ;
272+ }
273+
274+ if ( permissionRequest ) {
275+ return (
276+ < div className = "w-2/3 lg:w-1/2 text-center py-4 space-y-2" >
277+ < p className = "text-gray-700 dark:text-gray-300" >
278+ You requested access to the sign on { getFormattedTime ( permissionRequest . createdAt ) } .
279+ </ p >
280+ < p className = "text-sm text-gray-600 dark:text-gray-400 italic" >
281+ Drop a message in Discord to speed up the process!
282+ </ p >
283+ </ div >
284+ ) ;
285+ }
286+
287+ return (
288+ < div className = "w-2/3 lg:w-1/2 text-center py-4 space-y-2" >
289+ < p className = "text-gray-700 dark:text-gray-300" >
290+ You need permission to access the LED sign.
291+ </ p >
292+ < button
293+ className = "btn bg-blue-500 hover:bg-blue-400 text-white"
294+ onClick = { handleRequestAccess }
295+ disabled = { requestingPermission }
296+ >
297+ { requestingPermission ? 'Requesting...' : 'Request Access' }
298+ </ button >
299+ < p className = "text-sm text-gray-600 dark:text-gray-400 italic" >
300+ Drop a message in Discord to speed up the process
301+ </ p >
302+ </ div >
303+ ) ;
304+ }
305+
234306 function getAnimationDuration ( ) {
235307 // the scrollSpeed input can be can be anywhere from 0 to 10. the
236308 // lower the duration is, the faster the text scrolls. we divide by
@@ -239,80 +311,87 @@ function LedSign() {
239311 return ( 11 - scrollSpeed ) ;
240312 }
241313
314+ const hasAccess = user . accessLevel >= membershipState . OFFICER ;
315+
242316 return (
243317 < div >
244- < div className = "space-y-12 mt-10 gap-x-6 gap-y-8 w-full sm:grid-cols-6" >
245- < div className = "flex border-b border-gray-900/10 pb-12 md:w-full" >
246- < div className = "flex flex-col justify-center items-center sm:col-span-3 w-full" >
247- < div className = 'w-2/3 lg:w-1/2' >
248- < label > Preview</ label >
249- < div >
250- < div
251- className = "led-sign-preview-border-top"
252- style = { { backgroundColor : borderColor } }
253- > </ div >
254- < div
255- className = "led-sign-preview-background"
256- style = { { backgroundColor : backgroundColor } }
257- >
258- < div className = "led-sign-marquee-container" >
259- < div className = "led-sign-marquee" style = { { animationDuration : `${ getAnimationDuration ( ) } s` } } >
260- < h1 className = "led-sign-preview-text text-3xl" style = { { color : textColor } } placeholder = "Sign Text" >
261- { /*
318+ { ! hasAccess && (
319+ < div className = "flex justify-center items-center mt-10 w-full" >
320+ { renderPermissionRequestUI ( ) }
321+ </ div >
322+ ) }
323+ { hasAccess && (
324+ < div className = "space-y-12 mt-10 gap-x-6 gap-y-8 w-full sm:grid-cols-6" >
325+ < div className = "flex border-b border-gray-900/10 pb-12 md:w-full" >
326+ < div className = "flex flex-col justify-center items-center sm:col-span-3 w-full" >
327+ < div className = 'w-2/3 lg:w-1/2' >
328+ < label > Preview</ label >
329+ < div >
330+ < div
331+ className = "led-sign-preview-border-top"
332+ style = { { backgroundColor : borderColor } }
333+ > </ div >
334+ < div
335+ className = "led-sign-preview-background"
336+ style = { { backgroundColor : backgroundColor } }
337+ >
338+ < div className = "led-sign-marquee-container" >
339+ < div className = "led-sign-marquee" style = { { animationDuration : `${ getAnimationDuration ( ) } s` } } >
340+ < h1 className = "led-sign-preview-text text-3xl" style = { { color : textColor } } placeholder = "Sign Text" >
341+ { /*
262342 we add a padding of 28 characters of whitespace so the entire message
263343 scrolls to the end of the preview before repeating. the preview has a
264344 width of about 28 characters.
265345 */ }
266- { text . padEnd ( 28 , ' ' ) }
267- </ h1 >
346+ { text . padEnd ( 28 , ' ' ) }
347+ </ h1 >
348+ </ div >
268349 </ div >
269350 </ div >
351+ < div
352+ className = "led-sign-preview-border-bottom"
353+ style = { { backgroundColor : borderColor } }
354+ > </ div >
270355 </ div >
271- < div
272- className = "led-sign-preview-border-bottom"
273- style = { { backgroundColor : borderColor } }
274- > </ div >
275356 </ div >
276- </ div >
277- { maybeShowExpirationDate ( ) }
278- { getExpirationButtonOrInput ( ) }
279- {
280- inputArray . map ( ( {
281- id ,
282- title ,
283- type ,
284- value ,
285- onChange ,
286- ... rest
287- } ) => (
288- < div key = { title } className = "sm:col-span-2 sm:col-start-1 w-2/3 lg:w-1/2 " >
289- < div className = "mt-2 " >
290- < label htmlFor = "copies" className = "block text-sm font-medium leading-6" > { title } </ label >
291- < input
292- type = { type }
293- value = { value }
294- id = { id }
295- onChange = { onChange }
296- className = "indent-2 text-black dark:text-white block w-full rounded-md border-0 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-500 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
297- { ... rest }
298- / >
357+ { maybeShowExpirationDate ( ) }
358+ { getExpirationButtonOrInput ( ) }
359+ {
360+ inputArray . map ( ( {
361+ id ,
362+ title ,
363+ type ,
364+ value ,
365+ onChange ,
366+ ... rest
367+ } ) => (
368+ < div key = { title } className = "sm:col-span-2 sm:col-start-1 w-2/3 lg:w-1/2" >
369+ < div className = "mt-2 " >
370+ < label htmlFor = "copies" className = "block text-sm font-medium leading-6" > { title } </ label >
371+ < input
372+ type = { type }
373+ value = { value }
374+ id = { id }
375+ onChange = { onChange }
376+ className = "indent-2 text-black dark:text-white block w-full rounded-md border-0 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-500 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
377+ { ... rest }
378+ />
379+ </ div >
299380 </ div >
300- </ div >
301- ) )
302- }
381+ ) )
382+ }
303383
304- < button className = 'btn w-2/3 lg:w-1/2 bg-red-500 hover:bg-red-400 text-black mt-4' onClick = { handleStop } >
384+ < button className = 'btn w-2/3 lg:w-1/2 bg-red-500 hover:bg-red-400 text-black mt-4' onClick = { handleStop } >
305385 Stop
306- </ button >
307- < button className = 'btn w-2/3 lg:w-1/2 bg-green-500 hover:bg-green-400 text-black mt-2' onClick = { handleSend } >
386+ </ button >
387+ < button className = 'btn w-2/3 lg:w-1/2 bg-green-500 hover:bg-green-400 text-black mt-2' onClick = { handleSend } >
308388 Send
309- </ button >
310- { renderRequestStatus ( ) }
389+ </ button >
390+ { renderRequestStatus ( ) }
391+ </ div >
311392 </ div >
312393 </ div >
313-
314- </ div >
315-
394+ ) }
316395 </ div >
317396 ) ;
318397}
0 commit comments