From a9a79d75f7c6ac28a7e3306cb2175c449f1cbe3c Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Wed, 19 Jul 2023 20:04:37 +0530 Subject: [PATCH 01/17] Update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 8b182cf..cd588f7 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ yarn-debug.log* yarn-error.log* .env + +/.idea From 2f3daab0c561d1f5e125080e86802614164b2153 Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Mon, 7 Aug 2023 22:33:52 +0530 Subject: [PATCH 02/17] Implement UI of 'resources/{id}/check-in-out' page --- public/assets/images/fp_3.png | Bin 0 -> 7082 bytes src/navigation/routes.tsx | 6 ++ .../check-in-out/CheckInOutContainer.tsx | 84 ++++++++++++++++++ src/pages/check-in-out/FingerprintUI.tsx | 73 +++++++++++++++ src/pages/check-in-out/fingerprint.css | 15 ++++ 5 files changed, 178 insertions(+) create mode 100644 public/assets/images/fp_3.png create mode 100644 src/pages/check-in-out/CheckInOutContainer.tsx create mode 100644 src/pages/check-in-out/FingerprintUI.tsx create mode 100644 src/pages/check-in-out/fingerprint.css diff --git a/public/assets/images/fp_3.png b/public/assets/images/fp_3.png new file mode 100644 index 0000000000000000000000000000000000000000..3673dfb626501d8770d15fd7c9d8b1160bf50fce GIT binary patch literal 7082 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 { @@ -18,6 +19,11 @@ const AppRoutes = () => { }/> }/> }/> + + + } /> + + ); diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx new file mode 100644 index 0000000..cddc0e8 --- /dev/null +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -0,0 +1,84 @@ +import React, { useEffect, useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { Resource, User } from "../../types"; +import ResourcesServices from "../../services/ResourcesServices"; +import { useSelector } from "react-redux"; +import { AppState } from "../../redux/reducer"; +import FingerprintUi from "./FingerprintUI"; +import CssBaseline from "@mui/material/CssBaseline"; +import AppbarComponent from "../../components/AppbarComponent"; +import DrawerComponent from "../../components/DrawerComponent"; +import { Box, Container, Paper, Toolbar, Typography } from "@mui/material"; +import ThemeProvider from "@mui/material/styles/ThemeProvider"; +import { createTheme } from "@mui/material/styles"; +import Copyright from "../../components/Copyright"; + +const dashboardTheme = createTheme({ + palette: { + primary: { + main: "#3f51b5", + }, + secondary: { + main: "#f50057", + }, + }, +}); + +export default function CheckInOutContainer() { + const [resource, setResource] = useState(null); + const user: User | null = useSelector((state: AppState) => state.user.user); + const { resourceId } = useParams(); + const navigate = useNavigate(); + + useEffect(() => { + if (!user) { + navigate("/"); + } + + if (user.role !== "RESOURCE_MANAGER" && user.role !== "ADMIN") { + navigate("/dashboard"); + } + }, []); + + const [open, setOpen] = useState(false); + const toggleDrawer = () => { + setOpen(!open); + }; + + useEffect(() => { + const fetchResource = async () => { + const id = parseInt(resourceId); + if (isNaN(id)) { + setResource(null); + return; + } + + const res = await ResourcesServices.getResourceById(id, user.token); + + if (res.data && res.data.id) setResource(res.data); + else setResource(null); + }; + + fetchResource(); + }, [resourceId]); + + return ( + + + + + + + + + {resource && } + {!resource && ( + Resource not found. + )} + + + + + + ); +} diff --git a/src/pages/check-in-out/FingerprintUI.tsx b/src/pages/check-in-out/FingerprintUI.tsx new file mode 100644 index 0000000..54d0c95 --- /dev/null +++ b/src/pages/check-in-out/FingerprintUI.tsx @@ -0,0 +1,73 @@ +import React, { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { Box, Button, Typography, useTheme } from "@mui/material"; +import FingerprintImg from "public/assets/images/fp_3.png"; +import "./fingerprint.css"; + +export default function FingerprintUi(props: any) { + const { resourceName } = props; + const navigate = useNavigate(); + const isStudent = true; + + const theme = useTheme(); + const containerWidth = theme.breakpoints.down("sm") ? "70%" : "30%"; + + return ( + + + {resourceName} + + + Please place your finger on the scanner + + fingerprint image + {isStudent && ( + + )} + + ); +} + +const headingStyle: React.CSSProperties = { + marginBottom: "2%", + fontSize: 28, + letterSpacing: "1px", + textAlign: "center", +}; + +const formContainerStyle: React.CSSProperties = { + padding: "30px", + alignItems: "center", + justifyContent: "center", + display: "flex", + flexDirection: "column", + margin: "0 auto", + boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.2)", + backgroundColor: "#FFFFFF", + borderRadius: "3%", +}; diff --git a/src/pages/check-in-out/fingerprint.css b/src/pages/check-in-out/fingerprint.css new file mode 100644 index 0000000..08d320f --- /dev/null +++ b/src/pages/check-in-out/fingerprint.css @@ -0,0 +1,15 @@ +@keyframes fade { + 0% { + opacity: 1; + } + 50% { + opacity: 0.5; + } + 100% { + opacity: 1; + } +} + +.fingerprint-animation { + animation: fade 2s ease-in-out infinite; +} From f5740228d3bb96cf887614ce94bb05ed1e253cdc Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Wed, 9 Aug 2023 16:20:19 +0530 Subject: [PATCH 03/17] Update UI of /resources/{id}/check-in-out --- .../check-in-out/CheckInOutContainer.tsx | 168 +++++++++--------- src/pages/check-in-out/FingerprintUI.tsx | 146 +++++++-------- 2 files changed, 157 insertions(+), 157 deletions(-) diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index cddc0e8..c9b7da7 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -1,84 +1,84 @@ -import React, { useEffect, useState } from "react"; -import { useNavigate, useParams } from "react-router-dom"; -import { Resource, User } from "../../types"; -import ResourcesServices from "../../services/ResourcesServices"; -import { useSelector } from "react-redux"; -import { AppState } from "../../redux/reducer"; -import FingerprintUi from "./FingerprintUI"; -import CssBaseline from "@mui/material/CssBaseline"; -import AppbarComponent from "../../components/AppbarComponent"; -import DrawerComponent from "../../components/DrawerComponent"; -import { Box, Container, Paper, Toolbar, Typography } from "@mui/material"; -import ThemeProvider from "@mui/material/styles/ThemeProvider"; -import { createTheme } from "@mui/material/styles"; -import Copyright from "../../components/Copyright"; - -const dashboardTheme = createTheme({ - palette: { - primary: { - main: "#3f51b5", - }, - secondary: { - main: "#f50057", - }, - }, -}); - -export default function CheckInOutContainer() { - const [resource, setResource] = useState(null); - const user: User | null = useSelector((state: AppState) => state.user.user); - const { resourceId } = useParams(); - const navigate = useNavigate(); - - useEffect(() => { - if (!user) { - navigate("/"); - } - - if (user.role !== "RESOURCE_MANAGER" && user.role !== "ADMIN") { - navigate("/dashboard"); - } - }, []); - - const [open, setOpen] = useState(false); - const toggleDrawer = () => { - setOpen(!open); - }; - - useEffect(() => { - const fetchResource = async () => { - const id = parseInt(resourceId); - if (isNaN(id)) { - setResource(null); - return; - } - - const res = await ResourcesServices.getResourceById(id, user.token); - - if (res.data && res.data.id) setResource(res.data); - else setResource(null); - }; - - fetchResource(); - }, [resourceId]); - - return ( - - - - - - - - - {resource && } - {!resource && ( - Resource not found. - )} - - - - - - ); -} +import React, { useEffect, useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import { Resource, User } from "../../types"; +import ResourcesServices from "../../services/ResourcesServices"; +import { useSelector } from "react-redux"; +import { AppState } from "../../redux/reducer"; +import FingerprintUi from "./FingerprintUI"; +import CssBaseline from "@mui/material/CssBaseline"; +import AppbarComponent from "../../components/AppbarComponent"; +import DrawerComponent from "../../components/DrawerComponent"; +import { Box, Container, Paper, Toolbar, Typography } from "@mui/material"; +import ThemeProvider from "@mui/material/styles/ThemeProvider"; +import { createTheme } from "@mui/material/styles"; +import Copyright from "../../components/Copyright"; + +const dashboardTheme = createTheme({ + palette: { + primary: { + main: "#3f51b5", + }, + secondary: { + main: "#f50057", + }, + }, +}); + +export default function CheckInOutContainer() { + const [resource, setResource] = useState(null); + const user: User | null = useSelector((state: AppState) => state.user.user); + const { resourceId } = useParams(); + const navigate = useNavigate(); + + useEffect(() => { + if (!user) { + navigate("/"); + } + + if (user.role !== "RESOURCE_MANAGER" && user.role !== "ADMIN") { + navigate("/dashboard"); + } + }, []); + + const [open, setOpen] = useState(false); + const toggleDrawer = () => { + setOpen(!open); + }; + + useEffect(() => { + const fetchResource = async () => { + const id = parseInt(resourceId); + if (isNaN(id)) { + setResource(null); + return; + } + + const res = await ResourcesServices.getResourceById(id, user.token); + + if (res.data && res.data.id) setResource(res.data); + else setResource(null); + }; + + fetchResource(); + }, [resourceId]); + + return ( + + + + + + + + + {resource && } + {!resource && ( + Resource not found. + )} + + + + + + ); +} diff --git a/src/pages/check-in-out/FingerprintUI.tsx b/src/pages/check-in-out/FingerprintUI.tsx index 54d0c95..05724da 100644 --- a/src/pages/check-in-out/FingerprintUI.tsx +++ b/src/pages/check-in-out/FingerprintUI.tsx @@ -1,73 +1,73 @@ -import React, { useEffect } from "react"; -import { useNavigate } from "react-router-dom"; -import { Box, Button, Typography, useTheme } from "@mui/material"; -import FingerprintImg from "public/assets/images/fp_3.png"; -import "./fingerprint.css"; - -export default function FingerprintUi(props: any) { - const { resourceName } = props; - const navigate = useNavigate(); - const isStudent = true; - - const theme = useTheme(); - const containerWidth = theme.breakpoints.down("sm") ? "70%" : "30%"; - - return ( - - - {resourceName} - - - Please place your finger on the scanner - - fingerprint image - {isStudent && ( - - )} - - ); -} - -const headingStyle: React.CSSProperties = { - marginBottom: "2%", - fontSize: 28, - letterSpacing: "1px", - textAlign: "center", -}; - -const formContainerStyle: React.CSSProperties = { - padding: "30px", - alignItems: "center", - justifyContent: "center", - display: "flex", - flexDirection: "column", - margin: "0 auto", - boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.2)", - backgroundColor: "#FFFFFF", - borderRadius: "3%", -}; +import React, { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { Box, Button, Typography, useTheme } from "@mui/material"; +import FingerprintImg from "public/assets/images/fp_3.png"; +import "./fingerprint.css"; + +export default function FingerprintUi(props: any) { + const { resourceName } = props; + const navigate = useNavigate(); + const isStudent = true; + + const theme = useTheme(); + const containerWidth = theme.breakpoints.down("sm") ? "70%" : "30%"; + + return ( + + + {resourceName} + + + Please place your finger on the scanner + + fingerprint image + {isStudent && ( + + )} + + ); +} + +const headingStyle: React.CSSProperties = { + marginBottom: "2%", + fontSize: 28, + letterSpacing: "1px", + textAlign: "center", +}; + +const formContainerStyle: React.CSSProperties = { + padding: "30px", + alignItems: "center", + justifyContent: "center", + display: "flex", + flexDirection: "column", + margin: "0 auto", + boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.2)", + backgroundColor: "#FFFFFF", + borderRadius: "3%", +}; From a6f956c06fc8db262dfa9bb1d952725b2f68605e Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Wed, 9 Aug 2023 16:28:21 +0530 Subject: [PATCH 04/17] Send requests to fingerprint device 10 times per second for '/requests/{id}/check-in-out' route --- .env | 1 + .../check-in-out/CheckInOutContainer.tsx | 33 ++++++++++++++++++- src/pages/check-in-out/FingerprintUI.tsx | 3 +- src/services/FingerprintAuthServices.ts | 19 +++++++++++ .../fingerprintService/FingerprintService.ts | 26 +++++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/services/FingerprintAuthServices.ts create mode 100644 src/services/fingerprintService/FingerprintService.ts diff --git a/.env b/.env index 6d17ee8..4a325bf 100644 --- a/.env +++ b/.env @@ -1,2 +1,3 @@ REACT_APP_BACKEND_URL='http://localhost:8080/' REACT_APP_VITE_NAME = "Booking App" +REACT_APP_FINGERPRINT_SERVICE_URL="http://localhost:7291/reg/rcapture" diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index c9b7da7..f590c9a 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -12,6 +12,8 @@ import { Box, Container, Paper, Toolbar, Typography } from "@mui/material"; import ThemeProvider from "@mui/material/styles/ThemeProvider"; import { createTheme } from "@mui/material/styles"; import Copyright from "../../components/Copyright"; +import FingerprintService from "../../services/fingerprintService/FingerprintService"; +import FingerprintAuthServices from "../../services/FingerprintAuthServices"; const dashboardTheme = createTheme({ palette: { @@ -62,6 +64,30 @@ export default function CheckInOutContainer() { fetchResource(); }, [resourceId]); + const authenticateFp = async () => { + const fingerprintData = await FingerprintService.getFingerprint(); + // const authenticationData = fingerprintAuthServices.fpAuthenticate(fingerprintData); + + // TODO: Display the result + }; + + const [sendingRequests, setSendingRequests] = useState(true); + useEffect(() => { + let intervalId: NodeJS.Timeout | null = null; + + if (sendingRequests) { + intervalId = setInterval(authenticateFp, 100); + } else { + clearInterval(intervalId); + } + + return () => { + if (intervalId) { + clearInterval(intervalId); + } + }; + }, [sendingRequests]); + return ( @@ -71,7 +97,12 @@ export default function CheckInOutContainer() { - {resource && } + {resource && ( + + )} {!resource && ( Resource not found. )} diff --git a/src/pages/check-in-out/FingerprintUI.tsx b/src/pages/check-in-out/FingerprintUI.tsx index 05724da..7083da8 100644 --- a/src/pages/check-in-out/FingerprintUI.tsx +++ b/src/pages/check-in-out/FingerprintUI.tsx @@ -5,7 +5,7 @@ import FingerprintImg from "public/assets/images/fp_3.png"; import "./fingerprint.css"; export default function FingerprintUi(props: any) { - const { resourceName } = props; + const { resourceName, requests } = props; const navigate = useNavigate(); const isStudent = true; @@ -43,6 +43,7 @@ export default function FingerprintUi(props: any) { variant="contained" color="error" onClick={() => { + requests(false); navigate("/viewresources"); }} > diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts new file mode 100644 index 0000000..8517d5e --- /dev/null +++ b/src/services/FingerprintAuthServices.ts @@ -0,0 +1,19 @@ +import axios from "src/services/HttpServices"; + +const fpAuthenticate = async (fingerprintData: any) => { + const data = { + status: "IN-USE", + fingerprint: fingerprintData, + }; + + try { + const response = await axios.post("/", data); + return response; + } catch (error) { + return error; + } +}; + +export default { + fpAuthenticate, +}; diff --git a/src/services/fingerprintService/FingerprintService.ts b/src/services/fingerprintService/FingerprintService.ts new file mode 100644 index 0000000..7410fd0 --- /dev/null +++ b/src/services/fingerprintService/FingerprintService.ts @@ -0,0 +1,26 @@ +import Axios from "axios"; + +export const baseURL = import.meta.env.REACT_APP_FINGERPRINT_SERVICE_URL; +Axios.defaults.withCredentials = false; +const axiosInstance = Axios.create({ + withCredentials: false, + baseURL: baseURL, +}); + +const getFingerprint = async () => { + const data = { + deviceSubId: "3", + }; + + try { + console.log(baseURL); + const response = await axiosInstance.post("/", data); + return response; + } catch (error) { + console.log(error); + } +}; + +export default { + getFingerprint, +}; From 3191d687d5a744cd782287b86ea4b878705a5b01 Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Wed, 9 Aug 2023 17:41:20 +0530 Subject: [PATCH 05/17] Update backend API call for fingerprint authentication --- src/pages/check-in-out/CheckInOutContainer.tsx | 12 ++++++++++-- src/services/FingerprintAuthServices.ts | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index f590c9a..a4bd00b 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -65,8 +65,16 @@ export default function CheckInOutContainer() { }, [resourceId]); const authenticateFp = async () => { + const id = parseInt(resourceId); + if (isNaN(id)) { + return; + } + const fingerprintData = await FingerprintService.getFingerprint(); - // const authenticationData = fingerprintAuthServices.fpAuthenticate(fingerprintData); + const authenticationData = FingerprintAuthServices.fpAuthenticate( + id, + fingerprintData + ); // TODO: Display the result }; @@ -75,7 +83,7 @@ export default function CheckInOutContainer() { useEffect(() => { let intervalId: NodeJS.Timeout | null = null; - if (sendingRequests) { + if (sendingRequests && resource) { intervalId = setInterval(authenticateFp, 100); } else { clearInterval(intervalId); diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index 8517d5e..d54becf 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -1,13 +1,13 @@ import axios from "src/services/HttpServices"; -const fpAuthenticate = async (fingerprintData: any) => { +const fpAuthenticate = async (resourceId: number, fingerprintData: any) => { const data = { - status: "IN-USE", + resourceId, fingerprint: fingerprintData, }; try { - const response = await axios.post("/", data); + const response = await axios.patch("/bookings", data); return response; } catch (error) { return error; From 0ceaec8220d96019050e73ebce7a1b2082f822d8 Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Thu, 10 Aug 2023 12:56:26 +0530 Subject: [PATCH 06/17] Add token to fingerprint authentication service request --- src/pages/check-in-out/CheckInOutContainer.tsx | 3 ++- src/services/FingerprintAuthServices.ts | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index a4bd00b..01dc871 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -73,7 +73,8 @@ export default function CheckInOutContainer() { const fingerprintData = await FingerprintService.getFingerprint(); const authenticationData = FingerprintAuthServices.fpAuthenticate( id, - fingerprintData + fingerprintData, + user.token ); // TODO: Display the result diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index d54becf..dd582cd 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -1,12 +1,17 @@ import axios from "src/services/HttpServices"; -const fpAuthenticate = async (resourceId: number, fingerprintData: any) => { +const fpAuthenticate = async ( + resourceId: number, + fingerprintData: any, + token: string +) => { const data = { resourceId, fingerprint: fingerprintData, }; try { + axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; const response = await axios.patch("/bookings", data); return response; } catch (error) { From f174c7c0133e49326db6712cfce5f2b065e1a3f0 Mon Sep 17 00:00:00 2001 From: Sasitha Kumarasinghe Date: Thu, 10 Aug 2023 15:20:52 +0530 Subject: [PATCH 07/17] Updates to '/resources/{id}/check-in-out' route - Fixed issue where requests are not sending when the resource is changed. - Added functionality to start/stop sending requests. - Some UI updates. --- .../check-in-out/CheckInOutContainer.tsx | 30 ++++++++++++++----- src/pages/check-in-out/FingerprintUI.tsx | 21 ++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index 01dc871..2d155ab 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -71,31 +71,44 @@ export default function CheckInOutContainer() { } const fingerprintData = await FingerprintService.getFingerprint(); - const authenticationData = FingerprintAuthServices.fpAuthenticate( - id, - fingerprintData, - user.token - ); + + const fpRead = false; // TODO: Check whether fingerprint has been read + if (fpRead) { + const authenticationData = FingerprintAuthServices.fpAuthenticate( + id, + fingerprintData, + user.token + ); + } // TODO: Display the result }; - const [sendingRequests, setSendingRequests] = useState(true); + const [sendingRequests, setSendingRequests] = useState(false); + const [fpImageClasses, setFpImageClasses] = useState(""); + useEffect(() => { let intervalId: NodeJS.Timeout | null = null; if (sendingRequests && resource) { + setFpImageClasses("fingerprint-animation"); intervalId = setInterval(authenticateFp, 100); } else { + setFpImageClasses(""); clearInterval(intervalId); } return () => { if (intervalId) { + setFpImageClasses(""); clearInterval(intervalId); } }; - }, [sendingRequests]); + }, [sendingRequests, resource]); + + const toggleRequest = () => { + setSendingRequests(!sendingRequests); + }; return ( @@ -109,7 +122,8 @@ export default function CheckInOutContainer() { {resource && ( )} {!resource && ( diff --git a/src/pages/check-in-out/FingerprintUI.tsx b/src/pages/check-in-out/FingerprintUI.tsx index 7083da8..7d8f18e 100644 --- a/src/pages/check-in-out/FingerprintUI.tsx +++ b/src/pages/check-in-out/FingerprintUI.tsx @@ -1,12 +1,10 @@ -import React, { useEffect } from "react"; -import { useNavigate } from "react-router-dom"; +import React from "react"; import { Box, Button, Typography, useTheme } from "@mui/material"; import FingerprintImg from "public/assets/images/fp_3.png"; import "./fingerprint.css"; export default function FingerprintUi(props: any) { - const { resourceName, requests } = props; - const navigate = useNavigate(); + const { resourceName, fpClass, toggleRequest } = props; const isStudent = true; const theme = useTheme(); @@ -30,24 +28,23 @@ export default function FingerprintUi(props: any) { variant="h3" sx={{ ...headingStyle, color: "#0170D6" } as React.CSSProperties} > - Please place your finger on the scanner + {fpClass + ? "Please place your finger on the scanner" + : "Please click Start Attending button to start"} fingerprint image {isStudent && ( )} From 925f4a6482083224280af9f2107fec0012d0d5b7 Mon Sep 17 00:00:00 2001 From: Nethum Lamahewage Date: Thu, 10 Aug 2023 20:50:55 +0530 Subject: [PATCH 08/17] Request fingerprint through socket --- package-lock.json | 84 ++++++++++++++++- package.json | 1 + src/helpers/socket.ts | 5 + .../check-in-out/CheckInOutContainer.tsx | 94 +++++++------------ src/pages/check-in-out/FingerprintUI.tsx | 21 ++--- src/services/FingerprintAuthServices.ts | 2 +- 6 files changed, 131 insertions(+), 76 deletions(-) create mode 100644 src/helpers/socket.ts diff --git a/package-lock.json b/package-lock.json index 1981129..3a4c01d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "react-toastify": "^9.1.3", "recharts": "^2.7.2", "redux-persist": "^6.0.0", + "socket.io-client": "^4.7.2", "vite-plugin-env-compatible": "^1.1.1", "web-vitals": "^2.1.4", "yup": "^1.2.0" @@ -1441,6 +1442,11 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-7.0.0.tgz", @@ -2415,7 +2421,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2531,6 +2536,26 @@ "integrity": "sha512-8tgdX0Odl24LtmLwxotpJCVjIndN559AvaOtd67u+2mo+IDsgsTF580NB+uuDCqsHw8yFg53l5+imFV9Fw3cbA==", "dev": true }, + "node_modules/engine.io-client": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", + "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -3471,8 +3496,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.6", @@ -4067,6 +4091,32 @@ "node": ">=8" } }, + "node_modules/socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4446,6 +4496,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index d843459..df5b9f7 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "react-toastify": "^9.1.3", "recharts": "^2.7.2", "redux-persist": "^6.0.0", + "socket.io-client": "^4.7.2", "vite-plugin-env-compatible": "^1.1.1", "web-vitals": "^2.1.4", "yup": "^1.2.0" diff --git a/src/helpers/socket.ts b/src/helpers/socket.ts new file mode 100644 index 0000000..1ccfab2 --- /dev/null +++ b/src/helpers/socket.ts @@ -0,0 +1,5 @@ +import { io } from "socket.io-client"; + +const URL = import.meta.env.REACT_APP_SOCKET_HOST; + +export const socket = io(URL); diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index 2d155ab..2c29f5b 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -1,19 +1,19 @@ -import React, { useEffect, useState } from "react"; -import { useNavigate, useParams } from "react-router-dom"; -import { Resource, User } from "../../types"; -import ResourcesServices from "../../services/ResourcesServices"; -import { useSelector } from "react-redux"; -import { AppState } from "../../redux/reducer"; -import FingerprintUi from "./FingerprintUI"; +import { Box, Container, Toolbar, Typography } from "@mui/material"; import CssBaseline from "@mui/material/CssBaseline"; -import AppbarComponent from "../../components/AppbarComponent"; -import DrawerComponent from "../../components/DrawerComponent"; -import { Box, Container, Paper, Toolbar, Typography } from "@mui/material"; -import ThemeProvider from "@mui/material/styles/ThemeProvider"; import { createTheme } from "@mui/material/styles"; +import ThemeProvider from "@mui/material/styles/ThemeProvider"; +import { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { useNavigate, useParams } from "react-router-dom"; +import AppbarComponent from "../../components/AppbarComponent"; import Copyright from "../../components/Copyright"; -import FingerprintService from "../../services/fingerprintService/FingerprintService"; +import DrawerComponent from "../../components/DrawerComponent"; +import { socket } from "../../helpers/socket"; +import { AppState } from "../../redux/reducer"; import FingerprintAuthServices from "../../services/FingerprintAuthServices"; +import ResourcesServices from "../../services/ResourcesServices"; +import { Resource, User } from "../../types"; +import FingerprintUi from "./FingerprintUI"; const dashboardTheme = createTheme({ palette: { @@ -64,51 +64,29 @@ export default function CheckInOutContainer() { fetchResource(); }, [resourceId]); - const authenticateFp = async () => { - const id = parseInt(resourceId); - if (isNaN(id)) { - return; - } - - const fingerprintData = await FingerprintService.getFingerprint(); - - const fpRead = false; // TODO: Check whether fingerprint has been read - if (fpRead) { - const authenticationData = FingerprintAuthServices.fpAuthenticate( - id, - fingerprintData, - user.token - ); - } - - // TODO: Display the result - }; - - const [sendingRequests, setSendingRequests] = useState(false); - const [fpImageClasses, setFpImageClasses] = useState(""); - useEffect(() => { - let intervalId: NodeJS.Timeout | null = null; - - if (sendingRequests && resource) { - setFpImageClasses("fingerprint-animation"); - intervalId = setInterval(authenticateFp, 100); - } else { - setFpImageClasses(""); - clearInterval(intervalId); - } - - return () => { - if (intervalId) { - setFpImageClasses(""); - clearInterval(intervalId); - } - }; - }, [sendingRequests, resource]); - - const toggleRequest = () => { - setSendingRequests(!sendingRequests); - }; + if (resource === null) return; + socket.on("fingerprintData", async (fingerprintData) => { + const authenticationData: any = + await FingerprintAuthServices.fpAuthenticate( + parseInt(resource.id), + fingerprintData, + user.token + ); + console.log(authenticationData); + const { username } = authenticationData.data; + console.log(username); + setScannerActive(false); + // TODO: Display the result + }); + }, [resource]); + + const [scannerActive, setScannerActive] = useState(false); + + function requestFingerprint() { + setScannerActive(true); + socket.emit("fingerprint", 3); + } return ( @@ -122,8 +100,8 @@ export default function CheckInOutContainer() { {resource && ( )} {!resource && ( diff --git a/src/pages/check-in-out/FingerprintUI.tsx b/src/pages/check-in-out/FingerprintUI.tsx index 7d8f18e..7481422 100644 --- a/src/pages/check-in-out/FingerprintUI.tsx +++ b/src/pages/check-in-out/FingerprintUI.tsx @@ -1,10 +1,10 @@ -import React from "react"; import { Box, Button, Typography, useTheme } from "@mui/material"; import FingerprintImg from "public/assets/images/fp_3.png"; +import React from "react"; import "./fingerprint.css"; export default function FingerprintUi(props: any) { - const { resourceName, fpClass, toggleRequest } = props; + const { resourceName, scannerActive, requestFingerprint } = props; const isStudent = true; const theme = useTheme(); @@ -24,27 +24,20 @@ export default function FingerprintUi(props: any) { > {resourceName} - - {fpClass - ? "Please place your finger on the scanner" - : "Please click Start Attending button to start"} - fingerprint image {isStudent && ( )} diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index dd582cd..4976f57 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -13,7 +13,7 @@ const fpAuthenticate = async ( try { axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; const response = await axios.patch("/bookings", data); - return response; + return response.data; } catch (error) { return error; } From 5f1ae0ee696d6b4e7b09e6e996cbfba4953b5cce Mon Sep 17 00:00:00 2001 From: Nethum Lamahewage Date: Thu, 10 Aug 2023 20:51:16 +0530 Subject: [PATCH 09/17] Add environment variables to `vite-env.d.ts` --- src/vite-env.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index c45b214..be5e8c2 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,10 +1,10 @@ /// interface ImportMetaEnv { - readonly VITE_BACKEND_URL: string - // more env variables... + readonly REACT_APP_BACKEND_URL: string; + readonly REACT_APP_SOCKET_HOST: string; } interface ImportMeta { - readonly env: ImportMetaEnv -} \ No newline at end of file + readonly env: ImportMetaEnv; +} From db031485218aa63b38ceae904a9f0a140476d3ca Mon Sep 17 00:00:00 2001 From: Yasith-Heshan <81988554+Yasith-Heshan@users.noreply.github.com> Date: Sat, 12 Aug 2023 20:30:59 +0530 Subject: [PATCH 10/17] Fingerprint results dialog --- public/assets/images/fingerprint_failed.jpg | Bin 0 -> 6452 bytes public/assets/images/fingerprint_success.jpg | Bin 0 -> 6659 bytes src/components/FingerPrintResults.tsx | 126 ++++++++++++++++++ .../check-in-out/CheckInOutContainer.tsx | 57 +++++++- src/services/FingerprintAuthServices.ts | 3 +- src/types.ts | 12 +- 6 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 public/assets/images/fingerprint_failed.jpg create mode 100644 public/assets/images/fingerprint_success.jpg create mode 100644 src/components/FingerPrintResults.tsx diff --git a/public/assets/images/fingerprint_failed.jpg b/public/assets/images/fingerprint_failed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bff187dd3aba3b01a819dd5c9403397fb039a771 GIT binary patch literal 6452 zcmb7|bx;&u)c1E;TDlP=mu{p}8kXE81(XtyEE2}CHBpj2$4HeR8G)a)s?#WYWqVcubl>tMUorrAS!!;%LHMj+s!=l>_g zgCY?0(C33yh#Y_g#KHk#VgIlCe?>fGAjig`V1-hODB-f-uf!VDh2YR#J3y91Xo~v%*_w5&3kFxMHbl|0_B{bRA=Vgn zavIvsuS9gQXQDDsG?pZ(g10gZML~{3h?H3VzR&WU{URac-(c2umZscgbsCV?@|*PY zjATIoGA}+!1WL?u#rA|x%k(fK-loZzpZfV<{I=LU&bC>{U+ug=et@sCgOA z_>6ISPpD#yJQ}@k5}3JEjWq)6O`quGjwtnyETLF})!wEbNd5`37b6v@L(Un`fD6_NxTzi_7@Z7T*k&K>e0K}UPzvVp~ULk)JFYwcC};z*PO6RQ43#ROvo>^w}@*A`s_uI>C+$~gvs?W`RW1N_XoLnJ?@ zA5Wy2-8%e}SKzezOiPty@@r5~=la?1h_Js|qR=$%^u4`}rn(nSp`Ah&1C!d`ISV|ELWAED~;C z>+t&vyluhg!%U1P>0SAEZR=b0zh%s0PitQ4I@TbTdr+(9&$L)e0B)xftg|AS{Hy(b zTL-SIL)#KG7xm#8G1=yMwbYM;y|Yh{CWidKi_HTnfb}DgZ4F#7NhO?_FIbK{L|_zr5<=F( z`AgZTHX$SErPgnuv%xgzQgzm6x1wCJdCz%Bm_X6SDkLg_>C4Nlb8Y3@&ZtVM+6c}w z!17x~pjOQPic6Om8``8}mth{s@F4>&~~7IyPg{nq(jIn#YFkmaGITVXmb>dT`_yrdsYG z1D?S7GxG6c67Lxb&77Jt<{0k|548ORLN>@Kk9e1K6UCq3j+&?%tdmf3)FE$#2Zx&XGLeP3v-U74Zsw zcH3wNHUIOov1m!S)Y~s~{QFr^I8;ejgw@^W@$t>rPNO6wV%YXJv@42kHupy3N(27G zCT^a|z6|nC@esD~r2G!*H+A@5M~GD9aXiAH|Z z=2W~xF0F0%Z&YOU{5j-(g(&^DZd&7;R`OhTF-A*!vG8%bVkXJ&?Hx`8kfDQJYrfqd zUC}FP6;m-E)wk!a%#o!{JF#_kjOg*FJmyZL%^uun?4c&IsC18D(g9Cqv5mIYl-Vfp zH?v~V)02cI3-*rsy;5xRJnn4sOAx@a(Rjiia?SP&Sn?MJH&ZSkXTnW&vWr~Hud1mW z-vC?YIKSr6iuQztd9!D&+8fs&tF?9>v-RGzOYnjsrzKtDJ5a>l%pcdXR0? z{gHDWeEklsMbmW;aOL*;%K&r*Zml-WMP%>12-KQM&Eu4@r&|_=cI9a)94FMdQhMt) z!asMQz(}pfu81Z|&JrkBp~lx7SH7C-#QuKlyA~*BX^=-0^)#z(nU+_7kX1Qw_*v`#M* zfm7zJ_hjA~b6l1Ejx*j1MCc&rUm6a%_&_T&T48lKKF<}A-Z^00Ie4+ADK5v<-U&e? zV|8?MzIpD#J;0Rz&_u;)k)$|fTQb&f920%!(3QH*7nj>f+^L|kSNO*A5w)G;KBn+w z53}Thr~-?kh+t;f8jVEwg4cJ9Vp5|~FiUd7};??8@<`c){?|u)DxyQg2Tbh-gnab=;N;!Y` z1e~FU^@uVdn9QE=)dkkwKyG(FEr|<_yfC{S5><4t(gaeU+x=@HEryfd3r$YH0sb-V zY4tZYVqQJEHEvP8C(m&zXy?^j!Wi~YEkWK;6VhB0y!sf5^QPSS83AuQ;6@E1_x<64 z5~Z)=l?QY|7z zpEuL8HRxp6kesL+ERm+3XUQr;!0Vg#UXo&0zV~nJ<=jr^KY{ry$tQDXjW*8NogLwx z%5I6U5~fs^!>n~C$)k0AT6C&f(ie2;{`2OPE6h)LK8)}zxn{xa)x?-sam9t2^rg<} zqg5sa%C|oU-UTJy10Km5yC^P-b7j0Rej~|;lCaQ5M@`0vff|nw!*K>BPP8~VO^yIO z)=O%%ceBdFfz}-BC3jIB>hcDBU1G+cQ?eZNG8_&G-;0uqoS-`l3=R71yZ3ynLtFc# zpX)~ae$Q4tVc9;(qkueZlrB0Ua1Lnr;3S-)->!Z{7rv6+au0}IJ{nz>WmNA@4ImtQ z;lJbO2%~S!HpZcT1Wt(wXA~=CQ5|eAhpldu1N9>l)+)?*Huo6ac&YpRoFTl7*1{m<|R$9!BR*iBUB-6hoDc(rdQxwJ+|`sHqqE+ zcV>i%0qz5$Y9f9~3Z6I-e|metVX_tgEP`H}W8GR&efsjB-^*C!GOYr*en=ieq`2-r zMR}B!zJ6;!J*iIxt0?A<3F3}BMq+wycd0w@#B;`%VxmH`)s-3!n=9P<((Cs{tXCAw zye;JF_w&L?Bg(&Jk^mJU_)w z$61tS#pf6u-tbUzQUYp;XgOCMWofO{?{DBnmW!{JSv>?JfCs9 z^@-IVUZ$lgQflLt@G1JEzg>`1`b0H*a*s&NV%*tVm2rnh9GlNWjzJar_O%uiR`<-u z6R%Jt=IC2Vte;dpW)-&I&1p2d^Gh;)kJjyrywf8G=;P|fZ0-VNnbih$#NRJM|=rO(tDD@a5uZm<{SsmvVZ={pKq zz-qr5KsU|?-QGw|@_Z2GKN}lCN62z&MdT{Cm1w%T5IW5$4#@F6+-TBaeZqA6Z`wo? z`2(NJas^Q2YZd2MPk65H0VZCSa28&n(Pj;?b*irJSvE-2f)Mf^kQVOU(SxUd!gD(u zT!z}C*IjrkyywI_K$OXIl?sqZX=P21VuCz7WqSOKnKd%0I*6ZG9tGj7&!lQ47Y|F< zE1?d2-|$6JaXV67p@ULNmuDdWF6?WcE-juP`p=JGu5hO@fwnq6pzJC)d2+^&=S@DP zMHGBAI!3PWgh>2vLo3f~1kVwhh;x7g=ifOfLl2ZY$nqT7ad#2hgT&C!o@k}dx(V7p zp=N9$t`MyEn>`*Pp{JHwR<4Fl(9zKeu9gGIhLE;_>t=M=Rv$vJaV!fDR?&@e)!E4O z9BPsLf%InKSf`O~4vkaZ%XlPx_H?{5 z{(~T^HW3z9hG#kpsj%Wvf{&p0!>KhqS<72_y0^H-e!?J8=3WaWc$U%7>L(lRyO0`m zI{;7jNHS3?LFA-CT19e(%1nsr{4`+%0dK<)>4J^|r6vpELI%l2$q? z1V78pm)y7y1y`%TR&|g-ylOFO^-x!tpDQa?aSKDxm8V;p0p7~0$icl{iu*cQO>7@h zMVQ#Jnt%8X>z}AZEQ7HR2)B-o2M13J5LT!jD9>5ZFM=SszT9%l*owvM%yZ->_l1Eg zdijNHa{VV~1+#CTn^8>(dcIOrtqjDxk(Od&W!dquQEn3OQvr9WUkF8V&1ihCc4Evp z$rmcK7^4ggsk5|3FfaGkmWI}u6VmpB5B``NzTA?wpZx72vO;B#=2VXlRQAtcMYiDR zu*yqQ=gr463W6?FSeD`}9tE;;$686-`xjqRq&}6w+=eP7Tltdgw-|#f-$4szeC5)% z=%;yVHG=nf&`wlb{D;aA3$pP@j{(n%7;YYjtGg!jNuAITIbZGQMQ#_r5i1THd^xe# z^i#0d`+M`CsvN)Nq7?-q&6>fhMXWn`q|<*z-C?GcI#3Bk=H;p$#gW*b!D?e!-1|)N zU%qUP-5lkMrK@yfU)Qo1O5zk~b9NV=+?nf2wln@>!R|sUfA(&<&b^=Oweg>_dVao$q#+mHtHNzLkNjCQorhd^B4}%x9iA8nHL@4(aHC zRT-xG)f#?-4V?u(V`6v=opA@jOiGuGc6Po8{*#(gqeI%B*7fdZbaK=eJH2aU7uF8| zx&m#D_9Ej$vyDg>PeS?|U<*l(ZYG}#k%Wri^WAB3E2fsuaM^SbT4J6&9TvLxqy9vn zOYszn82rHSDcl${-lKA;9%PRqO?cO*R&Do*qVjz4u07E}AiFc}&(^QLC)?J*YtlMS zruwIXrWyVm`mbKlZ6;3-^_P&^(%MU6$GwZtnA9V;`_*BkBYyQ3u_ev-Ok*d(Y)h2$ zD7pA>BT4wMjZoX}V&Us%K|ji-ax6w{+VJ_sKS#4NR;qM{5;j)a<;W%FI+PUGM9S!8 z#iqVpMN3Q1vC$p5#}!{(%Ignmz7DRa*G5mCONSdB^AI+@FvI7Guu&Apv9y}}`W{^? zKs~lueY0NIeB5j}+c-I(NR=J2I;Ejn2{G^Z`>HZ1m~6PRp79=#FhLL>#m=J{Wtr74 zgGu@M>Tq+*%`F)(6;I+HW-tD-^o~LID$rexKf#%)3ZB7A2wL?PnUSmr2q*ag4mz|N zK^5aq-#XQA#e8p?7}&{tYc#LH{aSsp zkEQ%qv>8uo=Hk^vX`=D{PzGBtnERtxbEEL8-cnYRtuX1edT(zRReJ^KjuCn=`l|9W zuKQ6;gIi`CDAhQ;*_HWMcrCm{cXaT(m#^X-v`q=7}(J z-lU%7Uz{3w3|JU=(N`7wLTNHq^{?eB5<)*Zkl0VN)7!)R1&5iknp&|D-;mtqTZeH6 zrksn|8&xt3L@{9#t_|7tmZ}E~779xw6*jtMe+5E{*RyN$FEC+2vVptEKBZ^ywqwQ_d z{w&m1(@!pZX)RN_NS$4$Zu9$c6|Cux@R5n;tknT`#k$?WuAXdPmaV!vhJK6vQ{Roe z2^@KCeWHo_WRFT%>DaxC>1DPg?$3+!Clavmu=zTW)~BNbvKG|CKWDVU#gpg-;NHXo zU6S#6|4tDl3+6pqW55zr>c#(2;sTkg$sFab*t;>(`S?ghN4O*%0cz*~P$I{6&j-fD z2MYBsU1Pu@jpPP$g}%?+L`1L|+KX>dXQ1tq!JrSVS}-bDgOb*%f(BE*(U^oC+5CxF z`)K40h0$hsa-ojxU;(Y@n}h4|)(h~RiXrKQBh6R4t>!V#{ot#-Lei*%mhC#BJ|% zG3liBIagPkduf-I?Bh9>hpI{g^v(O&GNHlL0MEEfAD{C}>qa{wV`evo>%cZhg5OSr zxI~)$f$8WvMnp83QE$Nux7W2TvU?45swW^>lK90*Q^vT9-68xahibGUi@DT}Egy}7 zJ(11-u>20vcP;>$4v6vu?&KC1>Qu#`#^6%$k?f0ds@Bx{aHdga7Jgj0wnE>iTsWeA z{-*(q=7T*;;sE)`pJ1y33IkNlc(BgZPPcJRjT?^dQXO=~UE|H_7~>}tr=9alfBAfe zvR8ULLOS;KQx;09(NZO!*1c=THJf1TjSv{W5aw5vdwz$0CF5xE(-IoE)R-kIRlS+w z_W@)~rI`~0GfMAtFNDjgf2)IN&=|CK1dh7bJ;sc_#w|U}Ndsj!nWU0Uh@0Ztb&|<5 zLGt`x793A0&|?;=E$CNpD7g|RUNd$jcSf|`JmJH)R;e@qgdL|NhdsD({zk75{OI^w zzi|&htP%`wua^Cj!tC#CfAp>X7QrK4rkCQ~?N6+jV5zOYFgtUQfh5YD+ENY^q*^zC zWY`^q+KsjEc>dYAu6JcfY(HMytP^nOUU7!X98ZKruY==H{@Pf?xknczURz;ZC~UMOR#qlPW|Lz1D+&{HJ}ZRrug)O*{Brg T0t#y#{JM4CclWUYc)#>N5=|bD literal 0 HcmV?d00001 diff --git a/public/assets/images/fingerprint_success.jpg b/public/assets/images/fingerprint_success.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1074c56f4fa635e99231f7ba8ad56b1b6a26481c GIT binary patch literal 6659 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 literal 0 HcmV?d00001 diff --git a/src/components/FingerPrintResults.tsx b/src/components/FingerPrintResults.tsx new file mode 100644 index 0000000..3328be5 --- /dev/null +++ b/src/components/FingerPrintResults.tsx @@ -0,0 +1,126 @@ +import * as React from 'react'; +import {styled} from '@mui/material/styles'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import IconButton from '@mui/material/IconButton'; +import CloseIcon from '@mui/icons-material/Close'; +import Typography from '@mui/material/Typography'; +import Grid from "@mui/material/Grid"; +import {FingerPrintDetails, SetDialogOpenFunction} from "../types"; + +const BootstrapDialog = styled(Dialog)(({theme}) => ({ + '& .MuiDialogContent-root': { + padding: theme.spacing(2), + }, + '& .MuiDialogActions-root': { + padding: theme.spacing(1), + }, +})); + +export interface DialogTitleProps { + id: string; + children?: React.ReactNode; + onClose: () => void; +} + +function BootstrapDialogTitle(props: DialogTitleProps) { + const {children, onClose, ...other} = props; + + return ( + + {children} + {onClose ? ( + theme.palette.grey[500], + }} + > + + + ) : null} + + ); +} + + +export const FingerPrintResults = ({ + open, + setOpen, + access, + booking + }: { open: boolean, setOpen: SetDialogOpenFunction, access: boolean, booking: FingerPrintDetails }) => { + + + const handleClose = () => { + setOpen(false); + }; + + return ( +
+ + + + + + { + access ? ( + <> + + {'fingerprint + + + + Successfully Recognized + + + + {booking.username} + + + + + + {booking.timeslot} + + + + + + + Count: {booking.count} + + + + + ) : ( + <> + + {'fingerprint + + + No Booking for this Timeslot + + + ) + } + + + + +
+ ); +} \ No newline at end of file diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index 2c29f5b..1819d7a 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -12,8 +12,12 @@ import { socket } from "../../helpers/socket"; import { AppState } from "../../redux/reducer"; import FingerprintAuthServices from "../../services/FingerprintAuthServices"; import ResourcesServices from "../../services/ResourcesServices"; -import { Resource, User } from "../../types"; +import {FingerPrintDetails, Resource, User} from "../../types"; import FingerprintUi from "./FingerprintUI"; +import {FingerPrintResults} from "../../components/FingerPrintResults"; +import dayjs from "dayjs"; +import localizedFormat from 'dayjs/plugin/localizedFormat' + const dashboardTheme = createTheme({ palette: { @@ -32,6 +36,10 @@ export default function CheckInOutContainer() { const { resourceId } = useParams(); const navigate = useNavigate(); + const [dialogOpen, setDialogOpen] = useState(false); + const [access, setAccess] = useState(false); + const [booking, setBooking] = useState(null); + useEffect(() => { if (!user) { navigate("/"); @@ -73,11 +81,34 @@ export default function CheckInOutContainer() { fingerprintData, user.token ); - console.log(authenticationData); - const { username } = authenticationData.data; - console.log(username); - setScannerActive(false); - // TODO: Display the result + if(authenticationData){ + const { username,startTime,endTime,count } = authenticationData.data; + + dayjs.extend(localizedFormat); + const booking:FingerPrintDetails = { + username, + count, + timeslot:dayjs(startTime).format('L LT')+'-'+dayjs(endTime).format('LT') + } + setBooking(booking); + + setAccess(true); + setScannerActive(false); + setDialogOpen(true); + }else { + setAccess(false); + setDialogOpen(true); + } + + setTimeout( + ()=>{ + setBooking(null); + setAccess(false) + setDialogOpen(false) + },5000 + ) + + }); }, [resource]); @@ -88,6 +119,9 @@ export default function CheckInOutContainer() { socket.emit("fingerprint", 3); } + + + return ( @@ -98,15 +132,26 @@ export default function CheckInOutContainer() { {resource && ( + <> + + + + )} {!resource && ( Resource not found. )} +
diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index 4976f57..9e4eae2 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -15,7 +15,8 @@ const fpAuthenticate = async ( const response = await axios.patch("/bookings", data); return response.data; } catch (error) { - return error; + console.error(error); + return null; } }; diff --git a/src/types.ts b/src/types.ts index 8c264f1..f5c0561 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,5 @@ +import * as React from "react"; + export type Resource = { id: string; name: string; @@ -45,4 +47,12 @@ export type BookingForm = { export const ADMIN = 'ADMIN'; export const RESOURCE_MANAGER = 'RESOURCE_MANAGER'; -export const RESOURCE_USER = 'RESOURCE_USER'; \ No newline at end of file +export const RESOURCE_USER = 'RESOURCE_USER'; + +export type SetDialogOpenFunction = React.Dispatch>; +export type FingerPrintDetails = { + username: string, + count: number, + timeslot: string, + +} \ No newline at end of file From 6268ea00fbe89dd40e04c8015cdcb2c103610dce Mon Sep 17 00:00:00 2001 From: Yasith-Heshan <81988554+Yasith-Heshan@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:47:02 +0530 Subject: [PATCH 11/17] Fix issues mentioned in review --- src/components/FingerPrintResults.tsx | 17 ++--- .../check-in-out/CheckInOutContainer.tsx | 62 +++++++++---------- .../view-resources/ViewResourcesContainer.tsx | 35 +++++++---- src/services/FingerprintAuthServices.ts | 1 - 4 files changed, 64 insertions(+), 51 deletions(-) diff --git a/src/components/FingerPrintResults.tsx b/src/components/FingerPrintResults.tsx index 3328be5..afa40af 100644 --- a/src/components/FingerPrintResults.tsx +++ b/src/components/FingerPrintResults.tsx @@ -8,6 +8,8 @@ import CloseIcon from '@mui/icons-material/Close'; import Typography from '@mui/material/Typography'; import Grid from "@mui/material/Grid"; import {FingerPrintDetails, SetDialogOpenFunction} from "../types"; +import FingerPrintFailed from '../../public/assets/images/fingerprint_failed.jpg' +import FingerPrintSuccess from '../../public/assets/images/fingerprint_success.jpg' const BootstrapDialog = styled(Dialog)(({theme}) => ({ '& .MuiDialogContent-root': { @@ -77,19 +79,20 @@ export const FingerPrintResults = ({ <> {'fingerprint - - - Successfully Recognized - + + + Successfully Recognized + {booking.username} - + {booking.timeslot} @@ -108,7 +111,7 @@ export const FingerPrintResults = ({ <> {'fingerprint diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index 1819d7a..90a8c35 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -1,15 +1,15 @@ -import { Box, Container, Toolbar, Typography } from "@mui/material"; +import {Box, Container, Toolbar, Typography} from "@mui/material"; import CssBaseline from "@mui/material/CssBaseline"; -import { createTheme } from "@mui/material/styles"; +import {createTheme} from "@mui/material/styles"; import ThemeProvider from "@mui/material/styles/ThemeProvider"; -import { useEffect, useState } from "react"; -import { useSelector } from "react-redux"; -import { useNavigate, useParams } from "react-router-dom"; +import {useEffect, useState} from "react"; +import {useSelector} from "react-redux"; +import {useNavigate, useParams} from "react-router-dom"; import AppbarComponent from "../../components/AppbarComponent"; import Copyright from "../../components/Copyright"; import DrawerComponent from "../../components/DrawerComponent"; -import { socket } from "../../helpers/socket"; -import { AppState } from "../../redux/reducer"; +import {socket} from "../../helpers/socket"; +import {AppState} from "../../redux/reducer"; import FingerprintAuthServices from "../../services/FingerprintAuthServices"; import ResourcesServices from "../../services/ResourcesServices"; import {FingerPrintDetails, Resource, User} from "../../types"; @@ -33,12 +33,12 @@ const dashboardTheme = createTheme({ export default function CheckInOutContainer() { const [resource, setResource] = useState(null); const user: User | null = useSelector((state: AppState) => state.user.user); - const { resourceId } = useParams(); + const {resourceId} = useParams(); const navigate = useNavigate(); const [dialogOpen, setDialogOpen] = useState(false); const [access, setAccess] = useState(false); - const [booking, setBooking] = useState(null); + const [booking, setBooking] = useState(null); useEffect(() => { if (!user) { @@ -81,31 +81,32 @@ export default function CheckInOutContainer() { fingerprintData, user.token ); - if(authenticationData){ - const { username,startTime,endTime,count } = authenticationData.data; + if (authenticationData) { + const {username, startTime, endTime, count} = authenticationData.data; dayjs.extend(localizedFormat); - const booking:FingerPrintDetails = { + const booking: FingerPrintDetails = { username, count, - timeslot:dayjs(startTime).format('L LT')+'-'+dayjs(endTime).format('LT') + timeslot: dayjs(startTime).format('L LT') + '-' + dayjs(endTime).format('LT') } setBooking(booking); setAccess(true); setScannerActive(false); setDialogOpen(true); - }else { + } else { setAccess(false); setDialogOpen(true); } setTimeout( - ()=>{ + () => { + setScannerActive(false); setBooking(null); setAccess(false) setDialogOpen(false) - },5000 + }, 5000 ) @@ -120,31 +121,28 @@ export default function CheckInOutContainer() { } - - return ( - - - - - - - + + + + + + + {resource && ( <> - + - )} @@ -153,7 +151,7 @@ export default function CheckInOutContainer() { )} - + diff --git a/src/pages/view-resources/ViewResourcesContainer.tsx b/src/pages/view-resources/ViewResourcesContainer.tsx index 88d3c5c..fa8fe85 100644 --- a/src/pages/view-resources/ViewResourcesContainer.tsx +++ b/src/pages/view-resources/ViewResourcesContainer.tsx @@ -20,6 +20,7 @@ import resourcesServices from "src/services/ResourcesServices"; import {Booking, Resource, User} from "../../types"; import {useSelector} from "react-redux"; import {AppState} from "../../redux/reducer"; +import Grid from "@mui/material/Grid"; const dashboardTheme = createTheme({ palette: { @@ -91,14 +92,14 @@ function ResourceCard({resource}: { resource: Resource }) { setExpanded(!expanded); }; - const handleEditStart = (e: any) => { + const handleEditStart = () => { setExpanded(false); setName(resource.name); setCount(resource.count) setEditStarted(true); }; - const handleUpdate = async (e: any) => { + const handleUpdate = async () => { if (!nameError && !countError) { await resourcesServices.updateResource(parseInt(resource.id), name, count,token); setEditStarted(false); @@ -189,14 +190,26 @@ function ResourceCard({resource}: { resource: Resource }) { > { !editStarted ? ( - + + + + + + + + + ) : ( diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index 9e4eae2..e13136c 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -15,7 +15,6 @@ const fpAuthenticate = async ( const response = await axios.patch("/bookings", data); return response.data; } catch (error) { - console.error(error); return null; } }; From e749d9ec9b3b89cb6797ef4d3625515352f37242 Mon Sep 17 00:00:00 2001 From: Yasith-Heshan <81988554+Yasith-Heshan@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:50:54 +0530 Subject: [PATCH 12/17] Fix 400 issue --- src/index.tsx | 4 ++-- .../check-in-out/CheckInOutContainer.tsx | 20 ++++++++++++------- src/services/FingerprintAuthServices.ts | 7 +++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 6bb2ae7..4f5dac1 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,7 +5,7 @@ import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + // - + // ); \ No newline at end of file diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index 90a8c35..fd2d63e 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -75,13 +75,15 @@ export default function CheckInOutContainer() { useEffect(() => { if (resource === null) return; socket.on("fingerprintData", async (fingerprintData) => { + try { + const authenticationData: any = await FingerprintAuthServices.fpAuthenticate( parseInt(resource.id), fingerprintData, user.token ); - if (authenticationData) { + const {username, startTime, endTime, count} = authenticationData.data; dayjs.extend(localizedFormat); @@ -95,19 +97,23 @@ export default function CheckInOutContainer() { setAccess(true); setScannerActive(false); setDialogOpen(true); - } else { + }catch (error:any){ setAccess(false); - setDialogOpen(true); + if(error.message==='400'){ + setDialogOpen(true); + }else{ + setDialogOpen(false); + } } setTimeout( () => { + setDialogOpen(false); setScannerActive(false); - setBooking(null); - setAccess(false) - setDialogOpen(false) + // setBooking(null); + // setAccess(false); }, 5000 - ) + ); }); diff --git a/src/services/FingerprintAuthServices.ts b/src/services/FingerprintAuthServices.ts index e13136c..f928f20 100644 --- a/src/services/FingerprintAuthServices.ts +++ b/src/services/FingerprintAuthServices.ts @@ -14,8 +14,11 @@ const fpAuthenticate = async ( axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; const response = await axios.patch("/bookings", data); return response.data; - } catch (error) { - return null; + } catch (error:any) { + if(error.response.status){ + throw new Error('400'); + } + throw new Error('unknown'); } }; From cd10a798d4c821425f678b4ac76a47a4f65924fb Mon Sep 17 00:00:00 2001 From: Yasith-Heshan <81988554+Yasith-Heshan@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:54:25 +0530 Subject: [PATCH 13/17] Fix Mosip --> CSE --- src/pages/view-resources/ViewResourcesContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/view-resources/ViewResourcesContainer.tsx b/src/pages/view-resources/ViewResourcesContainer.tsx index fa8fe85..4f91ff8 100644 --- a/src/pages/view-resources/ViewResourcesContainer.tsx +++ b/src/pages/view-resources/ViewResourcesContainer.tsx @@ -345,7 +345,7 @@ export default function ViewResourcesContainer() { - © {new Date().getFullYear()} MOSIP + © {new Date().getFullYear()} CSE From 210f79e69cb3c66378db9a96b05bee0117cd8ace Mon Sep 17 00:00:00 2001 From: Yasith-Heshan <81988554+Yasith-Heshan@users.noreply.github.com> Date: Sun, 13 Aug 2023 14:03:12 +0530 Subject: [PATCH 14/17] remove commented lines --- src/index.tsx | 4 ++-- src/pages/check-in-out/CheckInOutContainer.tsx | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 4f5dac1..6bb2ae7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,7 +5,7 @@ import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - // + - // + ); \ No newline at end of file diff --git a/src/pages/check-in-out/CheckInOutContainer.tsx b/src/pages/check-in-out/CheckInOutContainer.tsx index fd2d63e..dae8a46 100644 --- a/src/pages/check-in-out/CheckInOutContainer.tsx +++ b/src/pages/check-in-out/CheckInOutContainer.tsx @@ -110,8 +110,6 @@ export default function CheckInOutContainer() { () => { setDialogOpen(false); setScannerActive(false); - // setBooking(null); - // setAccess(false); }, 5000 ); From baf6d485c52d6ea7ab6572bda4536311209cd85e Mon Sep 17 00:00:00 2001 From: Nethum Lamahewage Date: Sun, 13 Aug 2023 17:56:31 +0530 Subject: [PATCH 15/17] Update .env file with defaults --- .env | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.env b/.env index 4a325bf..c430693 100644 --- a/.env +++ b/.env @@ -1,3 +1,2 @@ REACT_APP_BACKEND_URL='http://localhost:8080/' -REACT_APP_VITE_NAME = "Booking App" -REACT_APP_FINGERPRINT_SERVICE_URL="http://localhost:7291/reg/rcapture" +REACT_APP_SOCKET_HOST='http://localhost:4000' From efa387f3cec7274ce1b85e7136abd5c0c5ee13a0 Mon Sep 17 00:00:00 2001 From: Nethum Lamahewage Date: Sun, 13 Aug 2023 18:00:59 +0530 Subject: [PATCH 16/17] Remove unnecessary `FingerprintService` --- .../fingerprintService/FingerprintService.ts | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/services/fingerprintService/FingerprintService.ts diff --git a/src/services/fingerprintService/FingerprintService.ts b/src/services/fingerprintService/FingerprintService.ts deleted file mode 100644 index 7410fd0..0000000 --- a/src/services/fingerprintService/FingerprintService.ts +++ /dev/null @@ -1,26 +0,0 @@ -import Axios from "axios"; - -export const baseURL = import.meta.env.REACT_APP_FINGERPRINT_SERVICE_URL; -Axios.defaults.withCredentials = false; -const axiosInstance = Axios.create({ - withCredentials: false, - baseURL: baseURL, -}); - -const getFingerprint = async () => { - const data = { - deviceSubId: "3", - }; - - try { - console.log(baseURL); - const response = await axiosInstance.post("/", data); - return response; - } catch (error) { - console.log(error); - } -}; - -export default { - getFingerprint, -}; From 04aad585b0555f9e9c4c2d9bb478abbd050a7308 Mon Sep 17 00:00:00 2001 From: Nethum Lamahewage Date: Sun, 13 Aug 2023 18:15:00 +0530 Subject: [PATCH 17/17] Use `Link` from React Router instead of anchor tag --- src/pages/view-resources/ViewResourcesContainer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/view-resources/ViewResourcesContainer.tsx b/src/pages/view-resources/ViewResourcesContainer.tsx index 4f91ff8..8d943f6 100644 --- a/src/pages/view-resources/ViewResourcesContainer.tsx +++ b/src/pages/view-resources/ViewResourcesContainer.tsx @@ -196,7 +196,11 @@ function ResourceCard({resource}: { resource: Resource }) { disabled={role!='ADMIN'} variant="contained" sx={{backgroundColor: "primary", color: "white"}} - >Check-ins + > + + Check-ins + +