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,24 @@
import React from 'react';
import clsx from 'classnames';
import { Card } from 'components';
import CustomerDetailsActionsBar from './CustomerDetailsActionsBar';
import CustomerDetailsHeader from './CustomerDetailsHeader';
import Style from './CustomerDetailsDrawer.module.scss';
/**
* contact detail.
*/
export default function CustomerDetails() {
return (
<div className={clsx(Style.root)}>
<CustomerDetailsActionsBar />
<Card>
<CustomerDetailsHeader />
</Card>
</div>
);
}

View File

@@ -0,0 +1,130 @@
import React from 'react';
import intl from 'react-intl-universal';
import { useHistory } from 'react-router-dom';
import {
Button,
NavbarGroup,
Classes,
NavbarDivider,
Intent,
Position,
PopoverInteractionKind,
Popover,
Menu,
MenuItem,
} from '@blueprintjs/core';
import clsx from 'classnames';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import { useCustomerDetailsDrawerContext } from './CustomerDetailsDrawerProvider';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
import { Icon, FormattedMessage as T } from 'components';
import { compose } from 'utils';
/**
* Customer details actions bar.
*/
function CustomerDetailsActionsBar({
// #withAlertsActions
openAlert,
// #withDrawerActions
closeDrawer,
}) {
const { contact, customerId } = useCustomerDetailsDrawerContext();
const history = useHistory();
// Handle new invoice button click.
const handleNewInvoiceClick = () => {
history.push('invoices/new');
closeDrawer('customer-details-drawer');
};
// Handle new receipt button click.
const handleNewReceiptClick = () => {
history.push('receipts/new');
closeDrawer('customer-details-drawer');
};
// Handle new payment receive button click.
const handleNewPaymentClick = () => {
history.push('payment-receives/new');
closeDrawer('customer-details-drawer');
};
// Handle new estimate button click.
const handleNewEstimateClick = () => {
history.push('estimates/new');
closeDrawer('customer-details-drawer');
};
const handleDeleteCustomer = () => {
openAlert(`customer-delete`, { contactId: customerId });
closeDrawer('customer-details-drawer');
};
const handleEditContact = () => {
history.push(`/customers/${customerId}/edit`);
closeDrawer('customer-details-drawer');
};
return (
<DashboardActionsBar>
<NavbarGroup>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'customer.drawer.action.new_invoice'} />}
onClick={handleNewInvoiceClick}
/>
<MenuItem
text={<T id={'customer.drawer.action.new_estimate'} />}
onClick={handleNewEstimateClick}
/>
<MenuItem
text={<T id={'customer.drawer.action.new_receipt'} />}
onClick={handleNewReceiptClick}
/>
<MenuItem
text={<T id={'customer.drawer.action.new_payment'} />}
onClick={handleNewPaymentClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
className={clsx(Classes.MINIMAL)}
text={<T id={'customer.drawer.action.new_transaction'} />}
icon={<Icon icon={'plus'} />}
/>
</Popover>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pen-18" />}
text={intl.get('edit_contact', { name: contact?.contact_service })}
onClick={handleEditContact}
/>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={handleDeleteCustomer}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
export default compose(
withDrawerActions,
withAlertsActions,
)(CustomerDetailsActionsBar);

View File

@@ -0,0 +1,15 @@
.root {
&_content {
&_primary {
padding-bottom: 15px;
border-bottom: 1px solid #e2e2e2;
}
}
:global .card {
margin: 15px;
padding: 18px;
}
}

View File

@@ -0,0 +1,21 @@
import React from 'react';
import { DrawerBody } from 'components';
import CustomerDetails from './CustomerDetails';
import { CustomerDetailsDrawerProvider } from './CustomerDetailsDrawerProvider';
/**
* Contact detail drawer content.
*/
export default function CustomerDetailsDrawerContent({
// #ownProp
customerId,
}) {
return (
<CustomerDetailsDrawerProvider customerId={customerId}>
<DrawerBody>
<CustomerDetails />
</DrawerBody>
</CustomerDetailsDrawerProvider>
);
}

View File

@@ -0,0 +1,39 @@
import React from 'react';
import { DrawerHeaderContent, DrawerLoading } from 'components';
import { useCustomer } from 'hooks/query';
const ContactDetailDrawerContext = React.createContext();
/**
* Contact detail provider.
*/
function CustomerDetailsDrawerProvider({ customerId, ...props }) {
// Handle fetch customer details.
const { data: customer, isLoading: isCustomerLoading } = useCustomer(
customerId,
{
enabled: !!customerId,
},
);
// Provider.
const provider = {
customer,
customerId,
isCustomerLoading,
};
return (
<DrawerLoading loading={isCustomerLoading}>
<DrawerHeaderContent
name="customer-details-drawer"
title={customer?.display_name}
/>
<ContactDetailDrawerContext.Provider value={provider} {...props} />
</DrawerLoading>
);
}
const useCustomerDetailsDrawerContext = () =>
React.useContext(ContactDetailDrawerContext);
export { CustomerDetailsDrawerProvider, useCustomerDetailsDrawerContext };

View File

@@ -0,0 +1,79 @@
import React from 'react';
import intl from 'react-intl-universal';
import clsx from 'classnames';
import { defaultTo } from 'lodash';
import { DetailsMenu, DetailItem, T } from 'components';
import { useCustomerDetailsDrawerContext } from './CustomerDetailsDrawerProvider';
import Style from './CustomerDetailsDrawer.module.scss';
/**
* Customer details header.
*/
export default function CustomerDetailsHeader() {
const { customer } = useCustomerDetailsDrawerContext();
return (
<div className={clsx(Style.root_content)}>
<DetailsMenu
direction={'vertical'}
className={clsx(Style.root_content_primary)}
>
<DetailItem
name={'outstanding-receivable'}
label={<T id={'customer.drawer.label.outstanding_receivable'} />}
>
<h3 class="big-number">{customer.formatted_balance}</h3>
</DetailItem>
<DetailItem
label={<T id={'customer.drawer.label.customer_name'} />}
name={'name'}
children={customer?.display_name}
/>
<DetailItem
label={<T id={'customer.drawer.label.customer_type'} />}
name={'type'}
children={customer?.customer_type}
/>
<DetailItem label={<T id={'customer.drawer.label.unused_credits'} />}>
0
</DetailItem>
</DetailsMenu>
<DetailsMenu direction={'horizantal'} minLabelSize={'175px'}>
<DetailItem
label={<T id={'customer.drawer.label.company_name'} />}
children={defaultTo(customer?.company_name, '--')}
/>
<DetailItem
label={<T id={'customer.drawer.label.email'} />}
children={defaultTo(customer?.email, '--')}
/>
<DetailItem label={<T id={'customer.drawer.label.phone_number'} />}>
<div>{customer?.personal_phone} </div>
<div>{customer?.work_phone} </div>
</DetailItem>
<DetailItem
label={<T id={'customer.drawer.label.website'} />}
children={defaultTo(customer?.website, '--')}
/>
<DetailItem
label={<T id={'customer.drawer.label.opening_balance'} />}
children={customer?.formatted_opening_balance}
/>
<DetailItem
label={<T id={'customer.drawer.label.opening_balance_at'} />}
children={customer?.formatted_opening_balance_at}
/>
<DetailItem
label={<T id={'customer.drawer.label.currency'} />}
children={customer?.currency_code}
/>
</DetailsMenu>
</div>
);
}

View File

@@ -0,0 +1,30 @@
import React from 'react';
import { Drawer, DrawerSuspense } from 'components';
import withDrawers from 'containers/Drawer/withDrawers';
import { compose } from 'utils';
const CustomerDetailsDrawerContent = React.lazy(() =>
import('./CustomerDetailsDrawerContent'),
);
/**
* Contact detail drawer.
*/
function CustomerDetailsDrawer({
name,
// #withDrawer
isOpen,
payload: { customerId },
}) {
return (
<Drawer isOpen={isOpen} name={name} size={'750px'}>
<DrawerSuspense>
<CustomerDetailsDrawerContent customerId={customerId} />
</DrawerSuspense>
</Drawer>
);
}
export default compose(withDrawers())(CustomerDetailsDrawer);