Stashed / app / src / components / modals / addItemModal.jsx
addItemModal.jsx
Raw
import React, { useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import {
  Typography,
  Button,
  Grid,
  TextField,
  ButtonGroup,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  Paper,
  Divider,
  Card,
  CardContent,
  CardMedia,
} from "@material-ui/core";
import CloseIcon from "@material-ui/icons/Close";
import AddIcon from "@material-ui/icons/Add";
import RemoveIcon from "@material-ui/icons/Remove";
import Autocomplete from "@material-ui/lab/Autocomplete";
import useAutocomplete from "@material-ui/lab/useAutocomplete";

import {
  writeConfigRequest,
  useConfigInMainRequest,
} from "secure-electron-store";
import { connect } from "react-redux";
import { v4 as uuidv4 } from "uuid";

import algoliasearch from "algoliasearch";

import { closeModal } from "../../redux/modals/addItemModalSlice";
import { addItem } from "../../redux/data/inventorySlice";
import { Children } from "react";

const useStyles = makeStyles((theme) => ({
  paper: {
    paddingRight: theme.spacing(0.5),
    paddingLeft: theme.spacing(0.5),
    color: theme.palette.text.secondary,
    display: "flex",
    alignItems: "center",
    marginBottom: theme.spacing(1),
  },
  paperTitle: {
    paddingRight: theme.spacing(2.5),
    paddingLeft: theme.spacing(2.5),
    marginBottom: theme.spacing(0.5),
  },
  verticalSpacing: {
    marginBottom: theme.spacing(0.5),
  },
  verticalSpacing2: {
    marginBottom: theme.spacing(2),
  },
  root: {
    display: "flex",
  },
  details: {
    display: "flex",
    flexDirection: "column",
  },
  content: {
    flex: "1 0 auto",
  },
  cover: {
    width: 75,
    minWidth: 75,
    display: "flex",
    alignItems: "center",
    marginLeft: theme.spacing(1.5),
  },
}));

const AddItemModal = (props) => {
  const styles = useStyles();
  // Request so that the main process can use the store
  React.useEffect(() => {
    window.api.store.send(useConfigInMainRequest);

    window.api.stockxData("receiveProductData", (data) => {
      setFetchedProduct(data);
    });
  }, []);
  const [fetchedProduct, setFetchedProduct] = useState({});
  React.useEffect(() => {
    console.log(fetchedProduct);
  }, [fetchedProduct]);

  const stockxClient = algoliasearch(
    "XW7SBCT9V6",
    "6b5e76b49705eb9f51a06d3c82f7acee"
  );
  const stockxIndex = stockxClient.initIndex("products");
  const requestOptions = {
    headers: { "X-Algolia-UserToken": "xw7sbct9v6" },
  };

  const SaveItem = async (e) => {
    e.preventDefault();
    var prevItems = props.inventory.items;
    console.log("PREV ITEMS", prevItems);
    prodSizes.map((size) => {
      for (let i = 0; i < size.qty; i++) {
        Object.keys(fetchedProduct.Product.children).map((child) => {
          let prodSize = 0;
          if (
            !isNaN(fetchedProduct.Product.children[child].shoeSize.slice(-1))
          ) {
            if (fetchedProduct.Product.children[child].shoeSize == size.size)
              prodSize = size.size;
          } else {
            prodSize = fetchedProduct.Product.children[child].shoeSize.replace(
              /[^\d.-]/g,
              ""
            );
          }
          if (prodSize == size.size) {
            const newItem = {
              id: uuidv4(),
              name: prodName,
              sku: prodId,
              size: fetchedProduct.Product.children[child].shoeSize,
              status: "Sitting",
              brand: prodBrand,
              colorway: prodColor,
              condition: prodCondition,
              cost: prodCost,
              costShipping: prodCostShip,
              costTax: prodCostTax,
              store: prodStore,
              dateObtained: new Date(prodDate).toLocaleDateString("en-US"),
              dateAdded: new Date().toLocaleDateString("en-US"),
              description: prodDesc,
              image: prodImage,
              siteLinks: {
                stockX: {
                  parentId: stockxParentId,
                  urlKey: stockxUrl,
                  id: child,
                },
                goat: {},
                flightClub: {},
              },
              marketPrices: {
                stockX: {
                  lowestAsk:
                    fetchedProduct.Product.children[child].market
                      .lowestAskFloat,
                  highestBid:
                    fetchedProduct.Product.children[child].market
                      .highestBidFloat,
                },
                goat: {},
                flightClub: {},
              },
            };
            prevItems = [...prevItems, newItem];
            props.addItem(newItem);
            return;
          }
        });
      }
    });
    window.api.store.send(writeConfigRequest, "inventoryItems", prevItems);
    props.closeModal();
  };

  const [prodName, setProdName] = useState("");
  const [prodId, setProdId] = useState("");
  const [prodCost, setProdCost] = useState(0);
  const [prodCostTax, setProdCostTax] = useState(0);
  const [prodCostShip, setProdCostShip] = useState(0);
  const [prodStore, setProdStore] = useState("");
  const [prodDate, setProdDate] = useState(new Date());
  const [prodDesc, setProdDesc] = useState("");
  const [prodBrand, setProdBrand] = useState("");
  const [prodColor, setProdColor] = useState("");
  const [prodCondition, setProdCondition] = useState("Deadstock");
  const [prodImage, setProdImage] = useState("");

  const [stockxParentId, setStockxParentId] = useState("");
  const [stockxUrl, setStockxUrl] = useState("");

  const [queryResults, setQueryResults] = useState([]);
  React.useEffect(() => {
    if (prodName.length > 2) {
      stockxIndex.search(prodName, requestOptions).then(({ hits }) => {
        setQueryResults(hits);
      });
    }
  }, [prodName]);
  React.useEffect(() => {
    console.log(queryResults, "query results:" + prodName);
  }, [queryResults]);

  const [sizeType, setSizeType] = useState("sneakers");
  const shoeSizes = [
    3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12,
    12.5, 13, 13.5, 14, 15,
  ];
  const apparelSizes = ["XS", "S", "M", "L", "XL", "2XL", "3XL", "4XL"];
  const otherSizes = ["N/A", "OS", "Custom"];

  const [prodSizes, setProdSizes] = useState([]);
  const AddSize = (size) => {
    if (CheckSizeAdded(size)) {
      const objIndex = prodSizes.findIndex((sizeItem) => sizeItem.size == size);

      const newSize = {
        ...prodSizes[objIndex],
        qty: prodSizes[objIndex].qty + 1,
      };
      setProdSizes([
        ...prodSizes.slice(0, objIndex),
        newSize,
        ...prodSizes.slice(objIndex + 1),
      ]);
    } else {
      setProdSizes((sizes) => [...sizes, { size: size, qty: 1 }]);
      setAddedSizes((sizes) => [...sizes, size]);
    }
  };
  const MinusSize = (size) => {
    if (CheckSizeAdded(size)) {
      var result = prodSizes.filter((sizeItem) => {
        return sizeItem.size === size;
      });
      if (result[0].qty == 1) {
        RemoveSize(size);
      } else {
        const objIndex = prodSizes.findIndex(
          (sizeItem) => sizeItem.size == size
        );

        const newSize = {
          ...prodSizes[objIndex],
          qty: prodSizes[objIndex].qty - 1,
        };
        setProdSizes([
          ...prodSizes.slice(0, objIndex),
          newSize,
          ...prodSizes.slice(objIndex + 1),
        ]);
      }
    }
  };
  const RemoveSize = (size) => {
    setProdSizes(
      prodSizes.filter((sizeItem) => {
        return sizeItem.size !== size;
      })
    );
    setAddedSizes(
      addedSizes.filter((sizes) => {
        return sizes !== size;
      })
    );
  };
  const [addedSizes, setAddedSizes] = useState([]);
  const CheckSizeAdded = (size) => {
    if (addedSizes.includes(size)) {
      return true;
    }
    return false;
  };

  const resetModalState = () => {
    setProdName("");
    setProdId("");
    setProdCost(0);
    setProdCostTax(0);
    setProdCostShip(0);
    setProdStore("");
    setProdDate(new Date());
    setProdDesc("");
    setProdBrand("");
    setProdColor("");
    setProdCondition("Deadstock");
    setStockxParentId("");
    setStockxUrl("");
    setProdImage("");
    setProdSizes([]);
    setAddedSizes([]);
  };
  React.useEffect(() => {
    resetModalState();
  }, [props.addItemModal.visibility]);

  const {
    getRootProps,
    getInputLabelProps,
    getInputProps,
    getListboxProps,
    getOptionProps,
    groupedOptions,
  } = useAutocomplete({
    id: "use-autocomplete-demo",
    options: queryResults,
    getOptionLabel: (res) => res.title,
  });

  return (
    <>
      <Dialog
        open={props.addItemModal.visibility}
        aria-labelledby="form-dialog-title"
      >
        <DialogTitle id="form-dialog-title">Add New Item</DialogTitle>
        <DialogContent>
          <Grid container spacing={1}>
            <Grid
              container
              item
              xs={12}
              spacing={1}
              className={styles.verticalSpacing}
            >
              <Grid item xs={8}>
                <Autocomplete
                  id="stockxQueryResults"
                  freeSolo
                  options={queryResults}
                  getOptionLabel={(option) => option.name}
                  renderOption={(option) => (
                    <Card
                      className={styles.root}
                      onClick={() => {
                        setProdName(option.name);
                        setProdId(option.style_id);
                        setProdDate(option.release_date);
                        setProdCost(option.price);
                        setProdBrand(option.brand);
                        setProdColor(option.colorway);
                        setStockxParentId(option.id);
                        setStockxUrl(option.url);
                        setProdImage(option.thumbnail_url);
                        window.api.stockxData("getProductData", option.url);
                      }}
                    >
                      <CardMedia className={styles.cover} title={option.name}>
                        <img src={option.media.thumbUrl} />
                      </CardMedia>
                      <div className={styles.details}>
                        <CardContent className={styles.content}>
                          <Typography variant="subtitle1">
                            {option.name}
                          </Typography>
                          <Typography variant="subtitle2" color="textSecondary">
                            {option.style_id}
                          </Typography>
                          <Typography variant="overline" color="textSecondary">
                            Released {option.release_date}
                          </Typography>
                        </CardContent>
                      </div>
                    </Card>
                  )}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      id="prodName"
                      label="Product Name"
                      variant="filled"
                      size="small"
                      fullWidth
                      onChange={(e) => {
                        setProdName(e.target.value);
                      }}
                    />
                  )}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  id="prodId"
                  label="Product ID"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodId}
                  onChange={(e) => {
                    setProdId(e.target.value);
                  }}
                />
              </Grid>
            </Grid>

            <Grid
              container
              item
              xs={12}
              spacing={1}
              className={styles.verticalSpacing}
            >
              <Grid item xs={4}>
                <TextField
                  id="prodBrand"
                  label="Brand"
                  variant="filled"
                  size="small"
                  placeholder="Nike"
                  fullWidth
                  value={prodBrand}
                  onChange={(e) => {
                    setProdBrand(e.target.value);
                  }}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  id="prodColor"
                  label="Colorway"
                  variant="filled"
                  size="small"
                  fullWidth
                  placeholder="Black"
                  value={prodColor}
                  onChange={(e) => {
                    setProdColor(e.target.value);
                  }}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  id="prodCondition"
                  label="Condition"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodCondition}
                  onChange={(e) => {
                    setProdCondition(e.target.value);
                  }}
                />
              </Grid>
            </Grid>

            <Grid
              container
              item
              xs={12}
              spacing={1}
              className={styles.verticalSpacing}
            >
              <Grid item xs={4}>
                <TextField
                  id="prodCost"
                  label="Cost"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodCost}
                  onChange={(e) => {
                    setProdCost(e.target.value);
                  }}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  id="prodCostTax"
                  label="Tax"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodCostTax}
                  onChange={(e) => {
                    setProdCostTax(e.target.value);
                  }}
                />
              </Grid>
              <Grid item xs={4}>
                <TextField
                  id="prodCostShip"
                  label="Shipping"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodCostShip}
                  onChange={(e) => {
                    setProdCostShip(e.target.value);
                  }}
                />
              </Grid>
            </Grid>

            <Grid
              container
              item
              xs={12}
              spacing={1}
              className={styles.verticalSpacing2}
            >
              <Grid item xs={6}>
                <TextField
                  id="prodStore"
                  label="Store Purchased"
                  variant="filled"
                  size="small"
                  fullWidth
                  value={prodStore}
                  onChange={(e) => {
                    setProdStore(e.target.value);
                  }}
                />
              </Grid>
              <Grid item xs={6}>
                <TextField
                  id="prodDate"
                  label="Purchase Date"
                  variant="filled"
                  size="small"
                  type="date"
                  value={prodDate}
                  onChange={(e) => {
                    setProdDate(e.target.value);
                  }}
                  InputLabelProps={{
                    shrink: true,
                  }}
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid
              container
              item
              xs={12}
              spacing={1}
              justify="center"
              className={styles.verticalSpacing}
            >
              <ButtonGroup color="primary">
                <Button
                  variant={sizeType == "sneakers" ? "contained" : ""}
                  onClick={() => {
                    setSizeType("sneakers");
                  }}
                >
                  Sneakers
                </Button>
                <Button
                  variant={sizeType == "apparel" ? "contained" : ""}
                  onClick={() => {
                    setSizeType("apparel");
                  }}
                >
                  Apparel
                </Button>
                <Button
                  variant={sizeType == "other" ? "contained" : ""}
                  onClick={() => {
                    setSizeType("other");
                  }}
                >
                  Other
                </Button>
              </ButtonGroup>
            </Grid>

            <Grid
              container
              item
              xs={12}
              spacing={1}
              justify="center"
              className={styles.verticalSpacing2}
            >
              {sizeType == "sneakers"
                ? shoeSizes.map((size) => (
                    <Grid item key={size}>
                      <Button
                        variant="contained"
                        color="primary"
                        size="small"
                        onClick={() => {
                          AddSize(size);
                        }}
                        disabled={CheckSizeAdded(size)}
                      >
                        {size}
                      </Button>
                    </Grid>
                  ))
                : sizeType == "apparel"
                ? apparelSizes.map((size) => (
                    <Grid item key={size}>
                      <Button
                        variant="contained"
                        color="primary"
                        size="small"
                        onClick={() => {
                          AddSize(size);
                        }}
                        disabled={CheckSizeAdded(size)}
                      >
                        {size}
                      </Button>
                    </Grid>
                  ))
                : otherSizes.map((size) => (
                    <Grid item key={size}>
                      {size.toLowerCase() == "custom" ? (
                        <Button
                          variant="outlined"
                          color="primary"
                          size="small"
                          onClick={() => {
                            AddSize(size);
                          }}
                        >
                          {size}
                        </Button>
                      ) : (
                        <Button
                          variant="contained"
                          color="primary"
                          size="small"
                          onClick={() => {
                            AddSize(size);
                          }}
                          disabled={CheckSizeAdded(size)}
                        >
                          {size}
                        </Button>
                      )}
                    </Grid>
                  ))}
            </Grid>

            {prodSizes.length > 0 && (
              <Grid
                container
                xs={12}
                spacing={1}
                direction="column"
                justify="center"
                className={styles.verticalSpacing}
              >
                <Grid
                  container
                  xs={12}
                  direction="row"
                  className={styles.paperTitle}
                >
                  <Grid
                    container
                    xs={6}
                    direction="row"
                    justify="flex-start"
                    alignItems="flex-start"
                  >
                    <Typography variant="h6">Size</Typography>
                  </Grid>
                  <Grid
                    container
                    xs={6}
                    direction="row"
                    justify="flex-end"
                    alignItems="flex-start"
                  >
                    <Typography variant="h6">Quantity</Typography>
                  </Grid>
                </Grid>

                {prodSizes.map((sizeItem) => (
                  <Paper className={styles.paper} elevation={1}>
                    <Grid container xs={6} alignItems="center">
                      <IconButton
                        color="primary"
                        aria-label="remove-size"
                        onClick={() => {
                          RemoveSize(sizeItem.size);
                        }}
                      >
                        <CloseIcon />
                      </IconButton>
                      <Typography variant="h6">{sizeItem.size}</Typography>
                    </Grid>
                    <Grid
                      container
                      xs={6}
                      alignItems="center"
                      justify="flex-end"
                    >
                      <IconButton
                        color="primary"
                        aria-label="minus-size"
                        component="span"
                        onClick={() => {
                          MinusSize(sizeItem.size);
                        }}
                      >
                        <RemoveIcon />
                      </IconButton>
                      <Typography variant="h6">{sizeItem.qty}</Typography>
                      <IconButton
                        color="primary"
                        aria-label="add-size"
                        onClick={() => {
                          AddSize(sizeItem.size);
                        }}
                      >
                        <AddIcon />
                      </IconButton>
                    </Grid>
                  </Paper>
                ))}
              </Grid>
            )}
            <Grid container xs={12}>
              <TextField
                id="prodDesc"
                label="Description"
                multiline
                rows={3}
                variant="filled"
                size="small"
                type="date"
                onChange={(e) => {
                  setProdDesc(e.target.value);
                }}
                fullWidth
              />
            </Grid>
          </Grid>
        </DialogContent>
        <DialogActions>
          <Button
            color="primary"
            onClick={() => {
              props.closeModal();
            }}
          >
            Cancel
          </Button>
          <Button
            color="primary"
            onClick={(e) => {
              SaveItem(e);
            }}
          >
            Add Item
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
};

const mapStateToProps = (state, props) => ({
  addItemModal: state.addItemModal,
  inventory: state.inventory,
});
const mapDispatch = { closeModal, addItem };

export default connect(mapStateToProps, mapDispatch)(AddItemModal);