rewards refactor to support types, add list
This commit is contained in:
parent
31fb723d87
commit
2b8296fcc3
18 changed files with 240 additions and 131 deletions
|
@ -2,7 +2,7 @@ import * as types from "constants/action_types";
|
|||
import * as modals from "constants/modal_types";
|
||||
import lbryio from "lbryio";
|
||||
import rewards from "rewards";
|
||||
import { selectRewardsByType } from "selectors/rewards";
|
||||
import { selectUnclaimedRewardsByType } from "selectors/rewards";
|
||||
|
||||
export function doRewardList() {
|
||||
return function(dispatch, getState) {
|
||||
|
@ -13,7 +13,7 @@ export function doRewardList() {
|
|||
});
|
||||
|
||||
lbryio
|
||||
.call("reward", "list", {})
|
||||
.call("reward", "list", { multiple_rewards_per_type: true })
|
||||
.then(userRewards => {
|
||||
dispatch({
|
||||
type: types.FETCH_REWARDS_COMPLETED,
|
||||
|
@ -31,17 +31,9 @@ export function doRewardList() {
|
|||
|
||||
export function doClaimRewardType(rewardType) {
|
||||
return function(dispatch, getState) {
|
||||
const rewardsByType = selectRewardsByType(getState()),
|
||||
const rewardsByType = selectUnclaimedRewardsByType(getState()),
|
||||
reward = rewardsByType[rewardType];
|
||||
|
||||
if (reward) {
|
||||
dispatch(doClaimReward(reward));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function doClaimReward(reward, saveError = false) {
|
||||
return function(dispatch, getState) {
|
||||
if (reward.transaction_id) {
|
||||
//already claimed, do nothing
|
||||
return;
|
||||
|
@ -72,7 +64,7 @@ export function doClaimReward(reward, saveError = false) {
|
|||
type: types.CLAIM_REWARD_FAILURE,
|
||||
data: {
|
||||
reward,
|
||||
error: saveError ? error : null,
|
||||
error: error ? error : null,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -87,26 +79,18 @@ export function doClaimEligiblePurchaseRewards() {
|
|||
return;
|
||||
}
|
||||
|
||||
const rewardsByType = selectRewardsByType(getState());
|
||||
const rewardsByType = selectUnclaimedRewardsByType(getState());
|
||||
|
||||
let types = {};
|
||||
|
||||
types[rewards.TYPE_FIRST_STREAM] = false;
|
||||
types[rewards.TYPE_FEATURED_DOWNLOAD] = false;
|
||||
types[rewards.TYPE_MANY_DOWNLOADS] = false;
|
||||
Object.values(rewardsByType).forEach(reward => {
|
||||
if (types[reward.reward_type] === false && reward.transaction_id) {
|
||||
types[reward.reward_type] = true;
|
||||
}
|
||||
});
|
||||
|
||||
let unclaimedType = Object.keys(types).find(type => {
|
||||
return types[type] === false && type !== rewards.TYPE_FEATURED_DOWNLOAD; //handled below
|
||||
});
|
||||
if (unclaimedType) {
|
||||
dispatch(doClaimRewardType(unclaimedType));
|
||||
if (rewardsByType[rewards.TYPE_FIRST_STREAM]) {
|
||||
dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM));
|
||||
} else {
|
||||
[
|
||||
rewards.TYPE_MANY_DOWNLOADS,
|
||||
rewards.TYPE_FEATURED_DOWNLOAD,
|
||||
].forEach(type => {
|
||||
dispatch(doClaimRewardType(type));
|
||||
});
|
||||
}
|
||||
dispatch(doClaimRewardType(rewards.TYPE_FEATURED_DOWNLOAD));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
5
ui/js/component/linkTransaction/index.js
Normal file
5
ui/js/component/linkTransaction/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import Link from "./view";
|
||||
|
||||
export default connect(null, null)(Link);
|
14
ui/js/component/linkTransaction/view.jsx
Normal file
14
ui/js/component/linkTransaction/view.jsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import Link from "component/link";
|
||||
|
||||
const LinkTransaction = props => {
|
||||
const { id } = props;
|
||||
const linkProps = Object.assign({}, props);
|
||||
|
||||
linkProps.href = "https://explorer.lbry.io/#!/transaction/" + id;
|
||||
linkProps.label = id.substr(0, 7);
|
||||
|
||||
return <Link {...linkProps} />;
|
||||
};
|
||||
|
||||
export default LinkTransaction;
|
|
@ -6,7 +6,7 @@ import {
|
|||
makeSelectIsRewardClaimPending,
|
||||
} from "selectors/rewards";
|
||||
import { doNavigate } from "actions/app";
|
||||
import { doClaimReward, doClaimRewardClearError } from "actions/rewards";
|
||||
import { doClaimRewardType, doClaimRewardClearError } from "actions/rewards";
|
||||
import RewardLink from "./view";
|
||||
|
||||
const makeSelect = () => {
|
||||
|
@ -24,7 +24,7 @@ const makeSelect = () => {
|
|||
};
|
||||
|
||||
const perform = dispatch => ({
|
||||
claimReward: reward => dispatch(doClaimReward(reward, true)),
|
||||
claimReward: reward => dispatch(doClaimRewardType(reward.reward_type, true)),
|
||||
clearError: reward => dispatch(doClaimRewardClearError(reward)),
|
||||
navigate: path => dispatch(doNavigate(path)),
|
||||
});
|
||||
|
|
10
ui/js/component/rewardListClaimed/index.js
Normal file
10
ui/js/component/rewardListClaimed/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { selectClaimedRewards } from "selectors/rewards";
|
||||
import RewardListClaimed from "./view";
|
||||
|
||||
const select = state => ({
|
||||
rewards: selectClaimedRewards(state),
|
||||
});
|
||||
|
||||
export default connect(select, null)(RewardListClaimed);
|
44
ui/js/component/rewardListClaimed/view.jsx
Normal file
44
ui/js/component/rewardListClaimed/view.jsx
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React from "react";
|
||||
import LinkTransaction from "component/linkTransaction";
|
||||
|
||||
const RewardListClaimed = props => {
|
||||
const { rewards } = props;
|
||||
|
||||
if (!rewards || !rewards.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="card">
|
||||
<div className="card__title-identity"><h3>Claimed Rewards</h3></div>
|
||||
<div className="card__content">
|
||||
<table className="table-standard table-stretch">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{__("Title")}</th>
|
||||
<th>{__("Amount")}</th>
|
||||
<th>{__("Transaction")}</th>
|
||||
<th>{__("Date")}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rewards.map(reward => {
|
||||
return (
|
||||
<tr key={reward.id}>
|
||||
<td>{reward.reward_title}</td>
|
||||
<td>{reward.reward_amount}</td>
|
||||
<td><LinkTransaction id={reward.transaction_id} /></td>
|
||||
<td>
|
||||
{reward.created_at.replace("Z", " ").replace("T", " ")}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default RewardListClaimed;
|
5
ui/js/component/rewardTile/index.js
Normal file
5
ui/js/component/rewardTile/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import RewardTile from "./view";
|
||||
|
||||
export default connect(null, null)(RewardTile);
|
28
ui/js/component/rewardTile/view.jsx
Normal file
28
ui/js/component/rewardTile/view.jsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
import { CreditAmount, Icon } from "component/common";
|
||||
import RewardLink from "component/rewardLink";
|
||||
|
||||
const RewardTile = props => {
|
||||
const { reward } = props;
|
||||
|
||||
const claimed = !!reward.transaction_id;
|
||||
|
||||
return (
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-primary">
|
||||
<CreditAmount amount={reward.reward_amount} />
|
||||
<h3>{reward.reward_title}</h3>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
{claimed
|
||||
? <span><Icon icon="icon-check" /> {__("Reward claimed.")}</span>
|
||||
: <RewardLink reward_type={reward.reward_type} />}
|
||||
</div>
|
||||
<div className="card__content">{reward.reward_description}</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default RewardTile;
|
|
@ -13,6 +13,7 @@ import DeveloperPage from "page/developer.js";
|
|||
import RewardsPage from "page/rewards";
|
||||
import FileListDownloaded from "page/fileListDownloaded";
|
||||
import FileListPublished from "page/fileListPublished";
|
||||
import TransactionHistoryPage from "page/transactionHistory";
|
||||
import ChannelPage from "page/channel";
|
||||
import SearchPage from "page/search";
|
||||
import AuthPage from "page/auth";
|
||||
|
@ -36,6 +37,7 @@ const Router = props => {
|
|||
discover: <DiscoverPage params={params} />,
|
||||
downloaded: <FileListDownloaded params={params} />,
|
||||
help: <HelpPage params={params} />,
|
||||
history: <TransactionHistoryPage params={params} />,
|
||||
invite: <InvitePage params={params} />,
|
||||
publish: <PublishPage params={params} />,
|
||||
published: <FileListPublished params={params} />,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from "react";
|
||||
import { Address, BusyMessage, CreditAmount } from "component/common";
|
||||
import { BusyMessage } from "component/common";
|
||||
import LinkTransaction from "component/linkTransaction";
|
||||
|
||||
class TransactionList extends React.PureComponent {
|
||||
componentWillMount() {
|
||||
|
@ -26,12 +27,7 @@ class TransactionList extends React.PureComponent {
|
|||
: <span className="empty">{__("(Transaction pending)")}</span>}
|
||||
</td>
|
||||
<td>
|
||||
<a
|
||||
className="button-text"
|
||||
href={"https://explorer.lbry.io/#!/transaction/" + item.id}
|
||||
>
|
||||
{item.id.substr(0, 7)}
|
||||
</a>
|
||||
<LinkTransaction id={item.id} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ import { selectUserIsRewardApproved } from "selectors/user";
|
|||
import {
|
||||
makeSelectHasClaimedReward,
|
||||
makeSelectRewardByType,
|
||||
selectTotalRewardValue,
|
||||
selectUnclaimedRewardValue,
|
||||
} from "selectors/rewards";
|
||||
import * as settings from "constants/settings";
|
||||
import ModalCreditIntro from "./view";
|
||||
|
@ -19,7 +19,7 @@ const select = (state, props) => {
|
|||
return {
|
||||
isRewardApproved: selectUserIsRewardApproved(state),
|
||||
reward: selectReward(state, { reward_type: rewards.TYPE_NEW_USER }),
|
||||
totalRewardValue: selectTotalRewardValue(state),
|
||||
totalRewardValue: selectUnclaimedRewardValue(state),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
makeSelectRewardByType,
|
||||
selectFetchingRewards,
|
||||
selectRewards,
|
||||
selectUnclaimedRewards,
|
||||
} from "selectors/rewards";
|
||||
import { selectUser } from "selectors/user";
|
||||
import { doAuthNavigate, doNavigate } from "actions/app";
|
||||
import { doRewardList } from "actions/rewards";
|
||||
import rewards from "rewards";
|
||||
import RewardsPage from "./view";
|
||||
|
||||
const select = (state, props) => {
|
||||
const selectReward = makeSelectRewardByType();
|
||||
|
||||
return {
|
||||
fetching: selectFetchingRewards(state),
|
||||
rewards: selectRewards(state),
|
||||
newUserReward: selectReward(state, { reward_type: rewards.TYPE_NEW_USER }),
|
||||
rewards: selectUnclaimedRewards(state),
|
||||
user: selectUser(state),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,31 +1,9 @@
|
|||
import React from "react";
|
||||
import { BusyMessage, CreditAmount, Icon } from "component/common";
|
||||
import { BusyMessage } from "component/common";
|
||||
import RewardListClaimed from "component/rewardListClaimed";
|
||||
import RewardTile from "component/rewardTile";
|
||||
import SubHeader from "component/subHeader";
|
||||
import Link from "component/link";
|
||||
import RewardLink from "component/rewardLink";
|
||||
|
||||
const RewardTile = props => {
|
||||
const { reward } = props;
|
||||
|
||||
const claimed = !!reward.transaction_id;
|
||||
|
||||
return (
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-primary">
|
||||
<CreditAmount amount={reward.reward_amount} />
|
||||
<h3>{reward.reward_title}</h3>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
{claimed
|
||||
? <span><Icon icon="icon-check" /> {__("Reward claimed.")}</span>
|
||||
: <RewardLink reward_type={reward.reward_type} />}
|
||||
</div>
|
||||
<div className="card__content">{reward.reward_description}</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
class RewardsPage extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
|
@ -44,32 +22,8 @@ class RewardsPage extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { doAuth, fetching, navigate, rewards, user } = this.props;
|
||||
|
||||
let content, cardHeader;
|
||||
|
||||
if (fetching) {
|
||||
content = (
|
||||
<div className="card__content">
|
||||
<BusyMessage message={__("Fetching rewards")} />
|
||||
</div>
|
||||
);
|
||||
} else if (rewards.length > 0) {
|
||||
content = (
|
||||
<div>
|
||||
{rewards.map(reward =>
|
||||
<RewardTile key={reward.reward_type} reward={reward} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<div className="card__content empty">
|
||||
{__("Failed to load rewards.")}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
renderPageHeader() {
|
||||
const { doAuth, navigate, user } = this.props;
|
||||
|
||||
if (user && !user.is_reward_approved) {
|
||||
if (
|
||||
|
@ -77,7 +31,7 @@ class RewardsPage extends React.PureComponent {
|
|||
!user.has_verified_email ||
|
||||
!user.is_identity_verified
|
||||
) {
|
||||
cardHeader = (
|
||||
return (
|
||||
<div>
|
||||
<div className="card__content empty">
|
||||
<p>
|
||||
|
@ -90,7 +44,7 @@ class RewardsPage extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
} else {
|
||||
cardHeader = (
|
||||
return (
|
||||
<div className="card__content">
|
||||
<p>
|
||||
{__(
|
||||
|
@ -122,25 +76,49 @@ class RewardsPage extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
} else if (user === null) {
|
||||
cardHeader = (
|
||||
<div>
|
||||
<div className="card__content empty">
|
||||
<p>
|
||||
{__(
|
||||
"This application is unable to earn rewards due to an authentication failure."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
renderUnclaimedRewards() {
|
||||
const { fetching, rewards, user } = this.props;
|
||||
|
||||
if (fetching) {
|
||||
return (
|
||||
<div className="card__content">
|
||||
<BusyMessage message={__("Fetching rewards")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
} else if (user === null) {
|
||||
|
||||
return (
|
||||
<div className="card__content empty">
|
||||
<p>
|
||||
{__(
|
||||
"This application is unable to earn rewards due to an authentication failure."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
} else if (!rewards || rewards.length <= 0) {
|
||||
return (
|
||||
<div className="card__content empty">
|
||||
{__("Failed to load rewards.")}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return rewards.map(reward =>
|
||||
<RewardTile key={reward.reward_type} reward={reward} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<SubHeader />
|
||||
{cardHeader && <section className="card">{cardHeader}</section>}
|
||||
{content}
|
||||
{this.renderPageHeader()}
|
||||
{this.renderUnclaimedRewards()}
|
||||
{<RewardListClaimed />}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
5
ui/js/page/transactionHistory/index.js
Normal file
5
ui/js/page/transactionHistory/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import WalletPage from "./view";
|
||||
|
||||
export default connect(null, null)(WalletPage);
|
14
ui/js/page/transactionHistory/view.jsx
Normal file
14
ui/js/page/transactionHistory/view.jsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import SubHeader from "component/subHeader";
|
||||
import TransactionList from "component/transactionList";
|
||||
|
||||
const TransactionHistoryPage = props => {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<SubHeader />
|
||||
<TransactionList />
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionHistoryPage;
|
|
@ -3,7 +3,8 @@ import * as types from "constants/action_types";
|
|||
const reducers = {};
|
||||
const defaultState = {
|
||||
fetching: false,
|
||||
rewardsByType: {},
|
||||
claimedRewardsById: {}, //id => reward
|
||||
unclaimedRewardsByType: {},
|
||||
claimPendingByType: {},
|
||||
claimErrorsByType: {},
|
||||
};
|
||||
|
@ -17,11 +18,19 @@ reducers[types.FETCH_REWARDS_STARTED] = function(state, action) {
|
|||
reducers[types.FETCH_REWARDS_COMPLETED] = function(state, action) {
|
||||
const { userRewards } = action.data;
|
||||
|
||||
const rewardsByType = {};
|
||||
userRewards.forEach(reward => (rewardsByType[reward.reward_type] = reward));
|
||||
let unclaimedRewards = {},
|
||||
claimedRewards = {};
|
||||
userRewards.forEach(reward => {
|
||||
if (reward.transaction_id) {
|
||||
claimedRewards[reward.id] = reward;
|
||||
} else {
|
||||
unclaimedRewards[reward.reward_type] = reward;
|
||||
}
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
rewardsByType: rewardsByType,
|
||||
claimedRewardsById: claimedRewards,
|
||||
unclaimedRewardsByType: unclaimedRewards,
|
||||
fetching: false,
|
||||
});
|
||||
};
|
||||
|
@ -55,16 +64,22 @@ reducers[types.CLAIM_REWARD_STARTED] = function(state, action) {
|
|||
reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) {
|
||||
const { reward } = action.data;
|
||||
|
||||
const existingReward = state.rewardsByType[reward.reward_type];
|
||||
let unclaimedRewardsByType = Object.assign({}, state.unclaimedRewardsByType);
|
||||
const existingReward = unclaimedRewardsByType[reward.reward_type];
|
||||
delete state.unclaimedRewardsByType[reward.reward_type];
|
||||
|
||||
const newReward = Object.assign({}, reward, {
|
||||
reward_title: existingReward.reward_title,
|
||||
reward_description: existingReward.reward_description,
|
||||
});
|
||||
const rewardsByType = Object.assign({}, state.rewardsByType);
|
||||
|
||||
rewardsByType[reward.reward_type] = newReward;
|
||||
let claimedRewardsById = Object.assign({}, state.claimedRewardsById);
|
||||
claimedRewardsById[reward.id] = newReward;
|
||||
|
||||
const newState = Object.assign({}, state, { rewardsByType });
|
||||
const newState = Object.assign({}, state, {
|
||||
unclaimedRewardsByType,
|
||||
claimedRewardsById,
|
||||
});
|
||||
|
||||
return setClaimRewardState(newState, newReward, false, "");
|
||||
};
|
||||
|
|
|
@ -136,6 +136,7 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
|||
// This contains intentional fall throughs
|
||||
switch (page) {
|
||||
case "wallet":
|
||||
case "history":
|
||||
case "send":
|
||||
case "receive":
|
||||
case "invite":
|
||||
|
@ -143,6 +144,7 @@ export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
|||
case "backup":
|
||||
return {
|
||||
wallet: __("Overview"),
|
||||
history: __("History"),
|
||||
send: __("Send"),
|
||||
receive: __("Receive"),
|
||||
invite: __("Invites"),
|
||||
|
|
|
@ -3,13 +3,23 @@ import { selectUser } from "selectors/user";
|
|||
|
||||
const _selectState = state => state.rewards || {};
|
||||
|
||||
export const selectRewardsByType = createSelector(
|
||||
export const selectUnclaimedRewardsByType = createSelector(
|
||||
_selectState,
|
||||
state => state.rewardsByType || {}
|
||||
state => state.unclaimedRewardsByType
|
||||
);
|
||||
|
||||
export const selectRewards = createSelector(
|
||||
selectRewardsByType,
|
||||
export const selectClaimedRewardsById = createSelector(
|
||||
_selectState,
|
||||
state => state.claimedRewardsById
|
||||
);
|
||||
|
||||
export const selectClaimedRewards = createSelector(
|
||||
selectClaimedRewardsById,
|
||||
byId => Object.values(byId) || []
|
||||
);
|
||||
|
||||
export const selectUnclaimedRewards = createSelector(
|
||||
selectUnclaimedRewardsByType,
|
||||
byType => Object.values(byType) || []
|
||||
);
|
||||
|
||||
|
@ -23,10 +33,12 @@ export const selectFetchingRewards = createSelector(
|
|||
state => !!state.fetching
|
||||
);
|
||||
|
||||
export const selectTotalRewardValue = createSelector(selectRewards, rewards =>
|
||||
rewards.reduce((sum, reward) => {
|
||||
return sum + reward.reward_amount;
|
||||
}, 0)
|
||||
export const selectUnclaimedRewardValue = createSelector(
|
||||
selectUnclaimedRewards,
|
||||
rewards =>
|
||||
rewards.reduce((sum, reward) => {
|
||||
return sum + reward.reward_amount;
|
||||
}, 0)
|
||||
);
|
||||
|
||||
export const selectHasClaimedReward = (state, props) => {
|
||||
|
@ -65,7 +77,7 @@ export const makeSelectClaimRewardError = () => {
|
|||
};
|
||||
|
||||
const selectRewardByType = (state, props) => {
|
||||
return selectRewardsByType(state)[props.reward_type];
|
||||
return selectUnclaimedRewardsByType(state)[props.reward_type];
|
||||
};
|
||||
|
||||
export const makeSelectRewardByType = () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue