import React, { useState, useEffect, useCallback } from "react";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Avatar from "@material-ui/core/Avatar";
import Container from "@material-ui/core/Container";
import cblogo from "./cblogo.PNG";
import Image from "./bg.png";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import { Paper, CardActionArea, CardMedia, Grid, TableContainer, Table, TableBody, TableHead, TableRow, TableCell, Button, CircularProgress } from "@material-ui/core";
import Clear from '@material-ui/icons/Clear';
import { DropzoneArea } from 'material-ui-dropzone';
const ColorButton = withStyles((theme) => ({
root: {
color: theme.palette.getContrastText(theme.palette.common.white),
backgroundColor: theme.palette.common.white,
'&:hover': {
backgroundColor: '#ffffff7a',
},
},
}))(Button);
const axios = require("axios").default;
const useStyles = makeStyles((theme) => ({
grow: {
flexGrow: 1,
},
clearButton: {
width: "-webkit-fill-available",
borderRadius: "15px",
padding: "15px 22px",
color: "#000000a6",
fontSize: "20px",
fontWeight: 900,
},
root: {
maxWidth: 345,
flexGrow: 1,
},
media: {
height: 400,
},
paper: {
padding: theme.spacing(2),
margin: 'auto',
maxWidth: 500,
},
gridContainer: {
justifycontent: "center",
padding: "4em 1em 0 1em",
},
mainContainer: {
backgroundImage: `url(${Image})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
backgroundSize: 'cover',
height: "93vh",
marginTop: "8px",
},
ImageCard: {
margin: "auto",
maxWidth: 400,
height: 500,
backgroundColor: 'transparent',
boxShadow: '0px 9px 70px 0px rgb(0 0 0 / 30%) !important',
borderRadius: '15px',
},
ImageCardEmpty: {
height: 'auto',
},
noImage: {
margin: "auto",
width: 400,
height: "400 !important",
},
input: {
display: 'none',
},
uploadIcon: {
background: 'white',
},
tableContainer: {
backgroundColor: 'transparent !important',
boxShadow: 'none !important',
},
table: {
backgroundColor: 'transparent !important',
},
tableHead: {
backgroundColor: 'transparent !important',
},
tableRow: {
backgroundColor: 'transparent !important',
},
tableCell: {
fontSize: '22px',
backgroundColor: 'transparent !important',
borderColor: 'transparent !important',
color: '#000000a6 !important',
fontWeight: 'bolder',
padding: '1px 24px 1px 16px',
},
tableCell1: {
fontSize: '14px',
backgroundColor: 'transparent !important',
borderColor: 'transparent !important',
color: '#000000a6 !important',
fontWeight: 'bolder',
padding: '1px 24px 1px 16px',
},
tableBody: {
backgroundColor: 'transparent !important',
},
text: {
color: 'white !important',
textAlign: 'center',
},
buttonGrid: {
maxWidth: "416px",
width: "100%",
},
detail: {
backgroundColor: 'white',
display: 'flex',
justifycontent: 'center',
flexDirection: 'column',
alignItems: 'center',
},
appbar: {
background: 'purple',
boxShadow: 'none',
color: 'white'
},
loader: {
color: '#be6a77 !important',
}
}));
export const ImageUpload = () => {
const classes = useStyles();
const [selectedFile, setSelectedFile] = useState();
const [preview, setPreview] = useState();
const [data, setData] = useState();
const [Image, setImage] = useState(false);
const [isLoading, setIsloading] = useState(false);
let confidence = 0;
const sendFile = useCallback(async () => {
if (Image) {
try {
let formData = new FormData();
formData.append("file", selectedFile);
console.log("Before API request");
let res = await axios({
method: "post",
url: process.env.REACT_APP_API_URL,
data: formData,
});
console.log("After API request");
if (res.status === 200) {
setData(res.data);
} else {
// Handle other status codes here
console.error(`API request failed with status code: ${res.status}`);
}
} catch (error) {
// Handle request error (e.g., network error, server not running)
console.error("API request failed:", error);
} finally {
setIsloading(false);
}
}
}, [Image, selectedFile, setData, setIsloading]);
const clearData = () => {
setData(null);
setImage(false);
setSelectedFile(null);
setPreview(null);
};
useEffect(() => {
if (!selectedFile) {
setPreview(undefined);
return;
}
const objectUrl = URL.createObjectURL(selectedFile);
setPreview(objectUrl);
}, [selectedFile]);
useEffect(() => {
if (!preview) {
return;
}
setIsloading(true);
sendFile();
}, [preview, sendFile]);
const onSelectFile = (files) => {
if (!files || files.length === 0) {
setSelectedFile(undefined);
setImage(false);
setData(undefined);
return;
}
setSelectedFile(files[0]);
setData(undefined);
setImage(true);
};
if (data) {
confidence = (parseFloat(data.confidence) * 100).toFixed(2);
}
return (
<React.Fragment>
<AppBar position="static" className={classes.appbar}>
<Toolbar>
<Typography className={classes.title} variant="h6" noWrap>
CSE499: Lukemia Blood cell Cancer Classification
</Typography>
<div className={classes.grow} />
<Avatar src={cblogo}></Avatar>
</Toolbar>
</AppBar>
<Container maxWidth={false} className={classes.mainContainer} disableGutters={true}>
<Grid
className={classes.gridContainer}
container
direction="row"
justifycontent="center"
alignItems="center"
spacing={2}
>
<Grid item xs={12}>
<Card className={`${classes.ImageCard} ${!Image ? classes.ImageCardEmpty : ''}`}>
{Image && <CardActionArea>
<CardMedia
className={classes.media}
component="img" // Change to "img"
src={preview} // Change to "src"
title="Contemplative Reptile"
/>
</CardActionArea>
}
{!Image && <CardContent className={classes.content}>
<DropzoneArea
acceptedFiles={['image/*']}
dropzoneText={"Drag-drop or Upload an image of Blood Cell to proceed"}
onChange={onSelectFile}
/>
</CardContent>}
{data && <CardContent className={classes.detail}>
<TableContainer component={Paper} className={classes.tableContainer}>
<Table className={classes.table} size="small" aria-label="simple table">
<TableHead className={classes.tableHead}>
<TableRow className={classes.tableRow}>
<TableCell className={classes.tableCell1}>Label:</TableCell>
<TableCell align="right" className={classes.tableCell1}>Confidence:</TableCell>
</TableRow>
</TableHead>
<TableBody className={classes.tableBody}>
<TableRow className={classes.tableRow}>
<TableCell component="th" scope="row" className={classes.tableCell}>
{data.class}
</TableCell>
<TableCell align="right" className={classes.tableCell}>{confidence}%</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</CardContent>}
{isLoading && <CardContent className={classes.detail}>
<CircularProgress color="secondary" className={classes.loader} />
<Typography className={classes.title} variant="h6" noWrap>
Matching... Please Wait...
</Typography>
</CardContent>}
</Card>
</Grid>
{data &&
<Grid item className={classes.buttonGrid} >
<ColorButton variant="contained" className={classes.clearButton} color="primary" component="span" size="large" onClick={clearData} startIcon={<Clear fontSize="large" />}>
Clear
</ColorButton>
</Grid>}
</Grid >
</Container >
</React.Fragment >
);
};