11import React , { useState , useEffect } from 'react' ;
22import { healthCheck , updateSignText } from '../../APIFunctions/LedSign' ;
33import { useSCE } from '../../Components/context/SceContext' ;
4+
45import './ledsign.css' ;
56
67function LedSign ( ) {
78 const { user } = useSCE ( ) ;
89 const [ signHealthy , setSignHealthy ] = useState ( false ) ;
10+ const [ showInput , setInput ] = useState ( false ) ;
911 const [ loading , setLoading ] = useState ( true ) ;
1012 const [ text , setText ] = useState ( '' ) ;
1113 const [ brightness , setBrightness ] = useState ( 50 ) ;
1214 const [ scrollSpeed , setScrollSpeed ] = useState ( 5 ) ;
1315 const [ backgroundColor , setBackgroundColor ] = useState ( '#0000ff' ) ;
1416 const [ textColor , setTextColor ] = useState ( '#00ff00' ) ;
1517 const [ borderColor , setBorderColor ] = useState ( '#ff0000' ) ;
18+ const [ expiration , setExpiration ] = useState ( null ) ;
19+ const [ existingExpirationFromSign , setExistingExpirationFromSign ] = useState ( null ) ;
1620 const [ awaitingSignResponse , setAwaitingSignResponse ] = useState ( false ) ;
17- const [ awaitingStopSignResponse , setAwaitingStopSignResponse ]
18- = useState ( false ) ;
1921 const [ requestSuccessful , setRequestSuccessful ] = useState ( ) ;
2022 const [ stopRequestSuccesful , setStopRequestSuccesful ] = useState ( ) ;
21-
2223 const inputArray = [
2324 {
2425 title : 'Sign Text:' ,
@@ -67,7 +68,43 @@ function LedSign() {
6768 }
6869 ] ;
6970
71+ function isExpired ( ) {
72+ if ( ! expiration ) {
73+ return false ;
74+ }
75+ const currDate = new Date ( ) ;
76+ const expireDateObject = new Date ( expiration ) ;
77+ return expireDateObject < currDate ;
78+ }
79+
80+ function getFormattedTime ( maybeISOString = null ) {
81+ let date = new Date ( ) ;
82+ if ( maybeISOString ) {
83+ date = new Date ( maybeISOString ) ;
84+ }
85+
86+ return date . toLocaleString ( 'en-US' , {
87+ year : 'numeric' ,
88+ month : '2-digit' ,
89+ day : '2-digit' ,
90+ hour : 'numeric' ,
91+ minute : '2-digit' ,
92+ hour12 : true ,
93+ timeZoneName : 'short' ,
94+ } ) ;
95+ }
96+
97+ async function handleExpiration ( ) {
98+ setExpiration ( null ) ;
99+ setInput ( ! showInput ) ;
100+ }
101+
70102 async function handleSend ( ) {
103+ let expirationToUse = null ;
104+ if ( expiration ) {
105+ expirationToUse = new Date ( expiration ) . toISOString ( ) ;
106+ }
107+
71108 setAwaitingSignResponse ( true ) ;
72109 let correctedScrollSpeed = 10 - scrollSpeed ;
73110 const signResponse = await updateSignText (
@@ -78,6 +115,7 @@ function LedSign() {
78115 backgroundColor,
79116 textColor,
80117 borderColor,
118+ expiration : expirationToUse ,
81119 email : user . email ,
82120 firstName : user . firstName ,
83121 } ,
@@ -88,7 +126,6 @@ function LedSign() {
88126 }
89127
90128 async function handleStop ( ) {
91- setAwaitingStopSignResponse ( true ) ;
92129 const signResponse = await updateSignText (
93130 {
94131 ledIsOff : true ,
@@ -98,7 +135,6 @@ function LedSign() {
98135 user . token
99136 ) ;
100137 setStopRequestSuccesful ( ! signResponse . error ) ;
101- setAwaitingStopSignResponse ( false ) ;
102138 }
103139
104140 function renderRequestStatus ( ) {
@@ -115,20 +151,60 @@ function LedSign() {
115151 ) ;
116152 }
117153 }
154+
155+ function maybeShowExpirationDate ( ) {
156+ if ( ! existingExpirationFromSign ) {
157+ return < > </ > ;
158+ }
159+ const humanizedExpiration = new Date ( existingExpirationFromSign )
160+ . toLocaleString ( 'en-US' , {
161+ timeZoneName : 'short' // e.g., "Pacific Standard Time"
162+ } ) ;
163+ return < p > The current sign message will expire on { humanizedExpiration } </ p > ;
164+ }
165+
166+ function getExpirationButtonOrInput ( ) {
167+ if ( showInput ) {
168+ return < >
169+ < div className = 'w-2/3 lg:w-1/2 flex items-center justify-items-center flex-col items-center sm:flex-row' >
170+ < input className = 'm-1 mt-6 w-full rounded-md text-center flex-1 sm:pt-1 pl-4' type = "datetime-local" id = "endTime" name = "endTime" onChange = { e => setExpiration ( e . target . value ) } />
171+ < button className = 'btn w-full bg-gray-600 hover:bg-gray-500 text-white mr-4 sm:w-1/3 ml-5 mt-5 mb-3' onClick = { e => setInput ( ! showInput ) } >
172+ Cancel Expiration
173+ </ button >
174+ </ div >
175+ {
176+ isExpired ( ) && < div className = "w-2/3 lg:w-1/2 text-left break-words" >
177+ < p className = 'text-red-600 dark:text-red-400' >
178+ Your selected expiration is considered behind the current time of { getFormattedTime ( ) } .
179+ </ p >
180+ < p className = 'text-red-600 dark:text-red-400' >
181+ Submitting a message with this expiration will not update the sign.
182+ </ p >
183+ </ div >
184+ }
185+ </ > ;
186+ }
187+
188+ return < button className = 'btn w-2/3 lg:w-1/2 bg-gray-500 hover:bg-gray-400 text-white mt-2' onClick = { handleExpiration } >
189+ Set Expiration
190+ </ button > ;
191+ }
192+
118193 useEffect ( ( ) => {
119194 async function checkSignHealth ( ) {
120195 setLoading ( true ) ;
121196 const status = await healthCheck ( user . firstName ) ;
122197 if ( status && ! status . error ) {
123198 setSignHealthy ( true ) ;
124199 const { responseData } = status ;
125- if ( responseData && responseData . text ) {
200+ if ( Object . keys ( responseData ) . length > 0 ) {
126201 setText ( responseData . text ) ;
127202 setBrightness ( responseData . brightness ) ;
128203 setScrollSpeed ( responseData . scrollSpeed ) ;
129204 setBackgroundColor ( responseData . backgroundColor ) ;
130205 setTextColor ( responseData . textColor ) ;
131206 setBorderColor ( responseData . borderColor ) ;
207+ setExistingExpirationFromSign ( responseData . expiration ) ;
132208 }
133209 } else {
134210 setSignHealthy ( false ) ;
@@ -198,6 +274,8 @@ function LedSign() {
198274 > </ div >
199275 </ div >
200276 </ div >
277+ { maybeShowExpirationDate ( ) }
278+ { getExpirationButtonOrInput ( ) }
201279 {
202280 inputArray . map ( ( {
203281 id,
0 commit comments