expensesTables
Tue Mar 12 2024 06:59:04 GMT+0000 (Coordinated Universal Time)
Saved by @Raj0250
import React, { useEffect, useState } from "react"; import "./expensesTables.css" import Button from 'react-bootstrap/Button'; import Offcanvas from 'react-bootstrap/Offcanvas'; import defaultIcon from "../../../../assets/images/icon/default.png"; import { Check, ChevronLeft,ArrowDown,ArrowUp , Building,Person,Plus } from "react-bootstrap-icons"; import NodataImg from "../../../../assets/images/img/NodataImg.png"; import nodataBg from "../../../../assets/images/nodataBg.png"; import SearchIcon from "../../../../assets/images/icon/searchIcon.png"; import { Table } from "react-bootstrap"; import TableTopBar from "./TableTopBar"; import { Resizable } from 'react-resizable'; import StatusPopup from "./StatusPopup"; const ExpensesTables = ({ expensesData,rowsNo }) => { const [sortField, setSortField] = useState("Quote"); const [sortDirection, setSortDirection] = useState("asc"); const [selectedRow, setSelectedRow] = useState(null); // Formate Date const formatDate = (timestamp) => { const date = new Date(timestamp * 1000); const day = date.getDate(); const monthAbbreviation = new Intl.DateTimeFormat("en-US", { month: "short", }).format(date); const year = date.getFullYear(); return `${day} ${monthAbbreviation} ${year}`; }; const toggleSort = (field) => { setSortField(field); setSortDirection((prevDirection) => prevDirection === "asc" ? "desc" : "asc" ); }; const sortedClientsData = [...expensesData].sort((a, b) => { const aValue = a[sortField]; const bValue = b[sortField]; if (aValue === undefined || bValue === undefined) { return 0; } if (sortDirection === "asc") { return aValue.localeCompare(bValue, undefined, { numeric: true }); } else { return bValue.localeCompare(aValue, undefined, { numeric: true }); } }); const [show, setShow] = useState(false); const handleRowClick = (rowId) => { setSelectedRow(rowId === selectedRow ? null : rowId); setShow(true) }; const handleClose = () => setShow(false); const [selectedRows, setSelectedRows] = useState([]); const handleSelectAllCheckboxChange = () => { const allRowIds = expensesData.map((sale) => sale.id); if (selectedRows.length === allRowIds.length) { setSelectedRows([]); } else { setSelectedRows(allRowIds); } }; const selectedRowsCount = selectedRows.length; const [columns, setColumns] = useState([ { field: "Quote", headerName: ( <div className="styleColor1" onClick={() => toggleSort("Quote")}> <span>Expense ID</span> {sortField === "Quote" && ( <span> {sortDirection === "asc" ? ( <ArrowUp size={16} color="#475467" /> ) : ( <ArrowDown size={16} color="#475467" /> )} </span> )} </div> ), renderCell: (params) => ( <div className="styleColor1"> <strong>{params.value}</strong> <p>{params.row.created}</p> </div> ), }, { field: "supplier", headerName: ( <div className="styleColor1" onClick={() => toggleSort("supplier")}> <span>Supplier</span> {sortField === "supplier" && ( <span> {sortDirection === "asc" ? ( <ArrowUp size={16} color="#475467" /> ) : ( <ArrowDown size={16} color="#475467" /> )} </span> )} </div> ), renderCell: (params) => ( <div className="userImgStyle1"> <div className="innerFlex styleColor2 d-flex justify-content-between"> <div className="leftStyle spaceBorder d-flex align-items-center isbusinessIcon"> {params.row.photo ? ( <img src={params.row.photo} alt={params.row.photo} style={{ marginRight: "5px" }} onError={(e) => { e.target.src = defaultIcon; e.target.alt = "Image Not Found"; }} /> ) : ( params.row.isbusiness ? ( <div className="iconBuilding icon"> <Building size={13.71} color="#667085" /> </div> ) : ( <div className="iconPerson icon"> <Person size={24} color="#667085" /> </div> ) )} <span>{params.value}</span> </div> <Button className="linkByttonStyle" variant="link">Open</Button> </div> </div> ), }, { field: "reference", sortable: false, headerName: "Reference", width: 440, renderCell: (params) => { return ( <div className="mainStyle " style={{ whiteSpace: "normal", textAlign: "left" }} > {params.value} </div> ); }, }, { field: "duedate", sortable: false, headerName: "Due Date", width: 120, renderCell: (params) => { return ( <div className="mainStyle duedate" style={{ whiteSpace: "normal", textAlign: "left" }} > {formatDate(params.value)} </div> ); }, }, { field: "total", sortable: false, headerName: "Total", width: 131, renderCell: (params) => ( <div className="totalpayEx" style={{ whiteSpace: "normal", textAlign: "center" }} > $ {params.value}<span className="lineVerticle"><Plus size={12} color="#079455" /></span> </div> ), }, { field: "UserInvoice", sortable: false, headerName: "Interval/Order", width: 144, renderCell: (params) => ( params.value ? ( <div className="intervalorder" style={{ whiteSpace: "normal", textAlign: "center" }} > {params.value} </div> ) : ( <span></span> ) ), }, { field: "accountCode", sortable: false, headerName: "Account Code", width: 214, renderCell: (params) => ( params.value ? ( <div className="styleColor1 accountCode" style={{ whiteSpace: "normal", textAlign: "left" }} > {params.value}: {params.row.accountname} </div> ) : ( <span></span> ) ), }, { field: "country", sortable: false, headerName: "Xero/Myob", width: 111, renderCell: (params) => ( <div className="styleGrey01" style={{ whiteSpace: "normal", textAlign: "left", textTransform: "uppercase" }} > </div> ), }, { field: "department", sortable: false, headerName: "Departments", width: 128, renderCell: (params) => ( <div className="styleGrey01 departmentstyle" style={{ whiteSpace: "normal", textAlign: "left" }} > {params.value} </div> ), }, { field: "paid", sortable: false, headerName: "Status", width: 120, renderCell: (params) => ( <StatusPopup statusValue={params.value} /> ), } ]); const [rows, setRows] = useState([]); useEffect(()=> { const rows = expensesData.map((expense) => { return { isSelected: selectedRows.includes(expense.id), id: expense.id, Quote: expense.number, created: expense.created, paid: expense.paid, supplier: expense.supplier ? expense.supplier.name : null, photo: expense.supplier ? expense.supplier.photo : null, reference: expense.invoice_reference, duedate: expense.created, total: expense.total, UserInvoice: expense.type, accountCode: expense.account_code ? expense.account_code.code : null, accountname: expense.account_code ? expense.account_code.name : null, department: expense.department ? expense.department.name : null, }; }); setRows(rows) }, [expensesData,selectedRows]) const onResize = (index) => (event, { size }) => { setColumns((prevColumns) => { const nextColumns = [...prevColumns]; nextColumns[index] = { ...nextColumns[index], width: size.width, }; return nextColumns; }); }; const handleCheckboxChange = (rowId) => { const updatedSelectedRows = [...selectedRows]; if (updatedSelectedRows.includes(rowId)) { // Row is already selected, remove it updatedSelectedRows.splice(updatedSelectedRows.indexOf(rowId), 1); } else { // Row is not selected, add it updatedSelectedRows.push(rowId); } setSelectedRows(updatedSelectedRows); }; const isSelected = selectedRows.length > 0; const [rowsfilter, setRowsFilter] = useState([]); const handleRowsFilterChange = (filteredRows) => { const rows = filteredRows.map((expense) => { return { isSelected: selectedRows.includes(expense.id), id: expense.id, Quote: expense.number, created: expense.created, supplier: expense.supplier ? expense.supplier.name : null, photo: expense.supplier ? expense.supplier.photo : null, reference: expense.invoice_reference, duedate: expense.created, total: expense.total, UserInvoice: expense.type, accountCode: expense.account_code ? expense.account_code.code : null, accountname: expense.account_code ? expense.account_code.name : null, department: expense.department ? expense.department.name : null, }; }); setRows(rows); setRowsFilter(rows); }; return ( <div className="expensesTableWrap"> <TableTopBar expensesData={expensesData} rowsfilter={rowsfilter} onRowsFilterChange={handleRowsFilterChange} rows={sortedClientsData} selectedRow={selectedRows} selectClass={isSelected ? "selected-row" : ""} selectedRowCount={selectedRowsCount} /> <Table responsive> <thead style={{ position: "sticky", top: "0px", zIndex: 9 }}> <tr> <th> <label className="customCheckBox"> <input type="checkbox" checked={selectedRows.length === expensesData.length} onChange={handleSelectAllCheckboxChange} /> <span className="checkmark"> <Check color="#9E77ED" size={20} /> </span> </label> </th> {columns.map((column, index) => ( <th key={column.field} style={{ width: column.width }}> <Resizable width={column.width || 100} // Provide a default width if undefined height={0} onResize={onResize(index)} > <div> {column.headerName} </div> </Resizable> </th> ))} </tr> </thead> <tbody> {rows.length === 0 ? ( <tr className="nodataTableRow"> <td colSpan={columns.length} style={{ textAlign: "center" }}> <div style={{ textAlign: "center", marginTop: "20px" }}> <div className="Nodata" style={{ background: `url(${nodataBg})` }} > <div className="image"> <img src={NodataImg} alt="NodataImg" /> <img className="SearchIcon" src={SearchIcon} alt="SearchIcon" /> </div> <h2>There is no results</h2> <p> The user you are looking for doesn't exist. Here are some helpful links: </p> <Button className="gobackButton mb-4 mt-4" variant="link"> {" "} <ChevronLeft color="#000" size={20} /> Go back </Button> <Button className="gobackSupport mt-4" variant="link"> {" "} Support </Button> </div> </div> </td> </tr> ) : ( rows.map((row,index) => ( <tr data-clientuniqueid={row.clientUniqueId} rowsNo={index} key={row.id} className={row.isSelected ? "selected-row" : ""} > <td> <label className="customCheckBox"> <input type="checkbox" checked={selectedRows.includes(row.id)} onChange={() => handleCheckboxChange(row.id)} /> <span className="checkmark"> <Check color="#9E77ED" size={20} /> </span> </label> </td> {columns.map((column) => ( <td key={column.field} onClick={["Quote", "Client", "category"].includes(column.field) ? () => handleRowClick(row.id) : null}> {column.renderCell({ value: row[column.field], row })} </td> ))} </tr> )) )} </tbody> </Table> {/* Sidebar */} {selectedRow && ( <Offcanvas show={show} placement="end" onHide={handleClose}> <Offcanvas.Header closeButton> <Offcanvas.Title><strong>{selectedRow}.</strong> Client Edit Data Head</Offcanvas.Title> </Offcanvas.Header> <Offcanvas.Body> </Offcanvas.Body> </Offcanvas> )} </div> ); }; export default ExpensesTables
Comments