-
+
+
+
{
return (
-
+
{
id="SELECT_RECIPIENT"
defaultMessage="select recipient"
children={placeholder => (
- {
-
- props.startCreatingTransaction(props.userId, { amount: props.value })
+ startCreatingTransaction(store.dispatch, props.userId, {
+ amount: props.value,
+ })
}
type="button"
- disabled={props.disabled}
+ disabled={!isValid}
>
);
}
-
-const mapDispatchToProps = {
- startCreatingTransaction,
-};
-
-export const ConnectedTransactionButton = connect(
- undefined,
- mapDispatchToProps
-)(TransactionButton);
diff --git a/src/components/transaction/transaction-list-item.tsx b/src/components/transaction/transaction-list-item.tsx
index abf5f043..9d9da1bf 100644
--- a/src/components/transaction/transaction-list-item.tsx
+++ b/src/components/transaction/transaction-list-item.tsx
@@ -9,12 +9,10 @@ import {
withTheme,
} from 'bricks-of-sand';
import * as React from 'react';
-import { connect } from 'react-redux';
-import { AppState } from '../../store';
-import { Transaction } from '../../store/reducers';
import { Currency } from '../currency';
import { ShoppingBagIcon } from '../ui/icons/shopping-bag';
-import { ConnectedTransactionUndoButton } from './transaction-undo-button';
+import { TransactionUndoButton } from './transaction-undo-button';
+import { useTransaction } from '../../store';
const ArticleIcon = withTheme(
styled('span')({}, ({ theme }) => ({
@@ -22,27 +20,22 @@ const ArticleIcon = withTheme(
}))
);
-interface OwnProps {
+interface Props {
id: number | string;
}
-interface StateProps {
- transaction: Transaction;
-}
-
-type Props = OwnProps & StateProps;
-
const TextRight = styled(ResponsiveGrid)({
textAlign: 'right',
});
-export function TransactionListItem(props: Props): JSX.Element | null {
- if (!props.transaction) {
+export function TransactionListItem({ id }: Props): JSX.Element | null {
+ const transaction = useTransaction(Number(id));
+ if (!transaction) {
return null;
}
return (
-
+
-
-
+
+
- {props.transaction.sender && (
- <>← {props.transaction.sender.name} :>
- )}
- {props.transaction.recipient && (
- <>→ {props.transaction.recipient.name} :>
+ {transaction.sender && <>← {transaction.sender.name} :>}
+ {transaction.recipient && (
+ <>→ {transaction.recipient.name} :>
)}
- {props.transaction.article && (
+ {transaction.article && (
<>
{' '}
- {props.transaction.article.name}
+ {transaction.article.name}
>
)}
- {props.transaction.comment && <> {props.transaction.comment}>}
+ {transaction.comment && <> {transaction.comment}>}
- {props.transaction.isDeletable ? (
-
) : (
- {props.transaction.created}
+ {transaction.created}
)}
@@ -86,11 +77,3 @@ export function TransactionListItem(props: Props): JSX.Element | null {
);
}
-
-const mapStateToProps = (state: AppState, { id }: OwnProps) => ({
- transaction: state.transaction[id],
-});
-
-export const ConnectedTransactionListItem = connect(mapStateToProps)(
- TransactionListItem
-);
diff --git a/src/components/transaction/transaction-table.tsx b/src/components/transaction/transaction-table.tsx
index 731be565..760187ef 100644
--- a/src/components/transaction/transaction-table.tsx
+++ b/src/components/transaction/transaction-table.tsx
@@ -1,31 +1,16 @@
import * as React from 'react';
-import { connect } from 'react-redux';
-import { Dispatch } from '../../store';
-import {
- Transaction,
- TransactionsResponse,
- startLoadingTransactions,
-} from '../../store/reducers';
+import { store } from '../../store';
+import { Transaction, startLoadingTransactions } from '../../store/reducers';
import { Pager } from '../common/pager';
import { getUserTransactionsLink } from '../user/user-router';
-import { ConnectedTransactionListItem } from './transaction-list-item';
+import { TransactionListItem } from './transaction-list-item';
-interface OwnProps {
- userId: number;
+interface Props {
+ userId: string;
page: number;
onPageChange(url: string): void;
}
-interface ActionProps {
- loadTransactions(
- userId: number,
- offset?: number,
- limit?: number
- ): Promise;
-}
-
-export type TransactionTableProps = ActionProps & OwnProps;
-
interface State {
limit: number;
offset: number;
@@ -35,10 +20,7 @@ interface State {
let lastPage = 0;
-export class TransactionTable extends React.Component<
- TransactionTableProps,
- State
-> {
+export class TransactionTable extends React.Component {
public state = {
limit: 15,
offset: 0,
@@ -73,7 +55,8 @@ export class TransactionTable extends React.Component<
public loadRows = async (): Promise => {
const { limit, offset } = this.getLimitAndOffset();
- const res = await this.props.loadTransactions(
+ const res = await startLoadingTransactions(
+ store.dispatch,
this.props.userId,
offset,
limit
@@ -98,24 +81,11 @@ export class TransactionTable extends React.Component<
}
}
-const mapDispatchToProps = (dispatch: Dispatch): ActionProps => ({
- loadTransactions: (id: number, offset: number, limit: number) =>
- dispatch(startLoadingTransactions(id, offset, limit)),
-});
-
-export const ConnectedTransactionTable = connect(
- undefined,
- mapDispatchToProps
-)(TransactionTable);
-
function TransactionPage(props: { transactions: Transaction[] }): JSX.Element {
return (
<>
{props.transactions.map(transaction => (
-
+
))}
>
);
diff --git a/src/components/transaction/transaction-undo-button.tsx b/src/components/transaction/transaction-undo-button.tsx
index 628ca692..ad162de1 100644
--- a/src/components/transaction/transaction-undo-button.tsx
+++ b/src/components/transaction/transaction-undo-button.tsx
@@ -1,33 +1,18 @@
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
-import { connect } from 'react-redux';
-import { AppState } from '../../store';
-import {
- isTransactionDeletable,
- startDeletingTransaction,
-} from '../../store/reducers';
+import { useIsTransactionDeletable, store } from '../../store';
+import { startDeletingTransaction } from '../../store/reducers';
-interface OwnProps {
- userId?: number;
+interface Props {
+ userId?: string;
transactionId: number;
onSuccess?(): void;
}
-interface StateProps {
- canBeDeleted: boolean;
-}
-
-interface ActionProps {
- // tslint:disable-next-line:no-any
- startDeletingTransaction: any;
-}
-
-export type TransactionUndoButtonProps = ActionProps & StateProps & OwnProps;
+export function TransactionUndoButton(props: Props) {
+ const isDeletable = useIsTransactionDeletable(props.transactionId);
-export function TransactionUndoButton(
- props: TransactionUndoButtonProps
-): JSX.Element | null {
- if (!props.canBeDeleted) {
+ if (!isDeletable) {
return null;
}
@@ -41,23 +26,14 @@ export function TransactionUndoButton(
if (typeof props.onSuccess === 'function') {
props.onSuccess();
}
- props.startDeletingTransaction(props.userId || 0, props.transactionId);
+ startDeletingTransaction(
+ store.dispatch,
+ props.userId || '',
+ props.transactionId
+ );
}}
>
);
}
-
-const mapStateToProps = (state: AppState, props: OwnProps): StateProps => ({
- canBeDeleted: isTransactionDeletable(state, props.transactionId),
-});
-
-const mapDispatchToProps = {
- startDeletingTransaction,
-};
-
-export const ConnectedTransactionUndoButton = connect(
- mapStateToProps,
- mapDispatchToProps
-)(TransactionUndoButton);
diff --git a/src/components/transaction/user-to-user-validator.tsx b/src/components/transaction/user-to-user-validator.tsx
index bd0340ad..faefa20f 100644
--- a/src/components/transaction/user-to-user-validator.tsx
+++ b/src/components/transaction/user-to-user-validator.tsx
@@ -1,52 +1,23 @@
import * as React from 'react';
-import { connect } from 'react-redux';
-import { AppState } from '../../store';
-import { getUserBalance } from '../../store/reducers';
-import { ConnectedTransactionValidator } from './validator';
+import { useTransactionValidator } from './validator';
-interface OwnProps {
- userId: number;
- targetUserId: number;
+interface Props {
+ userId: string;
+ targetUserId: string;
value: number;
render(isValid: boolean): JSX.Element;
}
-interface StateProps {
- ownBalance: number;
- targetBalance: number;
-}
-
-export type UserToUserValidatorProps = StateProps & OwnProps;
-
-export function UserToUserValidator(
- props: UserToUserValidatorProps
-): JSX.Element | null {
- return (
- (
- {
- return (
- <>{props.render(userHasTheMoney && receiverCanAcceptTheMoney)} >
- );
- }}
- />
- )}
- />
+export function UserToUserValidator(props: Props): JSX.Element | null {
+ const userHasTheMoney = useTransactionValidator(
+ props.value,
+ props.userId,
+ false
);
+ const receiverCanAcceptTheMoney = useTransactionValidator(
+ props.value,
+ props.targetUserId,
+ true
+ );
+ return <>{props.render(userHasTheMoney && receiverCanAcceptTheMoney)} >;
}
-
-const mapStateToProps = (state: AppState, props: OwnProps): StateProps => ({
- ownBalance: getUserBalance(state, props.userId),
- targetBalance: getUserBalance(state, props.userId),
-});
-
-export const ConnectedUserToUserValidator = connect(mapStateToProps)(
- UserToUserValidator
-);
diff --git a/src/components/transaction/validator.tsx b/src/components/transaction/validator.tsx
index 5d46b145..2b5f5b09 100644
--- a/src/components/transaction/validator.tsx
+++ b/src/components/transaction/validator.tsx
@@ -1,11 +1,5 @@
-import * as React from 'react';
-import { connect } from 'react-redux';
-import { AppState, useSettings, useUserBalance } from '../../store';
-import {
- Boundary,
- getSettingsBalance,
- getUserBalance,
-} from '../../store/reducers';
+import { useSettings, useUserBalance } from '../../store';
+import { Boundary } from '../../store/reducers';
interface TransactionArguments {
accountBoundary: Boundary;
@@ -15,33 +9,6 @@ interface TransactionArguments {
value: number;
}
-export const isTransactionValid = ({
- accountBoundary,
- paymentBoundary,
- isDeposit,
- balance,
- value,
-}: TransactionArguments): boolean => {
- if (value === 0) {
- return false;
- }
- if (isDeposit) {
- return checkDepositIsValid({
- accountBoundaryValue: accountBoundary.upper,
- paymentBoundaryValue: paymentBoundary.upper,
- value,
- balance,
- });
- } else {
- return checkDispenseIsValid({
- accountBoundaryValue: accountBoundary.lower,
- paymentBoundaryValue: paymentBoundary.lower,
- value,
- balance,
- });
- }
-};
-
interface CheckValidProps {
accountBoundaryValue: number | boolean;
paymentBoundaryValue: number | boolean;
@@ -93,59 +60,46 @@ function checkDispenseIsValid({
return balance - value > accountBoundaryValue;
}
-interface OwnProps {
- userId?: number;
- value: number;
- isDeposit: boolean;
- render(isValid: boolean): JSX.Element;
-}
-
-interface StateProps {
- balance: number | boolean;
- accountBoundary: Boundary;
- paymentBoundary: Boundary;
-}
-
-export type TransactionValidatorProps = StateProps & OwnProps;
-
-export function TransactionValidator(
- props: TransactionValidatorProps
-): JSX.Element | null {
- const isValid = isTransactionValid({
- isDeposit: props.isDeposit,
- value: props.value,
- accountBoundary: props.accountBoundary,
- paymentBoundary: props.paymentBoundary,
- balance: props.balance,
- });
- return <>{props.render(isValid)}>;
-}
-
-const mapStateToProps = (state: AppState, props: OwnProps): StateProps => ({
- balance: props.userId
- ? getUserBalance(state, props.userId)
- : getSettingsBalance(state),
- accountBoundary: state.settings.account.boundary,
- paymentBoundary: state.settings.payment.boundary,
-});
-
-export const ConnectedTransactionValidator = connect(mapStateToProps)(
- TransactionValidator
-);
+export const isTransactionValid = ({
+ accountBoundary,
+ paymentBoundary,
+ isDeposit,
+ balance,
+ value,
+}: TransactionArguments): boolean => {
+ if (value === 0) {
+ return false;
+ }
+ if (isDeposit) {
+ return checkDepositIsValid({
+ accountBoundaryValue: accountBoundary.upper,
+ paymentBoundaryValue: paymentBoundary.upper,
+ value,
+ balance,
+ });
+ } else {
+ return checkDispenseIsValid({
+ accountBoundaryValue: accountBoundary.lower,
+ paymentBoundaryValue: paymentBoundary.lower,
+ value,
+ balance,
+ });
+ }
+};
export function useTransactionValidator(
value: number,
- userId: number
+ userId: string,
+ isDeposit: boolean = true
): boolean {
const settings = useSettings();
const balance = useUserBalance(userId);
+
return isTransactionValid({
value,
balance,
- isDeposit: true,
+ isDeposit,
accountBoundary: settings.account.boundary,
paymentBoundary: settings.payment.boundary,
});
-
- return true;
}
diff --git a/src/components/ui/footer.tsx b/src/components/ui/footer.tsx
index e4242a53..317692ea 100644
--- a/src/components/ui/footer.tsx
+++ b/src/components/ui/footer.tsx
@@ -2,9 +2,7 @@ import { Footer } from 'bricks-of-sand';
import * as React from 'react';
import { GitHubIcon } from '../ui/icons/git-hub';
-export interface MainFooterProps {}
-
-export function MainFooter(props: MainFooterProps): JSX.Element {
+export function MainFooter(): JSX.Element {
return (