Commit f254fd21 authored by Olivia Madrid's avatar Olivia Madrid

token onboarding notice flow

1 merge request!686WIP: Epic/wallet 80
Pipeline #118263163 passed with stages
in 89 minutes and 24 seconds
<div class="m-walletBalance--cash" *ngIf="!inProgress">
<div *ngIf="!loaded" class="m-wallet__spinner">
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div>
<div class="m-walletBalance--cash" *ngIf="loaded">
<div
class="m-walletBalance---cash__onboardingNotice"
*ngIf="!hasAccount || !account.bankAccount"
*ngIf="viewId !== 'settings' && (!hasAccount || !account.bankAccount)"
>
<p (click)="scrollToSettings()">
<a>Add your bank information</a>
</p>
<p>Start receiving cash payouts by adding your bank details.</p>
<p>
<ng-container *ngIf="!hasAccount"
>Start receiving cash payouts by adding your bank details.
</ng-container>
<ng-container *ngIf="hasAccount"
>Finish adding your bank details to start receiving cash payouts.
</ng-container>
</p>
</div>
<div class="m-walletBalance--cash__colContainer">
<!-- ---PENDING BALANCE ------------------------------------------------- -->
<!-- ---PENDING BALANCE ------------------- -->
<div class="m-walletBalance--cash__col">
<div class="m-walletBalance--cash__colTitle">
Pending Balance<m-tooltip icon="help"
>The total amount of cash you are scheduled to receive from wires
and/or earnings. The payout date is estimated and it may take up to 7
days before your balance reaches your bank account.
>The total amount of cash you are scheduled to receive from
wires<ng-container *ngIf="isPro"> and/or Pro earnings</ng-container>.
The payout date is an estimation and it may take up to 7 days before
your cash reaches your bank account.
</m-tooltip>
</div>
<div class="m-walletBalance--cash__colValWrapper" *ngIf="!hasAccount">
......@@ -41,7 +53,8 @@
</div>
</ng-container>
</div>
<!-- ---TOTAL PAID OUT------------------------------------------------- -->
<!-- ---TOTAL PAID OUT ------------------- -->
<div class="m-walletBalance--cash__col" *ngIf="hasAccount">
<div class="m-walletBalance--cash__colTitle">
......@@ -61,7 +74,9 @@
>
</div>
</div>
<!-- ---PRO EARNINGS------------------------------------------------- -->
<!-- ---PRO EARNINGS ------------------- -->
<div class="m-walletBalance--cash__col" *ngIf="isPro">
<div class="m-walletBalance--cash__colTitle">
Pro Earnings<m-tooltip icon="help"
......
......@@ -10,7 +10,7 @@ import {
} from '@angular/core';
import { Client } from '../../../../services/api/client';
import { Session } from '../../../../services/session';
import { WalletDashboardService } from '../dashboard.service';
import { WalletDashboardService, WalletCurrency } from '../dashboard.service';
import { ActivatedRoute, ParamMap } from '@angular/router';
import * as moment from 'moment';
import { Subscription } from 'rxjs';
......@@ -21,7 +21,10 @@ import { ConfigsService } from '../../../../common/services/configs.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WalletBalanceCashComponent implements OnInit, OnDestroy {
inProgress: boolean = true;
@Output() scrollToCashSettings: EventEmitter<any> = new EventEmitter();
@Input() viewId: string;
@Input() cashWallet: WalletCurrency; // TODOOJM USE ME & make me a setter
account;
hasAccount: boolean = true;
isPro: boolean = false;
......@@ -34,8 +37,6 @@ export class WalletBalanceCashComponent implements OnInit, OnDestroy {
paramsSubscription: Subscription;
loaded: boolean = false;
@Output() scrollToCashSettings: EventEmitter<any> = new EventEmitter();
constructor(
protected client: Client,
protected cd: ChangeDetectorRef,
......@@ -76,19 +77,25 @@ export class WalletBalanceCashComponent implements OnInit, OnDestroy {
.endOf('month')
.format('ddd Do MMM');
this.account = await this.walletService.getStripeAccount();
if (!this.account || !this.account.accountNumber) {
// this.account = await this.walletService.getStripeAccount();
// if (!this.account || !this.account.accountNumber) {
if (this.cashWallet.address !== 'stripe') {
this.hasAccount = false;
this.pendingBalance = this.formatBalance(0);
this.totalPaidOut = this.formatBalance(0);
} else {
this.pendingBalance = this.formatBalance(
this.account.pendingBalance.amount / 100
);
if (this.account.bankAccount) {
this.currency = this.account.bankAccount.currency.toUpperCase();
}
this.hasAccount = true;
this.pendingBalance = this.formatBalance(this.cashWallet.balance);
this.currency = this.cashWallet.label.toUpperCase();
this.account = await this.walletService.getStripeAccount();
// this.pendingBalance = this.formatBalance(
// this.account.pendingBalance.amount / 100
// );
// if (this.account.bankAccount) {
// this.currency = this.account.bankAccount.currency.toUpperCase();
// }
let totalPaidOutRaw =
(this.account.totalBalance.amount -
......@@ -103,14 +110,10 @@ export class WalletBalanceCashComponent implements OnInit, OnDestroy {
this.totalPaidOut = this.formatBalance(totalPaidOutRaw);
}
this.inProgress = false;
this.detectChanges();
}
async getProEarnings() {
this.inProgress = true;
this.detectChanges();
try {
const response: number = await this.walletService.getProEarnings();
this.proEarnings = this.formatBalance(response);
......@@ -118,7 +121,6 @@ export class WalletBalanceCashComponent implements OnInit, OnDestroy {
console.error(e.message);
this.proEarnings = this.formatBalance(0);
}
this.inProgress = false;
this.detectChanges();
}
......
......@@ -21,12 +21,19 @@
(tabChanged)="updateCurrency($event)"
></m-shadowboxHeader__tabs>
<div class="m-shadowboxLayout__body">
<div class="m-walletDashboardBalances__wrapper">
<div
class="m-walletDashboardBalances__wrapper"
*ngIf="
activeCurrencyId === 'tokens' || activeCurrencyId === 'cash'
"
>
<m-walletTokenOnboarding
*ngIf="
activeCurrencyId === 'tokens' && !tokenOnboardingComplete
"
(onboardingCompleted)="tokenOnboardingCompleted()"
[hasAddress]="hasOnchainAddress"
[phoneVerified]="phoneVerified"
(onboardingComplete)="tokenOnboardingCompleted()"
(scrollToTokenSettings)="scrollToSettings('tokens')"
></m-walletTokenOnboarding>
<m-walletBalance--tokens
......@@ -37,6 +44,8 @@
<m-walletBalance--cash
class="m-shadowboxLayout__body"
*ngIf="activeCurrencyId === 'cash'"
[viewId]="activeViewId"
[cashWallet]="wallet.cash"
(scrollToCashSettings)="scrollToSettings('cash')"
></m-walletBalance--cash>
</div>
......@@ -67,6 +76,7 @@
*ngIf="activeCurrencyId === 'tokens'"
></m-walletTransactions--tokens>
<m-walletTransactions--cash
[cashWallet]="wallet.cash"
*ngIf="activeCurrencyId === 'cash'"
[noAccount]="wallet.cash.address === null"
></m-walletTransactions--cash>
......@@ -76,18 +86,18 @@
<m-walletSettings--tokens
class="m-walletDashboardViews__view"
*ngIf="activeCurrencyId === 'tokens'"
(onchainAddressChanged)="loadWallet()"
#tokenSettings
(onchainAddressChanged)="onchainAddressChanged()"
></m-walletSettings--tokens>
<m-walletSettings--cash
class="m-walletDashboardViews__view"
*ngIf="activeCurrencyId === 'cash'"
[cashWallet]="wallet.cash"
(accountChanged)="loadWallet()"
#cashSettings
></m-walletSettings--cash>
<m-walletSettings--eth
class="m-walletDashboardViews__view"
*ngIf="activeCurrencyId === 'eth'"
[ethWallet]="wallet.eth"
(scrollToTokenSettings)="scrollToSettings('tokens')"
></m-walletSettings--eth>
<m-walletSettings--btc
......
......@@ -363,203 +363,261 @@ m-walletDashboard {
}
}
}
}
// *******************************************************
// ** SETTINGS - COMMON STYLES ***************************
// *******************************************************
// *******************************************************
// ** SETTINGS - COMMON STYLES ***************************
// *******************************************************
.m-walletSettings {
// font-weight: 300;
@include m-theme() {
color: themed($m-textColor--primary);
}
m-shadowboxSubmitButton {
margin: 27px 0 0 0;
}
h2 {
margin: 0;
font-size: 26px;
line-height: 34px;
}
h4 {
margin: 0;
font-size: 21px;
line-height: 28px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
.m-walletSettings {
// font-weight: 300;
}
a {
// font-weight: 300;
text-decoration: underline;
cursor: pointer;
font-size: 14px;
line-height: 19px;
}
p {
font-size: 14px;
line-height: 19px;
margin: 23px 0 0 0;
font-weight: 400; // TODOOJM - make this 300 on the install metamask page
@include m-theme() {
color: themed($m-textColor--tertiary);
color: themed($m-textColor--primary);
}
m-shadowboxSubmitButton {
margin: 27px 0 0 0;
}
}
.m-walletSettingsView--addressCurrent {
h2 {
margin-bottom: 23px;
margin: 0;
font-size: 26px;
line-height: 34px;
}
}
.m-walletSettingsView--addressCurrent__title {
margin-bottom: 13px;
}
.m-walletSettingsView--addressCurrent__addressContainer {
display: flex;
flex-flow: row wrap;
font-size: 15px;
line-height: 20px;
div:first-child {
margin: 0 18px 8px 0;
@include m-theme() {
color: themed($m-textColor--primary);
}
h4 {
margin: 0;
font-size: 21px;
line-height: 28px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
// font-weight: 300;
}
a {
// font-weight: 300;
text-decoration: underline;
cursor: pointer;
font-size: 14px;
line-height: 20px;
font-weight: 300;
line-height: 19px;
}
p {
font-size: 14px;
line-height: 19px;
margin: 23px 0 0 0;
font-weight: 400; // TODOOJM - make this 300 on the install metamask page
@include m-theme() {
color: themed($m-textColor--tertiary);
}
}
}
.m-walletSettings__setupOptions__recommendation {
display: flex;
flex-flow: row nowrap;
align-items: flex-end;
font-size: 12px;
line-height: 16px;
margin: 31px 0 0 0;
@include m-theme() {
color: themed($m-textColor--tertiary);
.m-walletSettingsView--addressCurrent {
h2 {
margin-bottom: 23px;
}
}
i {
font-size: 18px;
margin-right: 8px;
.m-walletSettingsView--addressCurrent__title {
margin-bottom: 13px;
}
}
.m-walletSettingsView__setupOptions__container {
display: flex;
flex-flow: row wrap;
li {
box-sizing: border-box;
flex: 1 1 50%;
padding: 16px 0 16px 54px;
.m-walletSettingsView--addressCurrent__addressContainer {
display: flex;
flex-flow: row wrap;
font-size: 15px;
line-height: 20px;
div:first-child {
margin: 0 18px 8px 0;
@include m-theme() {
color: themed($m-textColor--primary);
}
}
a {
font-size: 14px;
line-height: 20px;
font-weight: 300;
}
}
p {
.m-walletSettings__setupOptions__recommendation {
display: flex;
flex-flow: row nowrap;
align-items: flex-end;
font-size: 12px;
line-height: 16px;
margin: 31px 0 0 0;
@include m-theme() {
color: themed($m-textColor--primary);
color: themed($m-textColor--tertiary);
}
i {
font-size: 18px;
margin-right: 8px;
}
}
.m-walletSettingsView__setupOption--custom {
div {
margin-top: 16px;
display: inline-block;
a,
span {
.m-walletSettingsView__setupOptions__container {
display: flex;
flex-flow: row wrap;
li {
box-sizing: border-box;
flex: 1 1 50%;
padding: 16px 0 16px 54px;
}
p {
@include m-theme() {
color: themed($m-textColor--primary);
}
}
.m-walletSettingsView__setupOption--custom {
div {
margin-top: 16px;
display: inline-block;
margin-right: 5px;
a,
span {
display: inline-block;
margin-right: 5px;
font-weight: 300;
}
span {
@include m-theme() {
color: themed($m-textColor--tertiary);
}
}
}
}
.m-walletSettingsView__setupOption--metamask {
padding-right: 32px;
padding-left: 0;
border-width: 0;
border-right-width: 1px;
border-style: solid;
@include m-theme() {
border-image: linear-gradient(
transparent,
rgba(themed($m-grey-200), 0.6),
transparent
)
10 100%;
}
a {
font-weight: 300;
}
span {
@include m-theme() {
color: themed($m-textColor--tertiary);
}
}
div {
display: flex;
flex-flow: row nowrap;
align-items: center;
img {
height: 34px;
margin-right: 12px;
}
}
}
.m-walletSettingsView__setupOption--metamask {
padding-right: 32px;
padding-left: 0;
border-width: 0;
border-right-width: 1px;
border-style: solid;
span.m-walletSettings__address--emphasis {
@include m-theme() {
border-image: linear-gradient(
transparent,
rgba(themed($m-grey-200), 0.6),
transparent
)
10 100%;
}
a {
font-weight: 300;
color: themed($m-textColor--primary);
}
}
div {
display: flex;
a.m-walletSettings__backButton {
margin-top: 33px;
display: inline-flex;
flex-flow: row nowrap;
align-items: center;
img {
height: 34px;
margin-right: 12px;
align-items: baseline;
text-decoration: none;
@include m-theme() {
color: themed($m-textColor--tertiary);
}
&:hover {
span {
text-decoration: underline;
}
}
i {
font-size: 14px;
font-weight: 300;
margin-right: 10px;
}
}
}
span.m-walletSettings__address--emphasis {
@include m-theme() {
color: themed($m-textColor--primary);
}
}
a.m-walletSettings__backButton {
margin-top: 33px;
display: inline-flex;
flex-flow: row nowrap;
align-items: baseline;
text-decoration: none;
@include m-theme() {
color: themed($m-textColor--tertiary);
}
&:hover {
span {
text-decoration: underline;
@media screen and (max-width: $min-tablet) {
.m-walletSettingsView__setupOptions__container {
li.m-walletSettingsView__setupOption--custom {
padding-left: 32px;
}
}
}
i {
font-size: 14px;
font-weight: 300;
margin-right: 10px;
}
}
@media screen and (max-width: $min-tablet) {
.m-walletSettingsView__setupOptions__container {
li.m-walletSettingsView__setupOption--custom {
padding-left: 32px;
@media screen and (max-width: 520px) {
.m-walletSettingsView__setupOptions__container {
li {
flex-basis: 100%;
&.m-walletSettingsView__setupOption--metamask {
padding: 16px 0 32px 0;
border-right-width: 0;
}
&.m-walletSettingsView__setupOption--custom {
padding: 32px 0 0 0;
}
}
}
}
}
@media screen and (max-width: 520px) {
.m-walletSettingsView__setupOptions__container {
li {
flex-basis: 100%;
&.m-walletSettingsView__setupOption--metamask {
padding: 16px 0 32px 0;
border-right-width: 0;
@media screen and (max-width: $max-mobile) {
[class*='m-walletTokenOnboardingStep--'] {
padding: 19px;
}
m-walletModal {
.m-walletModal__close {
top: 14px;
right: 20px;
@include m-theme() {
background-color: rgba(0, 0, 0, 0);
box-shadow: none;
}
&:hover {
@include m-theme() {
box-shadow: none;
}
}
}
.m-walletModal {
min-width: 90vw;
min-height: 96vh;
padding: 20px;
.m-phoneInput__wrapper {
min-width: 200px;
}
.m-walletForm__wrapper {
margin-bottom: 0px;
}
.m-walletModal__title {
// font-size: 20px;
// line-height: 25px;
}
.m-walletModal__desc p {
// font-size: 14px;
// line-height: 19px;
}
.m-walletModal__footnote--formStatus {
font-size: 13px;
line-height: 18px;
> div {
&:first-child {
margin-bottom: 8px;
}
}
}
&.m-walletSettingsView__setupOption--custom {
padding: 32px 0 0 0;
m-shadowboxSubmitButton {
margin-bottom: 10px;
}
m-phoneInput {
.m-phoneInput__countryList {
max-height: 124px;
}
}
}
}
}
}
///////////////////////////////////
......@@ -25,8 +25,6 @@ import { ShadowboxHeaderTab } from '../../../interfaces/dashboard';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WalletDashboardComponent implements OnInit, OnDestroy {
@ViewChild('tokensSettings', { static: false }) tokenSettingsEl: ElementRef;
@ViewChild('cashSettings', { static: false }) cashSettingsEl: ElementRef;
@ViewChild('dashboardViews', { static: false })
dashboardViewsEl: ElementRef;
......@@ -37,7 +35,9 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
activeCurrencyId: string;
activeViewId: string;
tokenOnboardingComplete = false;
tokenOnboardingComplete: boolean = false;
hasOnchainAddress: boolean = false;
phoneVerified: boolean = false;
views: any = {
tokens: [
......@@ -70,10 +70,9 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
return;
}
if (
this.session.getLoggedInUser().rewards &&
this.session.getLoggedInUser().eth_wallet
) {
this.phoneVerified = this.session.getLoggedInUser().rewards;
this.hasOnchainAddress = this.session.getLoggedInUser().eth_wallet;
if (this.phoneVerified && this.hasOnchainAddress) {
this.tokenOnboardingComplete = true;
}
......@@ -135,6 +134,7 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
};
// Handle currency formatting for cash
// TODOOJM this isn't going to work
if (currency === 'cash') {
if (this.wallet.cash.unit === 'cash') {
headerTab.unit = 'usd';
......@@ -165,32 +165,33 @@ export class WalletDashboardComponent implements OnInit, OnDestroy {
this.detectChanges();
}
scrollToSettings(currency: string) {
if (this.activeCurrencyId !== currency) {
this.router.navigate([`/wallet/${currency}/settings`]);
} else {
const settingsEl =
currency === 'cash'
? this.cashSettingsEl.nativeElement
: this.tokenSettingsEl.nativeElement;
onchainAddressChanged() {
this.hasOnchainAddress = true;
this.detectChanges();
if (!settingsEl) {
this.updateView('settings');
}
}
this.loadWallet();
}
if (isPlatformBrowser(this.platformId)) {
setTimeout(
() =>
this.dashboardViewsEl.nativeElement.scrollIntoView({
behavior: 'smooth',
}),
0
);
scrollToSettings(currency: string) {
if (
this.activeCurrencyId !== currency ||
this.activeViewId !== 'settings'
) {
this.router.navigate([`/wallet/${currency}/settings`]).then(() => {
this.scrollToSettingsEl();
});
} else {
this.scrollToSettingsEl();
}
this.detectChanges();
}
scrollToSettingsEl() {
this.dashboardViewsEl.nativeElement.scrollIntoView({
behavior: 'smooth',
});
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
......
......@@ -5,11 +5,24 @@ import { Web3WalletService } from '../../blockchain/web3-wallet.service';
import { TokenContractService } from '../../blockchain/contracts/token-contract.service';
import toFriendlyCryptoVal from '../../../helpers/friendly-crypto';
export interface SplitBalance {
total: number;
int: number;
frac: number | null;
}
export interface StripeDetails {
pendingBalance: SplitBalance;
totalPaidOut: SplitBalance;
isLocalCurrency: boolean;
}
export interface WalletCurrency {
label: string;
unit: string;
balance: number;
address: string | null;
stripeDetails?: StripeDetails;
}
export interface Wallet {
......@@ -23,7 +36,6 @@ export interface Wallet {
}
@Injectable()
export class WalletDashboardService {
walletLoaded = false;
totalTokens = 0;
wallet: Wallet = {
tokens: {
......@@ -82,7 +94,7 @@ export class WalletDashboardService {
await this.getEthAccount();
await this.getStripeAccount();
this.walletLoaded = true;
console.log('***', this.wallet);
return this.wallet;
}
......@@ -155,16 +167,19 @@ export class WalletDashboardService {
}
async getEthAccount() {
const address = await this.web3Wallet.getCurrentWallet();
if (!address) {
return;
}
this.wallet.eth.address = address;
const ethBalance = await this.web3Wallet.getBalance(address);
if (ethBalance) {
this.wallet.eth.balance = toFriendlyCryptoVal(ethBalance);
try {
const address = await this.web3Wallet.getCurrentWallet();
if (address) {
this.wallet.eth.address = address;
const ethBalance = await this.web3Wallet.getBalance(address);
if (ethBalance) {
this.wallet.eth.balance = toFriendlyCryptoVal(ethBalance);
}
}
return this.wallet.eth;
} catch (e) {
console.error(e);
}
return this.wallet.eth;
}
async getStripeAccount() {
......@@ -175,21 +190,32 @@ export class WalletDashboardService {
const { account } = <any>(
await this.client.get('api/v2/payments/stripe/connect')
);
if (account) {
console.log('svc getAcc', account);
this.wallet.cash.address = 'stripe';
this.wallet.cash.balance =
(account.totalBalance.amount - account.pendingBalance.amount) / 100;
if (account.bankAccount) {
const bankCurrency: string = account.bankAccount.currency;
this.wallet.cash.label = bankCurrency.toUpperCase();
this.wallet.cash.unit = bankCurrency;
} else {
// Has stripe account but not setup bank account
this.wallet.cash.label = 'USD';
this.wallet.cash.unit = 'usd';
}
const friendlyAccount = { ...account };
console.log('svc getAcc', account);
this.wallet.cash.address = 'stripe';
this.wallet.cash.balance =
(account.totalBalance.amount - account.pendingBalance.amount) / 100;
if (!account.bankAccount) {
// Has stripe account but not setup bank account
this.wallet.cash.label = 'USD';
this.wallet.cash.unit = 'usd';
friendlyAccount.isLocalCurrency = false;
} else {
const bankCurrency: string = account.bankAccount.currency;
this.wallet.cash.label = bankCurrency.toUpperCase();
this.wallet.cash.unit = bankCurrency;
friendlyAccount.isLocalCurrency = true;
}
// TODOOJM
//pendingBalanceFriendly
// totalPaidOutFriendly = (account.totalBalance.amount - account.pendingBalance.amount) / 100;
// formatBalance(int, frac, total)
//return friendlyAccount
return account;
} catch (e) {
console.error(e);
......@@ -201,6 +227,7 @@ export class WalletDashboardService {
}
async createStripeAccount(form) {
console.log('creatingstripeaccount', form);
try {
const response = <any>(
await this.client.put('api/v2/wallet/usd/account', form)
......@@ -268,7 +295,6 @@ export class WalletDashboardService {
);
return response;
// TODOOJM toggle fake data
// return fakeData.tx_usd;
} catch (e) {
console.error(e);
......@@ -276,22 +302,6 @@ export class WalletDashboardService {
}
}
async getStripePayouts() {
try {
const response = <any>(
await this.client.get(
'api/v1/monetization/service/analytics/list?offset=&limit=12&type=payouts'
)
);
// TODOOJM toggle fake data
return response.transactions;
} catch (e) {
console.error(e);
return;
}
}
async getTokenChart(activeTimespanId) {
const opts = {
metric: 'token_balance',
......@@ -384,4 +394,23 @@ export class WalletDashboardService {
return false;
}
}
// Returns an object with separated dollars and cents
// as well as the original total
public splitBalance(balance) {
const splitBalance: SplitBalance = {
total: balance,
int: 0,
frac: null,
};
const balanceArray = balance.toString().split('.');
splitBalance.int = balanceArray[0];
if (balanceArray[1]) {
splitBalance.frac = balanceArray[1].slice(0, 2);
}
return splitBalance;
}
}
......@@ -120,13 +120,14 @@ m-walletModal {
.m-walletModal {
padding: 46px 50px;
max-width: 80vw;
width: 80vw;
max-height: 90vh;
}
}
@media screen and (max-width: $max-mobile) {
.m-walletModal {
padding: 26px 35px;
max-width: 90vw;
width: 90vw;
max-height: 95vh;
}
}
......
......@@ -20,7 +20,6 @@ m-walletPhoneVerification {
width: 100%;
}
}
// TODOOJM tweak this so countryList max-height doesn't overflow
@media screen and (max-width: 771px) {
m-shadowboxSubmitButton {
margin: 0 0 21px 0;
......@@ -46,10 +45,5 @@ m-walletPhoneVerification {
}
}
}
m-phoneInput {
.m-phoneInput__countryList {
max-height: 200px;
}
}
}
}
<div *ngIf="!loaded" class="m-wallet__spinner">
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div>
<div class="m-walletSettings" *ngIf="loaded">
<!---PROVIDE ADDRESS---------------------------->
<div
......
......@@ -3,7 +3,6 @@ import {
ChangeDetectorRef,
Component,
OnInit,
EventEmitter,
} from '@angular/core';
import {
FormGroup,
......@@ -36,18 +35,25 @@ export class WalletSettingsBTCComponent implements OnInit {
) {}
ngOnInit() {
this.load();
}
async load() {
// Check if already has an address
const { address } = <any>await this.client.get('api/v2/wallet/btc/address');
this.currentAddress = address;
this.form = new FormGroup({
addressInput: new FormControl('', {
validators: [Validators.required, this.validateAddressFormat],
}),
});
this.load();
}
async load() {
try {
// Check if already has an address
const { address } = <any>(
await this.client.get('api/v2/wallet/btc/address')
);
if (address) {
this.currentAddress = address;
}
} catch (e) {
console.error(e);
}
this.loaded = true;
this.detectChanges();
}
......
......@@ -2,7 +2,7 @@
<!-- HAS NOT SET UP BANK ACCOUNT / IS UPDATING BANK ACCOUNT ------------------ -->
<ng-container *ngIf="!leftMonetization">
<form [formGroup]="form" *ngIf="!hasBankAccount() || editing">
<p>Enter bank account details to receive payments.</p>
<p>Finish adding your bank details to start receiving cash payouts.</p>
<!-- ***INPUT COUNTRY DROPDOWN-->
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletSettings__row--label">
......
<div class="m-walletOnboardingExtrasForm" *ngIf="account">
<p>Start receiving cash payouts by adding your bank details.</p>
<!-- **** INPUT: PHOTO ID -->
<ng-container
*ngIf="account.requirement.indexOf('individual.verification.document') > -1"
......
......@@ -8,8 +8,8 @@
<div class="m-walletCashOnboardingView--form" *ngIf="editing">
<form [formGroup]="form">
<p>Enter personal details to start setting up your cash account.</p>
<!-- ------------------------------------------------------------ -->
<p>Start receiving cash payouts by adding your bank details.</p>
<!-- ----------------------------------------------- -->
<!-- **** INPUT: COUNTRY DROPDOWN -->
<div class="m-walletForm__multifieldGroup">
......
<div class="mdl-spinner mdl-js-spinner is-active" [mdl] *ngIf="!loaded"></div>
<div *ngIf="!loaded" class="m-wallet__spinner">
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div>
<div class="m-walletSettings" *ngIf="loaded">
<h4>Bank Information</h4>
<!-- ONBOARDING FORM ------------------ -->
......
......@@ -4,8 +4,9 @@ import {
ChangeDetectorRef,
Output,
EventEmitter,
Input,
} from '@angular/core';
import { WalletDashboardService } from '../dashboard.service';
import { WalletDashboardService, WalletCurrency } from '../dashboard.service';
import { Session } from '../../../../services/session';
@Component({
......@@ -13,6 +14,7 @@ import { Session } from '../../../../services/session';
templateUrl: './settings-cash.component.html',
})
export class WalletSettingsCashComponent implements OnInit {
@Input() cashWallet: WalletCurrency; // TODOOJM handle
@Output() accountChanged: EventEmitter<any> = new EventEmitter<any>();
@Output() scrollToCashSettings: EventEmitter<any> = new EventEmitter<any>();
......@@ -69,13 +71,13 @@ export class WalletSettingsCashComponent implements OnInit {
// 2. bank
// 3. (if necessary) extras
// 4. (once verified) bank
console.log('888 ... setting view');
const previousView = this.view;
// this.view = null;
this.inProgress = true;
this.detectChanges();
const hasMerchant = this.user && this.user.merchant.id;
const hasMerchant = this.user && this.user.merchant.service === 'stripe';
if (!hasMerchant) {
this.view = 'onboarding';
......
<div class="m-walletSettings" *ngIf="ethWallet">
<!-- <div *ngIf="!ethWallet" class="m-wallet__spinner">
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div> -->
<!-- <div class="m-walletSettings" *ngIf="ethWallet"> -->
<div class="m-walletSettings">
<h2>Ether Address</h2>
<p>
Your Ether address is the same as your on-chain address.<m-tooltip
......
import {
Component,
OnInit,
Output,
EventEmitter,
ChangeDetectorRef,
Input,
} from '@angular/core';
import { WalletDashboardService, WalletCurrency } from '../dashboard.service';
......@@ -11,24 +11,40 @@ import { WalletDashboardService, WalletCurrency } from '../dashboard.service';
selector: 'm-walletSettings--eth',
templateUrl: './settings-eth.component.html',
})
export class WalletSettingsETHComponent implements OnInit {
ethWallet: WalletCurrency;
export class WalletSettingsETHComponent {
@Input() ethWallet: WalletCurrency;
@Output() scrollToTokenSettings: EventEmitter<any> = new EventEmitter();
constructor(
protected walletService: WalletDashboardService,
private cd: ChangeDetectorRef
) {}
constructor() {}
// protected walletService: WalletDashboardService,
// private cd: ChangeDetectorRef
// {}
ngOnInit() {
this.load();
}
// ngOnInit() {
// this.load();
// }
async load() {
this.ethWallet = await this.walletService.getEthAccount();
this.detectChanges();
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
// async load() {
// this.inProgress = true;
// this.error = '';
// this.walletService
// .getStripeAccount()
// .then((account: any) => {
// this.account = account;
// this.setView();
// })
// .catch(e => {
// this.error = e.message;
// this.view = 'error';
// this.inProgress = false;
// this.detectChanges();
// });
// this.ethWallet = await this.walletService.getEthAccount();
// this.detectChanges();
// }
// detectChanges() {
// this.cd.markForCheck();
// this.cd.detectChanges();
// }
}
<div *ngIf="!wallet" class="m-wallet__spinner">
<div class="mdl-spinner mdl-js-spinner is-active" [mdl]></div>
</div>
<div class="m-walletSettings" *ngIf="wallet">
<div class="m-walletSettingsView--setup" *ngIf="!display">
<h4>
......
......@@ -41,7 +41,7 @@ enum Views {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
@Output() addressSetupComplete: EventEmitter<any> = new EventEmitter();
@Output() onchainAddressChanged: EventEmitter<any> = new EventEmitter();
wallet;
inProgress: boolean = false;
linkingMetamask: boolean = false;
......@@ -81,6 +81,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
ngOnInit() {
this.load();
}
async load() {
this.wallet = await this.walletService.getWallet();
// Check if already has an address
......@@ -88,7 +89,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
this.session.getLoggedInUser().eth_wallet || this.wallet.receiver.address;
if (this.currentAddress) {
this.display = Views.CurrentAddress;
this.addressSetupComplete.emit();
this.onchainAddressChanged.emit();
}
this.form = new FormGroup({
......@@ -144,7 +145,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, filename);
this.inProgress = false;
this.addressSetupComplete.emit();
this.onchainAddressChanged.emit();
this.detectChanges();
} else {
const link = window.document.createElement('a'),
......@@ -161,7 +162,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
setTimeout(() => {
URL.revokeObjectURL(objectUrl);
this.generatedAccount = null;
this.addressSetupComplete.emit();
this.onchainAddressChanged.emit();
this.inProgress = false;
if (!(this.cd as ViewRef).destroyed) {
this.detectChanges();
......@@ -194,7 +195,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
this.detectChanges();
await this.blockchain.setWallet({ address: this.addressInput.value });
this.addressSetupComplete.emit();
this.onchainAddressChanged.emit();
} catch (e) {
// TODOOJM get rid of form toast
this.formToastService.error(e);
......@@ -269,7 +270,7 @@ export class WalletSettingsTokensComponent implements OnInit, OnDestroy {
await this.blockchain.setWallet({ address: address });
this.currentAddress = address;
this.display = Views.CurrentAddress;
this.addressSetupComplete.emit();
this.onchainAddressChanged.emit();
} catch (e) {
// TODOOJM get rid of form toast
this.formToastService.error(e);
......
......@@ -18,11 +18,11 @@
<span>2.</span>
<a
(click)="clickedAddressStep()"
[ngClass]="{ disabled: !phoneVerified, stepComplete: addressAdded }"
[ngClass]="{ disabled: !phoneVerified, stepComplete: hasAddress }"
>
Add your on-chain address</a
>
<i class="material-icons" *ngIf="addressAdded">check</i>
<i class="material-icons" *ngIf="hasAddress">check</i>
</div>
<div class="m-walletTokenOnboardingStep__desc">
Your Ethereum address allows you to start receiving payments on the
......
......@@ -88,11 +88,6 @@ m-walletTokenOnboarding {
}
// ***************************************************
@media screen and (max-width: $max-mobile) {
[class*='m-walletTokenOnboardingStep--'] {
padding: 19px;
}
}
@media screen and (max-width: 890px) {
[class*='m-walletTokenOnboardingStep--'] {
......
import {
Component,
OnInit,
Input,
Output,
EventEmitter,
ChangeDetectionStrategy,
ChangeDetectorRef,
} from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Session } from '../../../../services/session';
import { FormToastService } from '../../../../common/services/form-toast.service';
import { Session } from '../../../../services/session';
type TokenOnboardingStep = 'phone' | 'address';
@Component({
selector: 'm-walletTokenOnboarding',
templateUrl: './token-onboarding.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WalletTokenOnboardingComponent implements OnInit {
phoneVerified = false;
addressAdded = false;
export class WalletTokenOnboardingComponent {
private _hasAddress: boolean;
@Input() set hasAddress(value: boolean) {
this._hasAddress = value;
if (value) {
this.addressSetupComplete();
}
this.detectChanges();
}
get hasAddress(): boolean {
return this._hasAddress;
}
private _phoneVerified: boolean;
@Input() set phoneVerified(value: boolean) {
this._phoneVerified = value;
if (value) {
this.phoneVerificationComplete();
}
this.detectChanges();
}
get phoneVerified(): boolean {
return this._phoneVerified;
}
showModal = false;
activeStep = 'phone'; // || address
activeStep: TokenOnboardingStep = 'phone';
user;
@Output() onboardingComplete: EventEmitter<any> = new EventEmitter();
@Output() scrollToTokenSettings: EventEmitter<any> = new EventEmitter();
constructor(
protected session: Session,
protected cd: ChangeDetectorRef,
private formToastService: FormToastService,
protected router: Router,
private route: ActivatedRoute
protected session: Session
) {}
ngOnInit() {
this.phoneVerified = this.session.getLoggedInUser().rewards;
this.addressAdded = this.session.getLoggedInUser().eth_wallet;
if (this.phoneVerified && this.addressAdded) {
this.onboardingComplete.emit();
}
this.detectChanges();
}
clickedPhoneStep() {
if (!this.phoneVerified) {
this.activeStep = 'phone';
......@@ -51,7 +62,7 @@ export class WalletTokenOnboardingComponent implements OnInit {
}
clickedAddressStep() {
if (!this.addressAdded) {
if (!this.hasAddress) {
this.activeStep = 'address';
this.scrollToTokenSettings.emit();
}
......@@ -59,29 +70,36 @@ export class WalletTokenOnboardingComponent implements OnInit {
}
phoneVerificationComplete() {
this.phoneVerified = true;
this._phoneVerified = true;
this.session.getLoggedInUser().rewards = true;
this.showModal = false;
this.formToastService.success('Your phone number has been verified');
if (!this.addressAdded) {
if (!this._hasAddress) {
this.activeStep = 'address';
this.detectChanges();
} else {
this.onboardingComplete.emit();
this.finishedOnboarding();
}
}
addressSetupComplete() {
this.addressAdded = true;
this._hasAddress = true;
this.session.getLoggedInUser().eth_wallet = true;
this.showModal = false;
if (!this.phoneVerified) {
if (!this._phoneVerified) {
this.activeStep = 'phone';
this.detectChanges();
} else {
this.formToastService.success(
"Congratulations! You're ready to start earning rewards"
);
this.onboardingComplete.emit();
this.finishedOnboarding();
}
}
finishedOnboarding() {
this.formToastService.success(
"You're ready to start earning token rewards!"
);
this.onboardingComplete.emit();
this.detectChanges();
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
......
......@@ -5,7 +5,7 @@
<ng-container *ngIf="init">
<div
class="m-walletTransactionsTable__wrapper"
*ngIf="transactions.length >= 1 || !noAccount"
*ngIf="transactions.length !== 0"
>
<m-walletTransactionsTable
[currency]="currency"
......@@ -21,7 +21,7 @@
</div>
<div
class="m-walletTransactions__noTxNotice"
*ngIf="transactions.length === 0 || noAccount"
*ngIf="transactions.length === 0"
>
<p>You don't have any cash transactions yet.</p>
</div>
......
......@@ -10,7 +10,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { Client } from '../../../../services/api/client';
import { Session } from '../../../../services/session';
import { Web3WalletService } from '../../../blockchain/web3-wallet.service';
import { WalletDashboardService } from '../dashboard.service';
import { WalletDashboardService, WalletCurrency } from '../dashboard.service';
import * as moment from 'moment';
......@@ -21,6 +21,7 @@ import * as moment from 'moment';
})
export class WalletTransactionsCashComponent implements OnInit {
@Input() noAccount: boolean = false;
@Input() cashWallet: WalletCurrency; // TODOOJM USE ME
init: boolean = false;
inProgress: boolean = true;
......@@ -47,6 +48,7 @@ export class WalletTransactionsCashComponent implements OnInit {
) {}
ngOnInit() {
console.log('cash transactions noAccount: ', this.noAccount);
if (!this.noAccount) {
this.getStripeAccount();
} else {
......@@ -58,13 +60,13 @@ export class WalletTransactionsCashComponent implements OnInit {
async getStripeAccount() {
try {
const account = await this.walletService.getStripeAccount();
console.log('txcashAcct', account);
if (account) {
if (account.bankAccount) {
this.currency = account.bankAccount.currency.toUpperCase();
}
this.runningTotal = account.pendingBalance.amount / 100;
this.loadTransactions(true);
}
} catch (e) {
console.error(e);
......@@ -76,24 +78,6 @@ export class WalletTransactionsCashComponent implements OnInit {
}
}
// const account = await this.walletService.getStripeAccount();
// console.log('txcashAcct', account);
// if (!account) {
// this.init = true;
// this.detectChanges();
// return;
// } else {
// if (account.bankAccount) {
// this.currency = account.bankAccount.currency.toUpperCase();
// }
// this.runningTotal = account.pendingBalance.amount / 100;
// this.detectChanges();
// }
// this.loadTransactions(true);
// }
async loadTransactions(refresh: boolean) {
if (this.inProgress && !refresh) {
return;
......@@ -117,12 +101,8 @@ export class WalletTransactionsCashComponent implements OnInit {
opts
);
if (refresh) {
this.transactions = [];
}
if (response) {
if (response && response.transactions) {
if (response.transactions) {
this.formatResponse(response.transactions);
}
......@@ -143,6 +123,11 @@ export class WalletTransactionsCashComponent implements OnInit {
} finally {
this.init = true;
this.inProgress = false;
console.log(
'cash transactions:',
this.transactions.length,
this.transactions
);
this.detectChanges();
}
}
......
......@@ -30,7 +30,7 @@
></m-dropdownSelector>
</div>
</div>
<ng-container *ngIf="transactions.length >= 1">
<ng-container *ngIf="transactions.length !== 0">
<m-walletTransactionsTable
currency="tokens"
[transactions]="transactions"
......
......@@ -146,12 +146,8 @@ export class WalletTransactionsTokensComponent implements OnInit, OnDestroy {
const response: any = await this.walletService.getTokenTransactions(opts);
if (refresh) {
this.transactions = [];
}
if (response) {
if (response && response.transactions) {
if (response.transactions) {
this.formatResponse(response.transactions);
}
......
Please register or to comment