Skip to content

Commit

Permalink
Merge pull request #33 from Yasith-Heshan/Checkin_checkout
Browse files Browse the repository at this point in the history
Fingerprint results dialog
  • Loading branch information
Yasith-Heshan authored Aug 13, 2023
2 parents 5f1ae0e + 210f79e commit 5642126
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 42 deletions.
Binary file added public/assets/images/fingerprint_failed.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/images/fingerprint_success.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
129 changes: 129 additions & 0 deletions src/components/FingerPrintResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
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";
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': {
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 (
<DialogTitle sx={{m: 0, p: 2}} {...other}>
{children}
{onClose ? (
<IconButton
aria-label="close"
onClick={onClose}
sx={{
position: 'absolute',
right: 1,
top: 0,
color: (theme) => theme.palette.grey[500],
}}
>
<CloseIcon/>
</IconButton>
) : null}
</DialogTitle>
);
}


export const FingerPrintResults = ({
open,
setOpen,
access,
booking
}: { open: boolean, setOpen: SetDialogOpenFunction, access: boolean, booking: FingerPrintDetails }) => {


const handleClose = () => {
setOpen(false);
};

return (
<div>

<BootstrapDialog
onClose={handleClose}
aria-labelledby="customized-dialog-title"
open={open}
>
<BootstrapDialogTitle id="customized-dialog-title" onClose={handleClose}>
</BootstrapDialogTitle>
<DialogContent dividers>
{
access ? (
<>
<Grid container direction={'column'} alignItems={'center'} justifyContent={'center'}>
<img style={{borderRadius: '50%'}}
src={FingerPrintSuccess}
alt={'fingerprint success'}/>
</Grid>
<Grid mt={1} container direction={"column"} alignItems={'center'} justifyContent={'center'}>
<Typography variant={"h6"} color={'green'} fontWeight={'bold'}>
Successfully Recognized
</Typography>

<Typography variant={'h4'} fontWeight={"bold"}>
{booking.username}
</Typography>
</Grid>
<Grid mt={2} spacing={2} container direction={"row"} alignItems={'center'}
justifyContent={'space-between'}>
<Grid item>
<Typography variant={'body2'}>
{booking.timeslot}
</Typography>
</Grid>
<Grid item>
</Grid>
<Grid item>
<Typography variant={'body2'}>
Count: {booking.count}
</Typography>
</Grid>
</Grid>
</>
) : (
<>
<Grid container direction={'column'} alignItems={'center'} justifyContent={'center'}>
<img style={{borderRadius: '50%'}}
src={FingerPrintFailed}
alt={'fingerprint success'}/>
</Grid>
<Typography gutterBottom variant={"h6"} color={'red'} mt={1}>
No Booking for this Timeslot
</Typography>
</>
)
}


</DialogContent>
</BootstrapDialog>
</div>
);
}
101 changes: 74 additions & 27 deletions src/pages/check-in-out/CheckInOutContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
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 { 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: {
Expand All @@ -29,9 +33,13 @@ const dashboardTheme = createTheme({
export default function CheckInOutContainer() {
const [resource, setResource] = useState<Resource | null>(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<FingerPrintDetails | null>(null);

useEffect(() => {
if (!user) {
navigate("/");
Expand Down Expand Up @@ -67,17 +75,45 @@ 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
);
console.log(authenticationData);
const { username } = authenticationData.data;
console.log(username);
setScannerActive(false);
// TODO: Display the result

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);
}catch (error:any){
setAccess(false);
if(error.message==='400'){
setDialogOpen(true);
}else{
setDialogOpen(false);
}
}

setTimeout(
() => {
setDialogOpen(false);
setScannerActive(false);
}, 5000
);


});
}, [resource]);

Expand All @@ -88,27 +124,38 @@ export default function CheckInOutContainer() {
socket.emit("fingerprint", 3);
}


return (
<ThemeProvider theme={dashboardTheme}>
<CssBaseline />
<Box sx={{ display: "flex" }}>
<AppbarComponent open={open} toggleDrawer={toggleDrawer} />
<DrawerComponent open={open} toggleDrawer={toggleDrawer} />
<Container component="main" sx={{ mb: 4 }}>
<Toolbar />
<Box sx={{ my: 5 }}>
<CssBaseline/>
<Box sx={{display: "flex"}}>
<AppbarComponent open={open} toggleDrawer={toggleDrawer}/>
<DrawerComponent open={open} toggleDrawer={toggleDrawer}/>
<Container component="main" sx={{mb: 4}}>
<Toolbar/>
<Box sx={{my: 5}}>
{resource && (
<FingerprintUi
resourceName={resource.name}
scannerActive={scannerActive}
requestFingerprint={requestFingerprint}
/>
<>
<FingerprintUi
resourceName={resource.name}
scannerActive={scannerActive}
requestFingerprint={requestFingerprint}
/>
<FingerPrintResults
open={dialogOpen}
setOpen={setDialogOpen}
access={access}
booking={booking}
/>
</>

)}
{!resource && (
<Typography variant="h4">Resource not found.</Typography>
)}

</Box>
<Copyright />
<Copyright/>
</Container>
</Box>
</ThemeProvider>
Expand Down
37 changes: 25 additions & 12 deletions src/pages/view-resources/ViewResourcesContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -189,14 +190,26 @@ function ResourceCard({resource}: { resource: Resource }) {
>
{
!editStarted ? (
<Button
disabled={role!='ADMIN'}
variant="contained"
onClick={handleEditStart}
sx={{backgroundColor: "green", color: "white"}}
>
Edit Resource
</Button>
<Grid container direction={'row'} spacing={1} justifyContent={'end'}>
<Grid item>
<Button
disabled={role!='ADMIN'}
variant="contained"
sx={{backgroundColor: "primary", color: "white"}}
><a style={{textDecoration:"none", color:"white"}} href={`resources/${resource.id}/check-in-out`}>Check-ins</a></Button>
</Grid>
<Grid item>
<Button
disabled={role!='ADMIN'}
variant="contained"
onClick={handleEditStart}
sx={{backgroundColor: "green", color: "white"}}
>
Edit Resource
</Button>
</Grid>
</Grid>

) : (
<Button
variant="contained"
Expand All @@ -211,7 +224,7 @@ function ResourceCard({resource}: { resource: Resource }) {
{
editStarted && (
<Button onClick={
(e) => {
() => {
setEditStarted(false);
}
}>Cancel</Button>
Expand Down Expand Up @@ -332,7 +345,7 @@ export default function ViewResourcesContainer() {
</Box>
<Box sx={{mt: 4}}>
<Typography variant="body2" color="text.secondary" align="center">
© {new Date().getFullYear()} MOSIP
© {new Date().getFullYear()} CSE
</Typography>
</Box>
</Container>
Expand Down
7 changes: 5 additions & 2 deletions src/services/FingerprintAuthServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 error;
} catch (error:any) {
if(error.response.status){
throw new Error('400');
}
throw new Error('unknown');
}
};

Expand Down
12 changes: 11 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as React from "react";

export type Resource = {
id: string;
name: string;
Expand Down Expand Up @@ -45,4 +47,12 @@ export type BookingForm = {

export const ADMIN = 'ADMIN';
export const RESOURCE_MANAGER = 'RESOURCE_MANAGER';
export const RESOURCE_USER = 'RESOURCE_USER';
export const RESOURCE_USER = 'RESOURCE_USER';

export type SetDialogOpenFunction = React.Dispatch<React.SetStateAction<boolean>>;
export type FingerPrintDetails = {
username: string,
count: number,
timeslot: string,

}

0 comments on commit 5642126

Please sign in to comment.