feat: categorize cashflow transaction drawer

This commit is contained in:
Ahmed Bouhuolia
2024-03-05 22:27:42 +02:00
parent db839137d0
commit a17b4f6a8a
16 changed files with 402 additions and 2 deletions

View File

@@ -11,6 +11,15 @@ const Root = styled.div`
const FilterTag = styled(Tag)`
min-height: 26px;
&.bp4-minimal:not([class*='bp4-intent-']) {
background: #fff;
border: 1px solid #e1e2e8;
&.bp4-interactive:hover {
background-color: rgba(143, 153, 168, 0.05);
}
}
`;
export function AccountTransactionsUncategorizeFilter() {

View File

@@ -25,6 +25,7 @@ import { useAccountTransactionsContext } from './AccountTransactionsProvider';
import { handleCashFlowTransactionType } from './utils';
import { compose } from '@/utils';
import { DRAWERS } from '@/constants/drawers';
/**
* Account transactions data table.
@@ -56,7 +57,11 @@ function AccountTransactionsDataTable({
const handleViewDetailCashflowTransaction = (referenceType) => {};
// Handle cell click.
const handleCellClick = (cell, event) => {};
const handleCellClick = (cell, event) => {
openDrawer(DRAWERS.CATEGORIZE_TRANSACTION, {
uncategorizedTransactionId: cell.row.original.id,
});
};
return (
<CashflowTransactionsTable
@@ -132,7 +137,7 @@ const CashflowTransactionsTable = styled(DashboardConstrantTable)`
}
.td-description {
color: #5F6B7C;
color: #5f6b7c;
}
}
}

View File

@@ -0,0 +1,38 @@
// @ts-nocheck
import React from 'react';
import { DrawerHeaderContent, DrawerLoading } from '@/components';
import { DRAWERS } from '@/constants/drawers';
import { useUncategorizedTransaction } from '@/hooks/query';
const CategorizeTransactionBootContext = React.createContext();
/**
* Estimate detail provider.
*/
function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
const {
data: uncategorizedTransaction,
isLoading: isUncategorizedTransactionLoading,
} = useUncategorizedTransaction(uncategorizedTransactionId);
const provider = {
uncategorizedTransaction,
isUncategorizedTransactionLoading,
};
return (
<DrawerLoading loading={isUncategorizedTransactionLoading}>
<DrawerHeaderContent
name={DRAWERS.CATEGORIZE_TRANSACTION}
title={'Categorize Transaction'}
subTitle={''}
/>
<CategorizeTransactionBootContext.Provider value={provider} {...props} />
</DrawerLoading>
);
}
const useCategorizeTransactionBoot = () =>
React.useContext(CategorizeTransactionBootContext);
export { CategorizeTransactionBoot, useCategorizeTransactionBoot };

View File

@@ -0,0 +1,18 @@
// @ts-nocheck
import { DrawerBody } from '@/components';
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
export default function CategorizeTransactionContent({
uncategorizedTransactionId,
}) {
return (
<CategorizeTransactionBoot
uncategorizedTransactionId={uncategorizedTransactionId}
>
<DrawerBody>
<CategorizeTransactionForm />
</DrawerBody>
</CategorizeTransactionBoot>
);
}

View File

@@ -0,0 +1,37 @@
// @ts-nocheck
import React, { lazy } from 'react';
import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers';
import { compose } from '@/utils';
const CategorizeTransactionContent = lazy(
() => import('./CategorizeTransactionContent'),
);
/**
* Categorize the uncategorized transaction drawer.
*/
function CategorizeTransactionDrawer({
name,
// #withDrawer
isOpen,
payload: { uncategorizedTransactionId },
}) {
return (
<Drawer
isOpen={isOpen}
name={name}
style={{ minWidth: '480px', maxWidth: '600px' }}
size={'40%'}
>
<DrawerSuspense>
<CategorizeTransactionContent
uncategorizedTransactionId={uncategorizedTransactionId}
/>
</DrawerSuspense>
</Drawer>
);
}
export default compose(withDrawers())(CategorizeTransactionDrawer);

View File

@@ -0,0 +1,7 @@
// @ts-nocheck
import * as Yup from 'yup';
const Schema = Yup.object().shape({});
export const CreateCategorizeTransactionSchema = Schema;
export const EditCategorizeTransactionSchema = Schema;

View File

@@ -0,0 +1,59 @@
// @ts-nocheck
import { Formik, Form } from 'formik';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import {
EditCategorizeTransactionSchema,
CreateCategorizeTransactionSchema,
} from './CategorizeTransactionForm.schema';
import { compose, transformToForm } from '@/utils';
import { CategorizeTransactionFormContent } from './CategorizeTransactionFormContent';
import { CategorizeTransactionFormFooter } from './CategorizeTransactionFormFooter';
// Default initial form values.
const defaultInitialValues = {};
/**
* Categorize cashflow transaction form dialog content.
*/
function CategorizeTransactionFormRoot({
// #withDialogActions
closeDialog,
}) {
const isNewMode = true;
// Form validation schema in create and edit mode.
const validationSchema = isNewMode
? CreateCategorizeTransactionSchema
: EditCategorizeTransactionSchema;
// Callbacks handles form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {};
// Form initial values in create and edit mode.
const initialValues = {
...defaultInitialValues,
/**
* We only care about the fields in the form. Previously unfilled optional
* values such as `notes` come back from the API as null, so remove those
* as well.
*/
...transformToForm({}, defaultInitialValues),
};
return (
<Formik
validationSchema={validationSchema}
initialValues={initialValues}
onSubmit={handleFormSubmit}
>
<Form>
<CategorizeTransactionFormContent />
<CategorizeTransactionFormFooter />
</Form>
</Formik>
);
}
export const CategorizeTransactionForm = compose(withDialogActions)(
CategorizeTransactionFormRoot,
);

View File

@@ -0,0 +1,90 @@
// @ts-nocheck
import { Position } from '@blueprintjs/core';
import styled from 'styled-components';
import {
AccountsSelect,
FDateInput,
FFormGroup,
FInputGroup,
FSelect,
FSuggest,
FTextArea,
} from '@/components';
import { getAddMoneyInOptions } from '@/constants';
// Retrieves the add money in button options.
const AddMoneyInOptions = getAddMoneyInOptions();
const Title = styled('h3')``;
export function CategorizeTransactionFormContent() {
return (
<>
<Title>$22,583.00</Title>
<FFormGroup name={'category'} label={'Category'} fastField inline>
<FSuggest
name={'transaction_type'}
items={AddMoneyInOptions}
popoverProps={{ minimal: true }}
valueAccessor={'value'}
textAccessor={'name'}
fill
/>
</FFormGroup>
<FFormGroup name={'date'} label={'Date'} fastField inline>
<FDateInput
name={'date'}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
formatDate={(date) => date.toLocaleDateString()}
parseDate={(str) => new Date(str)}
inputProps={{ fill: true }}
/>
</FFormGroup>
<FFormGroup
name={'from_account_id'}
label={'From Account'}
fastField={true}
inline
>
<AccountsSelect
name={'from_account_id'}
items={[]}
fastField={true}
fill={true}
allowCreate={true}
/>
</FFormGroup>
<FFormGroup
name={'toAccountId'}
label={'To Account'}
fastField={true}
inline
>
<AccountsSelect
name={'to_account_id'}
items={[]}
fastField={true}
fill={true}
allowCreate={true}
/>
</FFormGroup>
<FFormGroup name={'referenceNo'} label={'Reference No.'} fastField inline>
<FInputGroup name={'reference_no'} fill />
</FFormGroup>
<FFormGroup name={'description'} label={'Description'} fastField inline>
<FTextArea
name={'description'}
growVertically={true}
large={true}
fill={true}
/>
</FFormGroup>
</>
);
}

View File

@@ -0,0 +1,26 @@
import { Button, Classes, Intent } from '@blueprintjs/core';
export function CategorizeTransactionFormFooter() {
return (
<div>
<div className={Classes.DRAWER_FOOTER}>
<Button
intent={Intent.PRIMARY}
// loading={isSubmitting}
style={{ minWidth: '85px' }}
type="submit"
>
Save
</Button>
<Button
// disabled={isSubmitting}
// onClick={onClose}
style={{ minWidth: '75px' }}
>
Close
</Button>
</div>
</div>
);
}