diff --git a/assets/icons/financeicon.svg b/assets/icons/financeicon.svg new file mode 100644 index 0000000..565e9cf --- /dev/null +++ b/assets/icons/financeicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/invoiceicon.svg b/assets/icons/invoiceicon.svg new file mode 100644 index 0000000..77b14a6 --- /dev/null +++ b/assets/icons/invoiceicon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/components/Dashboard/Finance/FinanceOverview.jsx b/src/components/Dashboard/Finance/FinanceOverview.jsx new file mode 100644 index 0000000..5df8e4c --- /dev/null +++ b/src/components/Dashboard/Finance/FinanceOverview.jsx @@ -0,0 +1,61 @@ +import { useContext } from 'react' +import { Flex } from 'antd' +import useCollapseState from '../hooks/useCollapseState' +import StatsDisplay from '../common/StatsDisplay' +import InfoCollapse from '../common/InfoCollapse' +import ScrollBox from '../common/ScrollBox' + +import { ApiServerContext } from '../context/ApiServerContext' + +const FinanceOverview = () => { + const { connected } = useContext(ApiServerContext) + + const [collapseState, updateCollapseState] = useCollapseState( + 'FinanceOverview', + { + invoiceStats: true + } + ) + + if (!connected) { + return null + } + + return ( + + + + + updateCollapseState('invoiceStats', isActive) + } + className='no-t-padding-collapse' + collapseKey='invoiceStats' + > + + + + + + + + ) +} + +export default FinanceOverview + diff --git a/src/components/Dashboard/Finance/FinanceSidebar.jsx b/src/components/Dashboard/Finance/FinanceSidebar.jsx new file mode 100644 index 0000000..7f763da --- /dev/null +++ b/src/components/Dashboard/Finance/FinanceSidebar.jsx @@ -0,0 +1,46 @@ +import { useLocation } from 'react-router-dom' +import DashboardSidebar from '../common/DashboardSidebar' +import InvoiceIcon from '../../Icons/InvoiceIcon' +import FinanceIcon from '../../Icons/FinanceIcon' + +const items = [ + { + key: 'overview', + label: 'Overview', + icon: , + path: '/dashboard/finance/overview' + }, + { type: 'divider' }, + { + key: 'invoices', + label: 'Invoices', + icon: , + path: '/dashboard/finance/invoices' + } +] + +const routeKeyMap = { + '/dashboard/finance/overview': 'overview', + '/dashboard/finance/invoices': 'invoices' +} + +const FinanceSidebar = (props) => { + const location = useLocation() + const selectedKey = (() => { + const match = Object.keys(routeKeyMap).find((path) => { + const pathSplit = path.split('/') + const locationPathSplit = location.pathname.split('/') + if (pathSplit.length > locationPathSplit.length) return false + for (let i = 0; i < pathSplit.length; i++) { + if (pathSplit[i] !== locationPathSplit[i]) return false + } + return true + }) + return match ? routeKeyMap[match] : 'overview' + })() + + return +} + +export default FinanceSidebar + diff --git a/src/components/Dashboard/Finance/Invoices.jsx b/src/components/Dashboard/Finance/Invoices.jsx new file mode 100644 index 0000000..5f59c6e --- /dev/null +++ b/src/components/Dashboard/Finance/Invoices.jsx @@ -0,0 +1,98 @@ +import { useState, useRef } from 'react' +import { Button, Flex, Space, Dropdown, Modal } from 'antd' +import NewInvoice from './Invoices/NewInvoice' +import ObjectTable from '../common/ObjectTable' +import PlusIcon from '../../Icons/PlusIcon' +import ReloadIcon from '../../Icons/ReloadIcon' +import useColumnVisibility from '../hooks/useColumnVisibility' +import GridIcon from '../../Icons/GridIcon' +import ListIcon from '../../Icons/ListIcon' +import useViewMode from '../hooks/useViewMode' +import ColumnViewButton from '../common/ColumnViewButton' + +const Invoices = () => { + const [newInvoiceOpen, setNewInvoiceOpen] = useState(false) + const tableRef = useRef() + + const [viewMode, setViewMode] = useViewMode('invoices') + + const [columnVisibility, setColumnVisibility] = + useColumnVisibility('invoices') + + const actionItems = { + items: [ + { + label: 'New Invoice', + key: 'newInvoice', + icon: + }, + { type: 'divider' }, + { + label: 'Reload List', + key: 'reloadList', + icon: + } + ], + onClick: ({ key }) => { + if (key === 'reloadList') { + tableRef.current?.reload() + } else if (key === 'newInvoice') { + setNewInvoiceOpen(true) + } + } + } + + return ( + <> + + + + + + + + + +