diff --git a/client/src/components/DialogsContainer.js b/client/src/components/DialogsContainer.js index a9aa24ff0..19d8e021b 100644 --- a/client/src/components/DialogsContainer.js +++ b/client/src/components/DialogsContainer.js @@ -15,6 +15,8 @@ import QuickPaymentReceiveFormDialog from 'containers/Dialogs/QuickPaymentReceiv import QuickPaymentMadeFormDialog from 'containers/Dialogs/QuickPaymentMadeFormDialog'; import AllocateLandedCostDialog from 'containers/Dialogs/AllocateLandedCostDialog'; import InvoicePdfPreviewDialog from 'containers/Dialogs/InvoicePdfPreviewDialog'; +import EstimatePdfPreviewDialog from 'containers/Dialogs/EstimatePdfPreviewDialog'; +import ReceiptPdfPreviewDialog from '../containers/Dialogs/ReceiptPdfPreviewDialog'; /** * Dialogs container. @@ -35,7 +37,9 @@ export default function DialogsContainer() { - + + + ); } diff --git a/client/src/components/DrawersContainer.js b/client/src/components/DrawersContainer.js index 723fbfeab..acc556105 100644 --- a/client/src/components/DrawersContainer.js +++ b/client/src/components/DrawersContainer.js @@ -11,6 +11,7 @@ import InvoiceDetailDrawer from 'containers/Drawers/InvoiceDetailDrawer'; import ReceiptDetailDrawer from 'containers/Drawers/ReceiptDetailDrawer'; import PaymentReceiveDetailDrawer from 'containers/Drawers/PaymentReceiveDetailDrawer'; import PaymentMadeDetailDrawer from 'containers/Drawers/PaymentMadeDetailDrawer'; +import EstimateDetailDrawer from '../containers/Drawers/EstimateDetailDrawer'; export default function DrawersContainer() { return ( @@ -24,6 +25,7 @@ export default function DrawersContainer() { + diff --git a/client/src/containers/Dialogs/EstimatePdfPreviewDialog/EstimatePdfPreviewDialogContent.js b/client/src/containers/Dialogs/EstimatePdfPreviewDialog/EstimatePdfPreviewDialogContent.js new file mode 100644 index 000000000..f242d198b --- /dev/null +++ b/client/src/containers/Dialogs/EstimatePdfPreviewDialog/EstimatePdfPreviewDialogContent.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { AnchorButton } from '@blueprintjs/core'; + +import { DialogContent, PdfDocumentPreview, T } from 'components'; +import { usePdfEstimate } from 'hooks/query'; + +import withDialogActions from 'containers/Dialog/withDialogActions'; +import { compose } from 'utils'; + +function EstimatePdfPreviewDialogContent({ + subscriptionForm: { estimateId }, + dialogName, + // #withDialogActions + closeDialog, +}) { + const { isLoading, pdfUrl } = usePdfEstimate(estimateId); + + return ( + +
+ + + + + + + +
+ + +
+ ); +} + +export default compose(withDialogActions)(EstimatePdfPreviewDialogContent); diff --git a/client/src/containers/Dialogs/EstimatePdfPreviewDialog/index.js b/client/src/containers/Dialogs/EstimatePdfPreviewDialog/index.js new file mode 100644 index 000000000..1646222e9 --- /dev/null +++ b/client/src/containers/Dialogs/EstimatePdfPreviewDialog/index.js @@ -0,0 +1,44 @@ +import React from 'react'; +import classNames from 'classnames'; + +import { T, Dialog, DialogSuspense } from 'components'; +import { CLASSES } from 'common/classes'; + +import withDialogRedux from 'components/DialogReduxConnect'; + +import { compose } from 'utils'; + +// Lazy loading the content. +const PdfPreviewDialogContent = React.lazy(() => + import('./EstimatePdfPreviewDialogContent'), +); + +/** + * Estimate PDF preview dialog. + */ +function EstimatePdfPreviewDialog({ + dialogName, + payload = { estimateId: null }, + isOpen, +}) { + return ( + } + className={classNames(CLASSES.DIALOG_PDF_PREVIEW)} + autoFocus={true} + canEscapeKeyClose={true} + isOpen={isOpen} + style={{ width: '1000px' }} + > + + + + + ); +} + +export default compose(withDialogRedux())(EstimatePdfPreviewDialog); diff --git a/client/src/containers/Dialogs/InvoicePdfPreviewDialog/InvoicePdfPreviewDialogContent.js b/client/src/containers/Dialogs/InvoicePdfPreviewDialog/InvoicePdfPreviewDialogContent.js index 3dfe4e3fa..04d37e66f 100644 --- a/client/src/containers/Dialogs/InvoicePdfPreviewDialog/InvoicePdfPreviewDialogContent.js +++ b/client/src/containers/Dialogs/InvoicePdfPreviewDialog/InvoicePdfPreviewDialogContent.js @@ -8,17 +8,18 @@ import withDialogActions from 'containers/Dialog/withDialogActions'; import { compose } from 'utils'; function InvoicePdfPreviewDialogContent({ + subscriptionForm: { invoiceId }, // #withDialog closeDialog, }) { - const { isLoading, pdfUrl } = usePdfInvoice(1); + const { isLoading, pdfUrl } = usePdfInvoice(invoiceId); return (
@@ -27,7 +28,7 @@ function InvoicePdfPreviewDialogContent({ @@ -45,4 +46,4 @@ function InvoicePdfPreviewDialogContent({ ); } -export default compose(withDialogActions)(InvoicePdfPreviewDialogContent); \ No newline at end of file +export default compose(withDialogActions)(InvoicePdfPreviewDialogContent); diff --git a/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/ReceiptPdfPreviewDialogContent.js b/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/ReceiptPdfPreviewDialogContent.js new file mode 100644 index 000000000..1a66eb9cf --- /dev/null +++ b/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/ReceiptPdfPreviewDialogContent.js @@ -0,0 +1,49 @@ +import React from 'react'; +import { AnchorButton } from '@blueprintjs/core'; + +import { DialogContent, PdfDocumentPreview, T } from 'components'; +import { usePdfReceipt } from 'hooks/query'; + +import withDialogActions from 'containers/Dialog/withDialogActions'; +import { compose } from 'utils'; + +function ReceiptPdfPreviewDialogContent({ + subscriptionForm: { receiptId }, + // #withDialogActions + closeDialog, +}) { + const { isLoading, pdfUrl } = usePdfReceipt(receiptId); + + return ( + +
+ + + + + + + +
+ + +
+ ); +} + +export default compose(withDialogActions)(ReceiptPdfPreviewDialogContent); diff --git a/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/index.js b/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/index.js new file mode 100644 index 000000000..2dc894e65 --- /dev/null +++ b/client/src/containers/Dialogs/ReceiptPdfPreviewDialog/index.js @@ -0,0 +1,43 @@ +import React from 'react'; +import classNames from 'classnames'; + +import { T, Dialog, DialogSuspense } from 'components'; +import { CLASSES } from 'common/classes'; + +import withDialogRedux from 'components/DialogReduxConnect'; + +import { compose } from 'utils'; + +// Lazy loading the content. +const PdfPreviewDialogContent = React.lazy(() => + import('./ReceiptPdfPreviewDialogContent'), +); + +/** + * Receipt Pdf preview dialog. + */ +function ReceiptPdfPreviewDialog({ + dialogName, + payload = { receiptId: null }, + isOpen, +}) { + return ( + } + className={classNames(CLASSES.DIALOG_PDF_PREVIEW)} + autoFocus={true} + canEscapeKeyClose={true} + isOpen={isOpen} + style={{ width: '1000px' }} + > + + + + + ); +} +export default compose(withDialogRedux())(ReceiptPdfPreviewDialog); diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js new file mode 100644 index 000000000..eceb2f2bb --- /dev/null +++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js @@ -0,0 +1,21 @@ +import React from 'react'; +import { Tabs, Tab } from '@blueprintjs/core'; +import intl from 'react-intl-universal'; +import EstimateDetailTab from './EstimateDetailTab'; + +/** + * Estimate view detail + */ +export default function EstimateDetail() { + return ( +
+ + } + /> + +
+ ); +} diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js new file mode 100644 index 000000000..6a08ede8b --- /dev/null +++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js @@ -0,0 +1,20 @@ +import React from 'react'; + +import 'style/components/Drawers/ViewDetail/ViewDetail.scss'; + +import EstimateDetail from './EstimateDetail'; +import { EstimateDetailDrawerProvider } from './EstimateDetailDrawerProvider'; + +/** + * Estimate detail drawer content. + */ +export default function EstimateDetailDrawerContent({ + // #ownProp + estimate, +}) { + return ( + + + + ); +} diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js new file mode 100644 index 000000000..f5caf34c2 --- /dev/null +++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js @@ -0,0 +1,30 @@ +import React from 'react'; +import intl from 'react-intl-universal'; +import { DrawerHeaderContent, DashboardInsider } from 'components'; + +const EstimateDetailDrawerContext = React.createContext(); + +/** + * Estimate detail provider. + */ +function EstimateDetailDrawerProvider({ estimateId, ...props }) { + const provider = { + estimateId, + }; + + return ( + + + + + + ); +} + +const useEstimateDetailDrawerContext = () => + React.useContext(EstimateDetailDrawerContext); + +export { EstimateDetailDrawerProvider, useEstimateDetailDrawerContext }; diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js new file mode 100644 index 000000000..2de289201 --- /dev/null +++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js @@ -0,0 +1,89 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; + +import { + Button, + NavbarGroup, + Classes, + NavbarDivider, + Intent, +} from '@blueprintjs/core'; +import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; +import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider'; + +import withDialogActions from 'containers/Dialog/withDialogActions'; +import withAlertsActions from 'containers/Alert/withAlertActions'; +import withDrawerActions from 'containers/Drawer/withDrawerActions'; + +import { Icon, FormattedMessage as T } from 'components'; + +import { safeCallback, compose } from 'utils'; + +function EstimateDetailTab({ + // #withDialogActions + openDialog, + + // #withAlertsActions + openAlert, + + // #withDrawerActions + closeDrawer, +}) { + const history = useHistory(); + + const { estimateId } = useEstimateDetailDrawerContext(); + + // Handle edit sale estimate. + const onEditEstimate = () => { + return estimateId + ? (history.push(`/estimates/${estimateId}/edit`), + closeDrawer('estimate-detail-drawer')) + : null; + }; + + // Handle delete sale estimate. + const onDeleteEstimate = () => { + return estimateId + ? (openAlert('estimate-delete', { estimateId }), + closeDrawer('estimate-detail-drawer')) + : null; + }; + + // Handle print estimate. + const onPrintEstimate = () => { + openDialog('estimate-pdf-preview', { estimateId }); + }; + + return ( + + +