Skip to content

Commit 0572c22

Browse files
committed
permsision request button for led sign page
1 parent 9a70800 commit 0572c22

File tree

3 files changed

+198
-60
lines changed

3 files changed

+198
-60
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { ApiResponse } from './ApiResponses';
2+
import { BASE_API_URL } from '../Enums';
3+
4+
export async function getPermissionRequest(type, token) {
5+
const status = new ApiResponse();
6+
const url = new URL('/api/PermissionRequest/get', BASE_API_URL);
7+
url.searchParams.append('type', type);
8+
9+
try {
10+
const res = await fetch(url.toString(), {
11+
headers: {
12+
Authorization: `Bearer ${token}`,
13+
},
14+
});
15+
16+
if (res.ok) {
17+
const data = await res.json();
18+
status.responseData = data;
19+
} else if (res.status === 404) {
20+
status.responseData = null;
21+
} else {
22+
status.error = true;
23+
}
24+
} catch (err) {
25+
status.responseData = err;
26+
status.error = true;
27+
}
28+
29+
return status;
30+
}
31+
32+
export async function createPermissionRequest(type, token) {
33+
const status = new ApiResponse();
34+
const url = new URL('/api/PermissionRequest/create', BASE_API_URL);
35+
36+
try {
37+
const res = await fetch(url.toString(), {
38+
method: 'POST',
39+
headers: {
40+
'Content-Type': 'application/json',
41+
Authorization: `Bearer ${token}`,
42+
},
43+
body: JSON.stringify({ type }),
44+
});
45+
46+
if (res.ok) {
47+
const data = await res.json();
48+
status.responseData = data;
49+
} else {
50+
status.error = true;
51+
}
52+
} catch (err) {
53+
status.responseData = err;
54+
status.error = true;
55+
}
56+
57+
return status;
58+
}
59+

src/Pages/LedSign/LedSign.js

Lines changed: 138 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React, { useState, useEffect } from 'react';
22
import { healthCheck, updateSignText } from '../../APIFunctions/LedSign';
3+
import { getPermissionRequest, createPermissionRequest } from '../../APIFunctions/PermissionRequest';
34
import { useSCE } from '../../Components/context/SceContext';
5+
import { membershipState } from '../../Enums';
46

57
import './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
}

src/Routes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export const officerOrAdminRoutes = [
105105
Component: LedSign,
106106
path: '/led-sign',
107107
pageName: 'LED Sign',
108-
allowedIf: allowedIf.OFFICER_OR_ADMIN,
108+
allowedIf: allowedIf.MEMBER,
109109
redirect: '/',
110110
inAdminNavbar: true
111111
},

0 commit comments

Comments
 (0)