Untitled
unknown
javascript
a year ago
8.7 kB
3
Indexable
import React, { useState } from "react"; import { AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, Box, Flex, Heading, Button, Editable, EditableInput, EditablePreview, Image, useColorModeValue, IconButton, useToast, } from "@chakra-ui/react"; import { AiOutlineDelete, AiOutlineSave } from "react-icons/ai"; const InventoryCard = ({ itemToDisplay, updateCatalogueAfterDelete, updateCatalogueAfterPatch, }) => { const [currentItem, setCurrentItem] = useState(itemToDisplay); const toast = useToast(); const toggleAvailability = () => { setCurrentItem({ ...currentItem, availability: !currentItem.availability, }); }; const setPrice = (event) => { const numericValue = event.target.value.replace(/[^0-9]/g, ""); // only numbers. const price = parseInt(numericValue) || 0; setCurrentItem({ ...currentItem, price }); }; //item listing deleted from db, grandparent state update and according toast const listenForItemDeletion = () => { const successToastMessageDelete = () => { toast({ title: "Item Deleted.", description: "We've deleted your listing for you.", status: "success", duration: 3000, isClosable: true, }); }; const errorToastMessageDelete = () => { toast({ title: "Error encountered.", description: "We were unable to delete your item, please try again.", status: "error", duration: 3000, isClosable: true, }); }; const itemDeletion = async () => { try { const resp = await fetch( `${process.env.REACT_APP_API_CATALOGUE}/${currentItem.id}`, { method: "DELETE", } ); const data = await resp.json(); updateCatalogueAfterDelete(currentItem.id); successToastMessageDelete(); } catch (error) { console.error(`Error: ${error}`); errorToastMessageDelete(); } }; itemDeletion(); }; //item listing patched in db, grandparent state update and according toast const listenForItemPatch = () => { const successToastMessagePatch = () => { toast({ title: "Item Saved.", description: "We've updated your listing for you.", status: "success", duration: 3000, isClosable: true, }); }; const errorToastMessagePatch = () => { toast({ title: "Error encountered.", description: "We were unable to save your item, please try again.", status: "error", duration: 3000, isClosable: true, }); }; const itemPatch = async () => { try { const resp = await fetch( `${process.env.REACT_APP_API_CATALOGUE}/${currentItem.id}`, { method: "PATCH", header: { "Content-Type": "application/json", }, body: JSON.stringify({ id: currentItem.id, item: currentItem.item, category: currentItem.category, type: currentItem.type, image: currentItem.image, description: currentItem.description, size: currentItem.sizes, colors: currentItem.colors, price: currentItem.price + 0.99, availability: currentItem.availability, }), } ); const data = await resp.json(); console.log(`currentItem state: `); console.log(currentItem); console.log(`data sent back: `); console.log(data); successToastMessagePatch(); } catch (error) { console.log(`Error: ${error}`); errorToastMessagePatch(); } }; itemPatch(); }; const toggleSizeAvailability = (sizeToToggle) => { setCurrentItem((prevItem) => { const updatedSizes = prevItem.sizes.map((size) => { const { size: currentSize, isAvailable } = size; return currentSize === sizeToToggle ? { size: currentSize, isAvailable: !isAvailable } : size; }); return { ...prevItem, sizes: updatedSizes }; }); }; const toggleColorAvailability = (colorName) => { setCurrentItem((prevItem) => ({ ...prevItem, colors: prevItem.colors.map((color) => color.colorName === colorName ? { ...color, isAvailable: !color.isAvailable } : color ), })); }; return ( <AccordionItem mt={4} mb={4} display="flex" flexDir={"column"}> <Flex> <AccordionButton> {/* Item Name */} <Heading size="sm" color="accent.500"> Item Name: </Heading> <Editable value={currentItem.item} w="300px" color={useColorModeValue("black", "white")} > <EditablePreview /> <EditableInput name="item" onChange={(event) => { setCurrentItem({ ...currentItem, item: event.target.value }); }} /> </Editable> {/* Item Icon */} <Box as="span" flex="1" textAlign="right"> <AccordionIcon /> </Box> </AccordionButton> <Flex> <AccordionPanel> {/* Item Image */} <Image marginTop={"2"} src={currentItem.image || "https://placehold.co/400"} alt="Item's displayed image" rounded="full" width={["100px", "100px", "100px", "100px", "100px"]} objectFit={"cover"} /> </AccordionPanel> </Flex> </Flex> {/* Item Price */} <AccordionPanel> <Box as="span" flex="1" textAlign="left"> <Heading size="sm" color="accent.500"> Item Price: </Heading> <Editable value={currentItem.price} w="300px"> <EditablePreview /> <EditableInput name="price" onChange={setPrice} /> </Editable> </Box> {/* Item Description */} <Box as="span" display={"flex"} flexDirection="column" textAlign="left"> <Heading size="sm" color="accent.500"> Item Description: </Heading> <Editable value={currentItem.description} isTruncated whiteSpace={"wrap"} maxWidth={"500px"} > <EditablePreview isTruncated whiteSpace={"wrap"} /> <EditableInput name="description" fontFamily={"body"} onChange={(e) => setCurrentItem({ ...currentItem, description: e.target.value }) } isTruncated whiteSpace={"wrap"} /> </Editable> </Box> {/* Sizes */} <Flex mb={2}> {currentItem.sizes && currentItem.sizes.map((size) => ( <Button key={size.size} variant={size.isAvailable ? "secondary" : "accent"} onClick={() => toggleSizeAvailability(size.size)} border={"1px solid"} maxWidth={"20px"} marginRight={"2"} > {size.size} </Button> ))} </Flex> {/* Colors */} <Flex mb={2}> {currentItem.colors.map((color) => ( <Button key={color.colorName} variantColor={color.colorName} variant={color.isAvailable ? "dynamic" : "dynamicSelected"} onClick={() => toggleColorAvailability(color.colorName)} maxWidth={"20px"} marginRight={"2"} /> ))} </Flex> {/* Availability */} <Flex marginTop={4}> <div className="flex-1"> <IconButton colorScheme="red" icon={<AiOutlineDelete />} marginRight={2} onClick={listenForItemDeletion} /> </div> <div> <Button colorScheme={currentItem.availability ? "green" : "red"} onClick={toggleAvailability} marginRight={"2"} > {currentItem.availability ? "Available" : "Unavailable"} </Button> <IconButton colorScheme="green" icon={<AiOutlineSave />} marginRight={2} onClick={listenForItemPatch} /> </div> </Flex> </AccordionPanel> </AccordionItem> ); }; export default InventoryCard;
Editor is loading...