diff --git a/src/components/ExchangeRate/ExchangeRateInput.js b/src/components/ExchangeRate/ExchangeRateInput.js
new file mode 100644
index 000000000..cc3e4b9ae
--- /dev/null
+++ b/src/components/ExchangeRate/ExchangeRateInput.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import styled from 'styled-components';
+import { ControlGroup } from '@blueprintjs/core';
+
+import { FlagTag } from '../Tags';
+import { FMoneyInputGroup, FFormGroup } from '../Forms';
+
+export function ExchangeRateInputGroup({
+ fromCurrency,
+ toCurrency,
+ inputGroupProps,
+ formGroupProps,
+ name,
+}) {
+ return (
+
+
+
+ 1 {fromCurrency} =
+
+
+
+ {toCurrency}
+
+
+
+ );
+}
+
+const ExchangeRateField = styled(FMoneyInputGroup)`
+ max-width: 88px;
+`;
+
+const ExchangeRateSideIcon = styled.div`
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+ line-height: 1;
+`;
+
+const ExchangeRatePrepend = styled(ExchangeRateSideIcon)`
+ padding-right: 8px;
+`;
+
+const ExchangeRateAppend = styled(ExchangeRateSideIcon)`
+ padding-left: 8px;
+`;
diff --git a/src/components/ExchangeRate/index.js b/src/components/ExchangeRate/index.js
new file mode 100644
index 000000000..ea982a466
--- /dev/null
+++ b/src/components/ExchangeRate/index.js
@@ -0,0 +1 @@
+export * from './ExchangeRateInput';
\ No newline at end of file
diff --git a/src/components/Forms/FFormGroup.tsx b/src/components/Forms/FFormGroup.tsx
new file mode 100644
index 000000000..633ebec99
--- /dev/null
+++ b/src/components/Forms/FFormGroup.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import { FieldMetaProps, FieldInputProps, useField } from 'formik';
+import {
+ FormGroup as PBFormGroup,
+ Intent,
+ FormGroupProps as PBFormGroupProps,
+} from '@blueprintjs/core';
+
+export interface FormGroupProps extends PBFormGroupProps {
+ name: string;
+ children: React.ReactElement;
+}
+
+/**
+ * Transformes field props to form group.
+ * @param {Omit} props
+ * @param {FieldInputProps} field
+ * @param {FieldMetaProps} meta
+ * @returns {PBFormGroupProps}
+ */
+const fieldToFormGroup = (
+ props: Omit,
+ field: FieldInputProps,
+ meta: FieldMetaProps
+): PBFormGroupProps => {
+ const showError = meta.touched && meta.error;
+
+ return {
+ intent: showError ? Intent.DANGER : Intent.NONE,
+ helperText: showError ? meta.error : '',
+ ...props,
+ };
+};
+
+/**
+ * Form group.
+ * @param {FormGroupProps}
+ * @returns {React.JSX}
+ */
+export function FFormGroup({ children, ...props }: FormGroupProps): JSX.Element {
+ const [field, meta] = useField(props.name);
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/Forms/FMoneyInputGroup.js b/src/components/Forms/FMoneyInputGroup.js
new file mode 100644
index 000000000..2bc69fd35
--- /dev/null
+++ b/src/components/Forms/FMoneyInputGroup.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import { Intent } from '@blueprintjs/core';
+import { Field, getIn } from 'formik';
+import { CurrencyInput } from './MoneyInputGroup';
+
+const fieldToMoneyInputGroup = ({
+ field: { onBlur: onFieldBlur, ...field },
+ form: { setFieldValue, touched, errors },
+ onBlur,
+ ...props
+}) => {
+ const fieldError = getIn(errors, field.name);
+ const showError = getIn(touched, field.name) && !!fieldError;
+
+ return {
+ intent: showError ? Intent.DANGER : Intent.NONE,
+ onBlurValue:
+ onBlur ??
+ function (e) {
+ onFieldBlur(e ?? field.name);
+ },
+ ...field,
+ onChange: (value) => {
+ setFieldValue(field.name, value);
+ },
+ ...props,
+ };
+};
+
+function FieldToMoneyInputGroup({ ...props }) {
+ return ;
+}
+
+export function FMoneyInputGroup({ ...props }) {
+ return ;
+}
diff --git a/src/components/Forms/index.js b/src/components/Forms/index.js
index c531c474b..c6221811d 100644
--- a/src/components/Forms/index.js
+++ b/src/components/Forms/index.js
@@ -1,2 +1,4 @@
export * from './FormObserver';
-export * from './FormikObserver';
\ No newline at end of file
+export * from './FormikObserver';
+export * from './FMoneyInputGroup'
+export * from './FFormGroup'
\ No newline at end of file
diff --git a/src/components/index.js b/src/components/index.js
index 08c1b44ff..bb40a47ed 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -98,7 +98,7 @@ export * from './FinancialStatement';
export * from './FinancialReport';
export * from './FinancialSheet';
export * from './FeatureGuard';
-
+export * from './ExchangeRate'
const Hint = FieldHint;
const T = FormattedMessage;
diff --git a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
index 4193487bb..86eda3909 100644
--- a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
+++ b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
@@ -110,7 +110,6 @@ export default function CustomerFinancialPanel() {
onCurrencySelected={(currency) => {
form.setFieldValue('currency_code', currency.currency_code);
}}
- disabled={true}
/>
)}
diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js
index b9eb52470..760ffcab2 100644
--- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js
+++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.js
@@ -9,7 +9,6 @@ import { DateInput } from '@blueprintjs/datetime';
import { FastField, Field, ErrorMessage } from 'formik';
import { FormattedMessage as T, Col, Row, If } from 'components';
import { momentFormatter, compose, tansformDateValue } from 'utils';
-import { upperCase } from 'lodash';
import classNames from 'classnames';
import styled from 'styled-components';
@@ -25,8 +24,7 @@ import {
ListSelect,
Icon,
InputPrependButton,
- MoneyInputGroup,
- FlagTag,
+ ExchangeRateInputGroup,
} from 'components';
import { useInvoiceFormContext } from './InvoiceFormProvider';
@@ -121,42 +119,14 @@ function InvoiceFormHeaderFields({
)}
- {/* ----------- Exchange reate ----------- */}
-
-
-
- {({
- form: { values, setFieldValue },
- field,
- meta: { error, touched },
- }) => (
- }
- >
-
-
- 1 USD =
-
- {
- setFieldValue('exchange_rate', value);
- }}
- intent={inputIntent({ error, touched })}
- />
-
- LYD
-
-
-
- )}
-
-
+ {/* ----------- Exchange rate ----------- */}
+
+
@@ -309,25 +279,6 @@ export default compose(
})),
)(InvoiceFormHeaderFields);
-const ExchangeRateField = styled.div`
- display: flex;
- justify-content: flex-end;
- align-items: center;
- max-width: 366px;
- .bp3-input-group .bp3-input {
- width: 88px;
- margin: 0 5px;
- }
-`;
-
-const ExchangeRateTag = styled.div`
- display: flex;
- align-items: center;
- cursor: pointer;
- font-size: 10px;
- line-height: 1.6;
-`;
-
const ControlCustomerGroup = styled(ControlGroup)`
display: flex;
align-items: center;