chrone: sperate client and server to different repos.

This commit is contained in:
a.bouhuolia
2021-09-21 17:13:53 +02:00
parent e011b2a82b
commit 18df5530c7
10015 changed files with 17686 additions and 97524 deletions

View File

@@ -0,0 +1,69 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
import Icon from 'components/Icon';
import {
Button,
Classes,
NavbarGroup,
Intent,
NavbarDivider,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
import { compose } from 'utils';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
/**
* Expense drawer action bar.
*/
function ExpenseDrawerActionBar({
// #withAlertsDialog
openAlert,
// #withDrawerActions
closeDrawer,
}) {
const history = useHistory();
const { expense } = useExpenseDrawerContext();
// Handle the expense edit action.
const handleEditExpense = () => {
history.push(`/expenses/${expense.id}/edit`);
closeDrawer('expense-drawer');
};
// Handle the expense delete action.
const handleDeleteExpense = () => {
openAlert('expense-delete', { expenseId: expense.id });
};
return (
<DashboardActionsBar>
<NavbarGroup>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pen-18" />}
text={<T id={'edit_expense'} />}
onClick={handleEditExpense}
/>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={handleDeleteExpense}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
export default compose(
withAlertsActions,
withDrawerActions,
)(ExpenseDrawerActionBar);

View File

@@ -0,0 +1,24 @@
import React from 'react';
import { DrawerBody } from 'components';
import 'style/components/Drawers/ExpenseDrawer.scss';
import { ExpenseDrawerProvider } from './ExpenseDrawerProvider';
import ExpenseDrawerDetails from './ExpenseDrawerDetails';
/**
* Expense drawer content.
*/
export default function ExpenseDrawerContent({
// #ownProp
expenseId,
}) {
return (
<ExpenseDrawerProvider expenseId={expenseId}>
<DrawerBody>
<ExpenseDrawerDetails />
</DrawerBody>
</ExpenseDrawerProvider>
);
}

View File

@@ -0,0 +1,27 @@
import React from 'react';
import { Card } from 'components';
import ExpenseDrawerActionBar from './ExpenseDrawerActionBar';
import ExpenseDrawerHeader from './ExpenseDrawerHeader';
import ExpenseDrawerTable from './ExpenseDrawerTable';
import ExpenseDrawerFooter from './ExpenseDrawerFooter';
/**
* Expense view details.
*/
export default function ExpenseDrawerDetails() {
return (
<div className={'expense-drawer'}>
<ExpenseDrawerActionBar />
<div className="expense-drawer__content">
<Card>
<ExpenseDrawerHeader />
<ExpenseDrawerTable />
<ExpenseDrawerFooter />
</Card>
</div>
</div>
);
}

View File

@@ -0,0 +1,33 @@
import React from 'react';
import { T } from 'components';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
import { FormatNumber } from '../../../components';
/**
* Footer details of expense readonly details.
*/
export default function ExpenseDrawerFooter() {
const { expense } = useExpenseDrawerContext();
return (
<div className="expense-drawer__content-footer">
<div class="total-lines">
<div class="total-lines__line total-lines__line--subtotal">
<div class="title">
<T id={'expense.details.subtotal'} />
</div>
<div class="amount">
{<FormatNumber value={expense.total_amount} />}
</div>
</div>
<div class="total-lines__line total-lines__line--total">
<div class="title">
<T id={'expense.details.total'} />
</div>
<div class="amount">{expense.formatted_amount}</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,58 @@
import React from 'react';
import moment from 'moment';
import { defaultTo } from 'lodash';
import { DetailItem, DetailsMenu, Money } from 'components';
import { FormattedMessage as T } from 'components';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
/**
* Expense drawer content.
*/
export default function ExpenseDrawerHeader() {
const {
expense: {
total_amount,
payment_date,
currency_code,
reference_no,
description,
published_at,
},
} = useExpenseDrawerContext();
return (
<div className={'expense-drawer__content-header'}>
<DetailsMenu>
<DetailItem name={'amount'} label={<T id={'full_amount'} />}>
<h3 class="big-number">
<Money amount={total_amount} currency={currency_code} />
</h3>
</DetailItem>
<DetailItem name={'date'} label={<T id={'date'} />}>
{moment(payment_date).format('YYYY MMM DD')}
</DetailItem>
<DetailItem name={'currency'} label={<T id={'currency'} />}>
{currency_code}
</DetailItem>
<DetailItem name={'reference'} label={<T id={'reference_no'} />}>
{defaultTo(reference_no, '-')}
</DetailItem>
<DetailItem label={<T id={'published_at'} />}>
{moment(published_at).format('YYYY MMM DD')}
</DetailItem>
</DetailsMenu>
<DetailsMenu direction={'horizantal'}>
<DetailItem label={<T id={'description'} />}>
{defaultTo(description, '—')}
</DetailItem>
<DetailItem label={<T id={'created_at'} />}>2021 Aug 24</DetailItem>
</DetailsMenu>
</div>
);
}

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { useExpense } from 'hooks/query';
import { DrawerLoading } from 'components';
const ExpenseDrawerDrawerContext = React.createContext();
/**
* Expense drawer provider.
*/
function ExpenseDrawerProvider({ expenseId, ...props }) {
// Fetch the expense details.
const {
data: expense,
isLoading: isExpenseLoading,
isFetching: isExpenseFetching,
} = useExpense(expenseId, {
enabled: !!expenseId,
});
// Provider.
const provider = {
expenseId,
expense,
isExpenseFetching,
isExpenseLoading,
};
return (
<DrawerLoading loading={isExpenseLoading}>
<ExpenseDrawerDrawerContext.Provider value={provider} {...props} />
</DrawerLoading>
);
}
const useExpenseDrawerContext = () =>
React.useContext(ExpenseDrawerDrawerContext);
export { ExpenseDrawerProvider, useExpenseDrawerContext };

View File

@@ -0,0 +1,18 @@
import React from 'react';
import { DataTable } from 'components';
import { useExpenseReadEntriesColumns } from './utils';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
/**
* Expense details table.
*/
export default function ExpenseDrawerTable() {
const columns = useExpenseReadEntriesColumns();
const { expense } = useExpenseDrawerContext();
return (
<div className="expense-drawer__content--table">
<DataTable columns={columns} data={expense.categories} />
</div>
);
}

View File

@@ -0,0 +1,36 @@
import React, { lazy } from 'react';
import intl from 'react-intl-universal';
import { Drawer, DrawerSuspense } from 'components';
import withDrawers from 'containers/Drawer/withDrawers';
import { compose } from 'utils';
const ExpenseDrawerContent = lazy(() => import('./ExpenseDrawerContent'));
/**
* Expense drawer.
*/
function ExpenseDrawer({
name,
// #withDrawer
isOpen,
payload: { expenseId },
}) {
return (
<Drawer
isOpen={isOpen}
name={name}
title={intl.get('expense')}
size={'65%'}
style={{ minWidth: '700px', maxWidth: '900px' }}
>
<DrawerSuspense>
<ExpenseDrawerContent expenseId={expenseId} />
</DrawerSuspense>
</Drawer>
);
}
export default compose(withDrawers())(ExpenseDrawer);

View File

@@ -0,0 +1,37 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
/**
* Retrieve expense readonly details entries table columns.
*/
export const useExpenseReadEntriesColumns = () =>
React.useMemo(
() => [
{
Header: intl.get('expense_account'),
accessor: 'expense_account.name',
width: 110,
disableSortBy: true,
className: 'account',
},
{
Header: intl.get('description'),
accessor: 'description',
width: 110,
disableSortBy: true,
className: 'description',
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
disableSortBy: true,
className: 'amount',
align: 'right',
},
],
[],
);