From d800aedcdf4bf50e55951880e287f4c9292490d9 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Mon, 14 Apr 2025 10:43:33 -0600 Subject: [PATCH] qr code for bins re-implemented with new table --- src/common/QrCodeGenerator.tsx | 300 +++++++++++++++++++++++++++++++++ src/pages/Bins.tsx | 32 ++-- 2 files changed, 316 insertions(+), 16 deletions(-) create mode 100644 src/common/QrCodeGenerator.tsx diff --git a/src/common/QrCodeGenerator.tsx b/src/common/QrCodeGenerator.tsx new file mode 100644 index 0000000..8d5ddcb --- /dev/null +++ b/src/common/QrCodeGenerator.tsx @@ -0,0 +1,300 @@ +import { Box, Button, DialogActions, DialogContent, DialogTitle } from "@mui/material"; +// import MaterialTable from "material-table"; +import React, { useEffect, useState } from "react"; +import ResponsiveDialog from "./ResponsiveDialog"; +// import { getTableIcons } from "./ResponsiveTable"; +import { Document, Image, Page, PDFViewer, StyleSheet, Text, View } from "@react-pdf/renderer"; +import { useMobile } from "hooks"; +import { cloneDeep } from "lodash"; +import ResponsiveTable from "./ResponsiveTable"; + +export interface QrCodeKey { + name: string; + key: string; +} + +interface Props { + open: boolean; + close: () => void; + keyList: QrCodeKey[]; + requiredUrlAffix: string; + url?: string; +} + +export default function(props: Props) { + const { open, close, url, requiredUrlAffix, keyList } = props; + const [selectedKeys, setSelectedKeys] = useState([]); + const [selectedPageRows, setSelectedPageRows] = useState>(new Map())//key is the page value is an array of row indexes for that page + const [tablePage, setTablePage] = useState(0) + const [pageSize, setPageSize] = useState(10) + const isMobile = useMobile(); + const [displayedRows, setDisplayedRows] = useState([]); + const codesPerPage = 4; + const pdfStyle = StyleSheet.create({ + viewerDesktop: { + height: 500 * 1.44, + width: 500 + }, + viewerMobile: { + height: "100%", + width: "100%" + }, + page: { + padding: "3%", + textAlign: "center", + fontFamily: "Helvetica-Bold", + fontSize: 30 + }, + quadrant: { + width: "50%", + textAlign: "center", + //margin: 10, + borderRadius: 20 + }, + code: { + flexDirection: "column", + border: "2px dotted black", + margin: 10, + borderRadius: 20 + }, + image: { + padding: 20, + paddingBottom: 0 + //height: "65%" + //border: "1px solid black", //used just to see a representation of where the view is + }, + text: { + marginTop: 30, + marginBottom: 30, + textAlign: "center", + justifyContent: "center" + //border: "1px solid black", //used just to see a representation of where the view is + } + }); + + useEffect(()=>{ + let clone: QrCodeKey[] = cloneDeep(keyList) + let rows = clone.splice(tablePage * pageSize, pageSize) + setDisplayedRows(rows) + },[keyList, tablePage, pageSize]) + + const handleRowsPerPageChange = (event: any) => { + const newRowsPerPage = parseInt(event.target.value, 10); // Get selected value + setPageSize(newRowsPerPage); + setTablePage(0) + //clear the selected rows + setSelectedPageRows(new Map()) + //clear the selected keys + setSelectedKeys([]) + } + + const rowSelected = (row: QrCodeKey, index: number, checked: boolean) => { + //when a row is selected add it to the map for the page + let selected = cloneDeep(selectedKeys) + let pageMap = cloneDeep(selectedPageRows) + let pageSelect = pageMap.get(tablePage) + if(checked){ //add the page/index to the map + if(pageSelect){ + pageSelect.push(index) + }else{ + pageMap.set(tablePage, [index]) + } + //handle the row data to add it to a list of keys that are selected + selected.push(row) + }else{ //remove the page/index from the map + if(pageSelect){ + pageSelect.splice(pageSelect.indexOf(index)) + } + //remove the selected object from the array + selected.forEach((codeKey, index) => { + if(row.key === codeKey.key){ + selected.splice(index) + } + }) + } + setSelectedKeys(selected) + setSelectedPageRows(pageMap) + } + + const selectionTable = () => { + return ( + + {row.name} + } + ]} + rowSelect={rowSelected} + selectedRows={selectedPageRows.get(tablePage)} + rows={displayedRows} + page={tablePage} + pageSize={pageSize} + total={keyList.length} + setPage={(page) => {setTablePage(page)}} + handleRowsPerPageChange={handleRowsPerPageChange} + /> + {/* { + setSelectedKeys(data); + }} + columns={[ + { + cellStyle: { + padding: 0 + }, + title: "Name", + field: "name" + } + ]}> */} + + ); + }; + + const generatedCodes = () => { + let numPages = Math.ceil(selectedKeys.length / codesPerPage); + let keys = cloneDeep(selectedKeys); + let pages: JSX.Element[] = []; + + let location = url ?? document.URL; //document.URL will append the ending slash to the url string + if (!location.includes(requiredUrlAffix)) { + location = location + requiredUrlAffix; + } + + for (let i = 0; i < numPages; i++) { + let pageKeys = keys.splice(0, codesPerPage); + pages.push( + + + {pageKeys[0] && ( + + + + + + + {pageKeys[0].name} + + + + )} + {pageKeys[1] && ( + + + + + + + {pageKeys[1].name} + + + + )} + + + {pageKeys[2] && ( + + + + + + + {pageKeys[2].name} + + + + )} + {pageKeys[3] && ( + + + + + + + {pageKeys[3].name} + + + + )} + + + ); + } + + return ( + + {pages} + + ); + }; + + return ( + + Generate QR Codes + + {selectionTable()} + + + {generatedCodes()} + + + + + + + + ); +} diff --git a/src/pages/Bins.tsx b/src/pages/Bins.tsx index 8d9aff9..c3eb6be 100644 --- a/src/pages/Bins.tsx +++ b/src/pages/Bins.tsx @@ -46,7 +46,7 @@ import BinsList from "bin/BinsList"; // import BinYard from "bin/BinYard"; import BinInventoryChart, { GrainAmount } from "charts/BinInventoryChart"; import BinUtilizationChart from "charts/BinUtilizationChart"; -// import QrCodeGenerator, { QrCodeKey } from "common/QrCodeGenerator"; +import QrCodeGenerator, { QrCodeKey } from "common/QrCodeGenerator"; import GrainDescriber, { grainName } from "grain/GrainDescriber"; // import GrainBagList from "grainBag/grainBagList"; // import GrainBagSettings from "grainBag/grainBagSettings"; @@ -184,7 +184,7 @@ export default function Bins(props: Props) { const [expandUtilization, setExpandUtilization] = useState(false); const [expandFanTable, setExpandFanTable] = useState(false); const [openQrGenerator, setOpenQrGenerator] = useState(false); - // const [qrKeyList, setQrKeyList] = useState([]); + const [qrKeyList, setQrKeyList] = useState([]); const [totalFanControllers, setTotalFanControllers] = useState(0); const [totalFanControllersOn, setTotalFanControllersOn] = useState(0); const [yardsLoading, setYardsLoading] = useState(false); @@ -313,7 +313,7 @@ export default function Bins(props: Props) { let grain: Bin[] = []; let empty: Bin[] = []; let fert: Bin[] = []; - // let qr: QrCodeKey[] = []; + let qr: QrCodeKey[] = []; let b = resp.data.bins.map(b => Bin.any(b)); b.forEach(bin => { if (bin.empty()) { @@ -324,12 +324,12 @@ export default function Bins(props: Props) { grain.push(bin); } //build qr keys here - // qr.push({ - // key: bin.key(), - // name: bin.name() - // }); + qr.push({ + key: bin.key(), + name: bin.name() + }); }); - // setQrKeyList(qr); + setQrKeyList(qr); setGrainBins(grain); if (fert.length > 0) { setDisplayFert(true); @@ -428,7 +428,7 @@ export default function Bins(props: Props) { let empty: Bin[] = offset ? emptyBins : []; let fert: Bin[] = offset ? fertilizerBins : []; let grain: Bin[] = offset ? grainBins : []; - // let newKeyList: QrCodeKey[] = qrKeyList; + let newKeyList: QrCodeKey[] = qrKeyList; newBins.forEach(bin => { if (bin.empty()) { empty.push(bin); @@ -437,10 +437,10 @@ export default function Bins(props: Props) { } else { grain.push(bin); } - // newKeyList.push({ - // key: bin.key(), - // name: bin.name() - // }); + newKeyList.push({ + key: bin.key(), + name: bin.name() + }); }); if (fert.length > 0) { setDisplayFert(true); @@ -451,7 +451,7 @@ export default function Bins(props: Props) { setGrainBins([...grain]); setEmptyBins([...empty]); setFertilizerBins([...fert]); - // setQrKeyList([...newKeyList]); + setQrKeyList([...newKeyList]); }) .catch(err => { setPaginatedBins({ bins: [], binsOffset: 0, binsTotal: 0 }); @@ -1390,14 +1390,14 @@ export default function Bins(props: Props) { setAddBagOpen(false); }} /> - {/* { setOpenQrGenerator(false); }} keyList={qrKeyList} requiredUrlAffix={"bins"} - /> */} + /> {binMenu()} setAddBinOpen(true)} pulse={binsTotal < 1 && !allLoading} />