satellite/{web/payments}: show token balance on billing overview
This change shows STORJ token balance on the billing overview page instead of the Stripe balance it shows currently. It changes the text on the "Available balance" card to reflect the new balance being displayed. Finally, it adds shortcuts to navigate straight to token history or add tokens modal when call to action on "Balance card" Issue: https://github.com/storj/storj/issues/5204 Change-Id: Ic88e43c602e4949b6c6be4c7644c04f3c7d38585
This commit is contained in:
parent
907c911f57
commit
bf106131b0
@ -3,9 +3,13 @@
|
||||
|
||||
package payments
|
||||
|
||||
import (
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// Balance is an entity that holds free credits and coins balance of user.
|
||||
// Earned by applying of promotional coupon and coins depositing, respectively.
|
||||
type Balance struct {
|
||||
FreeCredits int64 `json:"freeCredits"`
|
||||
Coins int64 `json:"coins"`
|
||||
FreeCredits int64 `json:"freeCredits"`
|
||||
Coins decimal.Decimal `json:"coins"`
|
||||
}
|
||||
|
@ -97,21 +97,14 @@ func (accounts *accounts) Setup(ctx context.Context, userID uuid.UUID, email str
|
||||
func (accounts *accounts) Balance(ctx context.Context, userID uuid.UUID) (_ payments.Balance, err error) {
|
||||
defer mon.Task()(&ctx, userID)(&err)
|
||||
|
||||
customerID, err := accounts.service.db.Customers().GetCustomerID(ctx, userID)
|
||||
balance, err := accounts.service.billingDB.GetBalance(ctx, userID)
|
||||
if err != nil {
|
||||
return payments.Balance{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
c, err := accounts.service.stripeClient.Customers().Get(customerID, nil)
|
||||
if err != nil {
|
||||
return payments.Balance{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
accountBalance := payments.Balance{
|
||||
Coins: -c.Balance,
|
||||
}
|
||||
|
||||
return accountBalance, nil
|
||||
return payments.Balance{
|
||||
Coins: balance.AsDecimal(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ProjectCharges returns how much money current user will be charged for each project.
|
||||
|
@ -35,13 +35,13 @@
|
||||
</div>
|
||||
<div class="total-cost__card">
|
||||
<AvailableBalanceIcon class="total-cost__card__main-icon" />
|
||||
<p class="total-cost__card__money-text">{{ balance.coins | centsToDollars }}</p>
|
||||
<p class="total-cost__card__label-text">Available Balance</p>
|
||||
<p class="total-cost__card__money-text">${{ balance.coins }}</p>
|
||||
<p class="total-cost__card__label-text">STORJ Token Balance</p>
|
||||
<p
|
||||
class="total-cost__card__link-text"
|
||||
@click="routeToPaymentMethods"
|
||||
@click="balanceClicked"
|
||||
>
|
||||
View Payment Methods →
|
||||
{{ hasZeroCoins ? "Add Funds" : "See Balance" }} →
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -112,7 +112,6 @@ import CalendarIcon from '@/../static/images/account/billing/calendar-icon.svg';
|
||||
},
|
||||
})
|
||||
export default class BillingArea extends Vue {
|
||||
public availableBalance = 0;
|
||||
public showChargesTooltip = false;
|
||||
public isDataFetching = true;
|
||||
public currentDate = '';
|
||||
@ -152,6 +151,13 @@ export default class BillingArea extends Vue {
|
||||
return this.$store.state.paymentsModule.balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user's STORJ balance is empty.
|
||||
*/
|
||||
public get hasZeroCoins(): boolean {
|
||||
return this.balance.coins === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* projectUsageAndCharges is an array of all stored ProjectUsageAndCharges.
|
||||
*/
|
||||
@ -176,6 +182,13 @@ export default class BillingArea extends Vue {
|
||||
this.$router.push(RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).path);
|
||||
}
|
||||
|
||||
public balanceClicked(): void {
|
||||
this.$router.push({
|
||||
name: RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).name,
|
||||
params: { action: this.hasZeroCoins ? 'add tokens' : 'token history' },
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -283,6 +283,12 @@ export default class PaymentMethods extends Vue {
|
||||
|
||||
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
||||
|
||||
public mounted(): void {
|
||||
if (this.$route.params.action === 'token history') {
|
||||
this.showTransactionsTable();
|
||||
}
|
||||
}
|
||||
|
||||
private get wallet(): Wallet {
|
||||
return this.$store.state.paymentsModule.wallet;
|
||||
}
|
||||
|
@ -123,6 +123,44 @@ export default class AddTokenCardNative extends Vue {
|
||||
|
||||
public isLoading = false;
|
||||
|
||||
async mounted(): Promise<void> {
|
||||
await this.getWallet();
|
||||
|
||||
// check if user navigated here from Billing overview screen
|
||||
if (this.$route.params.action !== 'add tokens') {
|
||||
return;
|
||||
}
|
||||
// user clicked 'Add Funds' on Billing overview screen.
|
||||
if (this.wallet.address) {
|
||||
this.onAddTokensClick();
|
||||
} else {
|
||||
await this.claimWalletClick();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getWallet tries to get an existing wallet for this user. this will not claim a wallet.
|
||||
*/
|
||||
private async getWallet() {
|
||||
if (this.wallet.address) {
|
||||
return;
|
||||
}
|
||||
this.isLoading = true;
|
||||
await this.$store.dispatch(PAYMENTS_ACTIONS.GET_WALLET).catch(_ => {});
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* claimWallet claims a wallet for the current account.
|
||||
*/
|
||||
private async claimWallet(): Promise<void> {
|
||||
if (!this.wallet.address)
|
||||
await this.$store.dispatch(PAYMENTS_ACTIONS.CLAIM_WALLET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when "Add STORJ Tokens" button is clicked.
|
||||
*/
|
||||
public async claimWalletClick(): Promise<void> {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
@ -135,18 +173,6 @@ export default class AddTokenCardNative extends Vue {
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
mounted(): void {
|
||||
if (!this.wallet.address) {
|
||||
// try to get an existing wallet for this user. this will not claim a wallet.
|
||||
this.$store.dispatch(PAYMENTS_ACTIONS.GET_WALLET);
|
||||
}
|
||||
}
|
||||
|
||||
public async claimWallet(): Promise<void> {
|
||||
if (!this.wallet.address)
|
||||
await this.$store.dispatch(PAYMENTS_ACTIONS.CLAIM_WALLET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds on add tokens button click logic.
|
||||
* Triggers Add funds popup.
|
||||
|
@ -104,9 +104,12 @@ export interface PaymentsApi {
|
||||
export class AccountBalance {
|
||||
constructor(
|
||||
public freeCredits: number = 0,
|
||||
public coins: number = 0,
|
||||
private _coins: string = '0',
|
||||
) { }
|
||||
|
||||
public get coins(): number {
|
||||
return parseFloat(this._coins);
|
||||
}
|
||||
public get sum(): number {
|
||||
return this.freeCredits + this.coins;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user