From cabc68c932fedfb5a567276bb0387a166d77e629 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sat, 27 Dec 2025 13:45:26 +0000 Subject: [PATCH] Add finance dashboard components and routes - Introduced FinanceOverview, FinanceSidebar, and Invoices components for the finance dashboard. - Added InvoiceInfo and NewInvoice components for managing invoices. - Created SVG icons for finance and invoice. - Updated routing to include finance-related paths. - Enhanced DashboardBreadcrumb and DashboardNavigation to support finance navigation. - Defined Invoice model with actions and properties for invoice management. --- assets/icons/financeicon.svg | 1 + assets/icons/invoiceicon.svg | 14 + .../Dashboard/Finance/FinanceOverview.jsx | 61 ++++ .../Dashboard/Finance/FinanceSidebar.jsx | 46 +++ src/components/Dashboard/Finance/Invoices.jsx | 98 +++++ .../Finance/Invoices/InvoiceInfo.jsx | 218 ++++++++++++ .../Dashboard/Finance/Invoices/NewInvoice.jsx | 113 ++++++ .../Dashboard/common/DashboardBreadcrumb.jsx | 1 + .../Dashboard/common/DashboardNavigation.jsx | 8 + src/components/Icons/InvoiceIcon.jsx | 9 + src/database/models/Invoice.js | 336 ++++++++++++++++++ src/routes/FinanceRoutes.jsx | 29 ++ src/routes/index.js | 1 + 13 files changed, 935 insertions(+) create mode 100644 assets/icons/financeicon.svg create mode 100644 assets/icons/invoiceicon.svg create mode 100644 src/components/Dashboard/Finance/FinanceOverview.jsx create mode 100644 src/components/Dashboard/Finance/FinanceSidebar.jsx create mode 100644 src/components/Dashboard/Finance/Invoices.jsx create mode 100644 src/components/Dashboard/Finance/Invoices/InvoiceInfo.jsx create mode 100644 src/components/Dashboard/Finance/Invoices/NewInvoice.jsx create mode 100644 src/components/Icons/InvoiceIcon.jsx create mode 100644 src/database/models/Invoice.js create mode 100644 src/routes/FinanceRoutes.jsx 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 ( + <> + + + + + + + + + +