diff --git a/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx b/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx
index 29a2f3bb4..f78398442 100644
--- a/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx
+++ b/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx
@@ -3,7 +3,15 @@ import React from 'react';
import clsx from 'classnames';
import { Navbar } from '@blueprintjs/core';
-export function DashboardActionsBar({ className, children, name }) {
+interface DashboardActionsBarProps {
+ children?: React.ReactNode;
+}
+
+export function DashboardActionsBar({
+ className,
+ children,
+ name,
+}: DashboardActionsBarProps) {
return (
(
+ {} as RuleFormBootValues,
+);
+
+interface RuleFormBootProps {
+ bankRuleId?: number;
+ children: React.ReactNode;
+}
+
+function RuleFormBoot({ bankRuleId, ...props }: RuleFormBootProps) {
+ const provider = {} as RuleFormBootValues;
+
+ return (
+
+
+
+ );
+}
+
+const useRuleFormDialogBoot = () =>
+ React.useContext(RuleFormBootContext);
+
+export { RuleFormBoot, useRuleFormDialogBoot };
diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx
new file mode 100644
index 000000000..e96b1d500
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx
@@ -0,0 +1,19 @@
+import { RuleFormBoot } from "./RuleFormBoot";
+
+
+interface RuleFormContentProps {
+ dialogName: string;
+ bankRuleId?: number;
+}
+export function RuleFormContent({
+ dialogName,
+ bankRuleId,
+}: RuleFormContentProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts
new file mode 100644
index 000000000..3cde8f265
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+import * as Yup from 'yup';
+
+const Schema = Yup.object().shape({
+ name: Yup.string().required().label('Rule name'),
+ applyIfAccountId: Yup.number().required().label(''),
+ applyIfTransactionType: Yup.string().required().label(''),
+ conditionsType: Yup.string().required(),
+ assignCategory: Yup.string().required(),
+ assignAccountId: Yup.string().required(),
+});
+
+export const CreateRuleFormSchema = Schema;
diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx
new file mode 100644
index 000000000..a018fe9df
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx
@@ -0,0 +1,134 @@
+import { Form, Formik, useFormikContext } from 'formik';
+import { Button, Radio } from '@blueprintjs/core';
+import { CreateRuleFormSchema } from './RuleFormContentForm.schema';
+import {
+ Box,
+ FFormGroup,
+ FInputGroup,
+ FRadioGroup,
+ FSelect,
+ Group,
+} from '@/components';
+
+const initialValues = {
+ name: '',
+ order: 0,
+ applyIfAccountId: '',
+ applyIfTransactionType: '',
+ conditionsType: '',
+ conditions: [
+ {
+ field: 'description',
+ comparator: 'contains',
+ value: 'payment',
+ },
+ ],
+ assignCategory: '',
+ assignAccountId: '',
+};
+
+interface RuleFormValues {
+ name: string;
+ order: number;
+ applyIfAccountId: string;
+ applyIfTransactionType: string;
+ conditionsType: string;
+ conditions: Array<{
+ field: string;
+ comparator: string;
+ value: string;
+ }>;
+ assignCategory: string;
+ assignAccountId: string;
+}
+
+export function RuleFormContentForm() {
+ const validationSchema = CreateRuleFormSchema;
+ const handleSubmit = () => {};
+
+ return (
+
+ initialValues={initialValues}
+ validationSchema={validationSchema}
+ onSubmit={handleSubmit}
+ >
+
+
+ );
+}
+
+function RuleFormConditions() {
+ const { values } = useFormikContext();
+
+ const handleAddConditionBtnClick = () => {
+ values.conditions.push({
+ field: '',
+ comparator: '',
+ value: '',
+ });
+ };
+
+ return (
+
+ {values?.conditions?.map((condition, index) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx
new file mode 100644
index 000000000..5fa6929f7
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx
@@ -0,0 +1,33 @@
+// @ts-nocheck
+import React from 'react';
+import { Dialog, DialogSuspense } from '@/components';
+import withDialogRedux from '@/components/DialogReduxConnect';
+import { compose } from '@/utils';
+
+const RuleFormContent = React.lazy(() => import('./RuleFormContent'));
+
+/**
+ * Payment mail dialog.
+ */
+function RuleFormDialog({
+ dialogName,
+ payload: { bankRuleId = null },
+ isOpen,
+}) {
+ return (
+
+ );
+}
+
+export default compose(withDialogRedux())(RuleFormDialog);
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx
new file mode 100644
index 000000000..4ad67f0b6
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx
@@ -0,0 +1,39 @@
+// @ts-nocheck
+import * as R from 'ramda';
+import { Button, Intent } from '@blueprintjs/core';
+import { EmptyStatus, Can, FormattedMessage as T } from '@/components';
+import { AbilitySubject, BankRuleAction } from '@/constants/abilityOption';
+import withDialogActions from '@/containers/Dialog/withDialogActions';
+
+function BankRulesLandingEmptyStateRoot({
+ // #withDialogAction
+ openDialog,
+}) {
+ return (
+
+ Setup the organization taxes to start tracking taxes on sales
+ transactions.
+
+ }
+ action={
+ <>
+
+
+
+
+ >
+ }
+ />
+ );
+}
+
+export const BankRulesLandingEmptyState = R.compose(withDialogActions)(
+ BankRulesLandingEmptyStateRoot,
+);
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx
new file mode 100644
index 000000000..8c35a99ae
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx
@@ -0,0 +1,20 @@
+// @ts-nocheck
+import { DashboardPageContent } from '@/components';
+import { RulesListBoot } from './RulesListBoot';
+import { RulesListActionsBar } from './RulesListActionsBar';
+import { BankRulesTable } from './RulesTable';
+
+/**
+ *
+ */
+export function RulesList() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx
new file mode 100644
index 000000000..2f538afef
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx
@@ -0,0 +1,10 @@
+import { DashboardActionsBar } from '@/components';
+import { NavbarGroup } from '@blueprintjs/core';
+
+export function RulesListActionsBar() {
+ return (
+
+
+
+ );
+}
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx
new file mode 100644
index 000000000..71035fd60
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx
@@ -0,0 +1,30 @@
+import React, { createContext } from 'react';
+import { DialogContent } from '@/components';
+
+interface RulesListBootValues {
+ rules: any;
+ isRulesLoading: boolean;
+}
+
+const RulesListBootContext = createContext(
+ {} as RulesListBootValues,
+);
+
+interface RulesListBootProps {
+ children: React.ReactNode;
+}
+
+function RulesListBoot({ ...props }: RulesListBootProps) {
+ const provider = {} as RulesListBootValues;
+
+ return (
+
+
+
+ );
+}
+
+const useRulesListBoot = () =>
+ React.useContext(RulesListBootContext);
+
+export { RulesListBoot, useRulesListBoot };
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx
new file mode 100644
index 000000000..966b86bc8
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx
@@ -0,0 +1,81 @@
+// @ts-nocheck
+import * as R from 'ramda';
+import {
+ DataTable,
+ DashboardContentTable,
+ TableSkeletonHeader,
+ TableSkeletonRows,
+} from '@/components';
+
+import withAlertsActions from '@/containers/Alert/withAlertActions';
+import withDrawerActions from '@/containers/Drawer/withDrawerActions';
+import withDialogActions from '@/containers/Dialog/withDialogActions';
+import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
+
+import { useBankRulesTableColumns } from './hooks';
+import { BankRulesTableActionsMenu } from './_components';
+import { BankRulesLandingEmptyState } from './BankRulesLandingEmptyState';
+
+/**
+ * Invoices datatable.
+ */
+function RulesTable({
+ // #withAlertsActions
+ openAlert,
+
+ // #withDrawerActions
+ openDrawer,
+
+ // #withDialogAction
+ openDialog,
+}) {
+ // Invoices table columns.
+ const columns = useBankRulesTableColumns();
+
+ // Handle edit bank rule.
+ const handleDeleteBankRule = ({ id }) => {};
+
+ // Handle delete bank rule.
+ const handleEditBankRule = () => {};
+
+ // Display invoice empty status instead of the table.
+ if (isEmptyStatus) {
+ return ;
+ }
+
+ return (
+
+
+
+ );
+}
+
+export const BankRulesTable = R.compose(
+ withDashboardActions,
+ withAlertsActions,
+ withDrawerActions,
+ withDialogActions,
+)(RulesTable);
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx
new file mode 100644
index 000000000..a33c86dde
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx
@@ -0,0 +1,38 @@
+// @ts-nocheck
+import React from 'react';
+import { Intent, Menu, MenuDivider, MenuItem } from '@blueprintjs/core';
+import { Can, Icon } from '@/components';
+import { AbilitySubject, BankRuleAction } from '@/constants/abilityOption';
+import { safeCallback } from '@/utils';
+
+/**
+ * Tax rates table actions menu.
+ * @returns {JSX.Element}
+ */
+export function BankRulesTableActionsMenu({
+ payload: { onEdit, onDelete },
+ row: { original },
+}) {
+ return (
+
+ );
+}
diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts b/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts
new file mode 100644
index 000000000..3ba4e2106
--- /dev/null
+++ b/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts
@@ -0,0 +1,3 @@
+export const useBankRulesTableColumns = () => {
+ return [];
+};
diff --git a/packages/webapp/src/routes/dashboard.tsx b/packages/webapp/src/routes/dashboard.tsx
index 8f1122bae..afd35824d 100644
--- a/packages/webapp/src/routes/dashboard.tsx
+++ b/packages/webapp/src/routes/dashboard.tsx
@@ -1221,6 +1221,14 @@ export const getDashboardRoutes = () => [
pageTitle: 'Tax Rates',
subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
},
+ // Bank Rules
+ {
+ path: '/bank-rules',
+ component: lazy(
+ () => import('@/containers/Banking/Rules/RulesList/RulesList'),
+ ),
+ pageTitle: 'Bank Rules',
+ },
// Homepage
{
path: `/`,