Diff of /frontend/src/home.js [000000] .. [70ba26]

Switch to side-by-side view

--- a
+++ b/frontend/src/home.js
@@ -0,0 +1,298 @@
+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 >
+  );
+};