...
 
Commits (3)
This diff is collapsed.
<!-- <select>
<option value="" disabled hidden
><i i18n="@@M__COMMON__COUNTRY">Country</i></option
>
<option *ngFor="let country of filteredCountries" [value]="country.code">{{
country.name
}}</option>
</select> -->
<!-- --------------------------------- -->
<!-- <div
class="form-control m-countryInput__wrapper"
(click)="showDropdown ? closeDropdown() : openDropdown()"
[ngModel]="country"
(ngModelChange)="country = $event; countryChange.next($event)"
>
<div class="m-countryInput__selectedCountry">
<div class="m-countryInput__selectedCountryName">
{{ selectedCountry.name }}
</div>
<div class="m-countryInput__arrow" [ngClass]="{ up: showDropdown }"></div>
</div>
<ul
class="m-countryInput__countryList dropdown"
id="m-countryInput__countryList"
#dropdown
[hidden]="!showDropdown"
>
<li
*ngFor="let country of filteredCountries; let i = index"
class="m-countryInput__option"
(click)="onCountrySelect(i)"
[attr.data-index]="i"
tabindex="0"
(mouseenter)="onMouseEnter(i)"
[ngClass]="{ focused: focusedCountryIndex === i }"
#countryEl
>
<div class="m-countryInput__flagBox">
<div class="m-countryInput__flag" [ngClass]="country.flagClass"></div>
</div>
<span class="m-countryInput__countryName">{{ country.name }}</span>
<span
class="m-countryInput__dialCode"
[attr.data-minds]="country.dialCode"
>
+{{ country.dialCode }}
</span>
</li>
</ul>
<div
class="m-countryInput__wrapper"
[ngClass]="{
dropdownShown: showDropdown,
focused: showDropdown || inputFocused,
invalid: invalid
}"
#wrapper
>
<m-countryInput__country
[initCountryCode]="initCountryCode"
[allowedCountries]="allowedCountries"
(countrySelected)="countrySelected($event)"
(toggledDropdown)="toggledDropdown($event)"
[showDropdown]="showDropdown"
></m-countryInput__country> -->
<!-- <input
type="tel"
id="phone"
autocomplete="off"
placeholder="916-555-5555"
(keypress)="onInputKeyPress($event)"
[(ngModel)]="phoneNumber"
(ngModelChange)="onPhoneNumberChange()"
[placeholder]="selectedCountry.placeHolder"
class="form-control m-countryInput__input"
(click)="clickedInput($event)"
(focusout)="inputFocused = false"
#input
required
autofocus
/> -->
<!-- </div>
</div> -->
m-countryInput {
position: relative;
display: inline-flex;
margin-bottom: $minds-padding;
flex-grow: 1;
@media (max-width: $max-mobile) {
width: 100%;
input {
width: 100%;
}
}
span {
font-weight: 300;
}
.m-countryInput__wrapper {
flex-grow: 1;
display: flex;
justify-content: flex-start;
flex-flow: row nowrap;
align-items: center;
@include m-theme() {
background-color: themed($m-white);
border: 1px solid themed($m-borderColor--primary);
}
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
&.dropdownShown {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
&.focused {
@include m-theme() {
border-color: themed($m-blue);
}
.m-countryInput__input {
@include m-theme() {
border-color: themed($m-blue);
}
}
}
&.invalid {
@include m-theme() {
border-color: themed($m-alert);
}
input {
@include m-theme() {
border-color: themed($m-alert);
}
}
}
}
.m-countryInput__selectedCountry {
z-index: 1;
position: relative;
height: 36px;
padding: 0 0 0 8px;
border: 0;
border-right: 0;
display: inline-flex;
align-items: center;
cursor: pointer;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
outline: 0;
@include m-theme() {
background-color: themed($m-white);
}
.m-countryInput__selectedCountryName {
margin-left: 5px;
@include m-theme() {
color: themed($m-grey-300);
}
}
.m-countryInput__arrow {
margin: 0 5px;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
@include m-theme() {
border-top: 6px solid themed($m-grey-100);
}
}
.m-countryInput__arrow.up {
border-top: none;
@include m-theme() {
border-bottom: 6px solid themed($m-grey-100);
border-top: none;
}
}
}
.m-countryInput__input {
flex: 1 1 auto;
height: 100%;
padding: 10px;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
@include m-theme() {
background-color: themed($m-white);
border-left: 1px solid themed($m-grey-50);
}
&:focus {
outline: none;
}
}
m-countryInput__country {
flex: 0 1 auto;
}
.m-countryInput__countryList {
position: absolute;
z-index: 2;
list-style: none;
text-align: left;
padding: 0;
margin: 0;
top: 40px;
left: 0;
width: 100%;
white-space: nowrap;
max-height: 200px;
overflow-y: scroll;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
@include m-theme() {
box-shadow: 0 1px 4px 0 rgba(themed($m-black), 0.1);
background-color: themed($m-white);
border: 1px solid themed($m-blue);
border-top: none;
}
&.dropdown {
flex-direction: column !important;
}
@media (max-width: 500px) {
white-space: normal;
}
.m-countryInput__country {
cursor: pointer;
padding: 8;
overflow: hidden;
text-overflow: ellipsis;
outline: none;
transition: all 0.2s cubic-bezier(0.23, 1, 0.32, 1);
.m-countryInput__dialCode {
@include m-theme() {
color: themed($m-grey-300);
}
}
&:focus,
&.focused {
@include m-theme() {
background-color: rgba(themed($m-grey-50), 0.4);
}
}
&:active {
@include m-theme() {
background-color: rgba(themed($m-grey-50), 0.7);
}
}
}
}
.m-countryInput__dropup {
bottom: 100%;
margin-bottom: -1px;
}
.m-countryInput__flagBox {
display: inline-block;
width: 20px;
}
.m-countryInput__divider {
padding-bottom: 5px;
margin-bottom: 5px;
background-color: transparent;
margin-top: 0;
@include m-theme() {
border-bottom: 1px solid themed($m-grey-100);
}
}
&.country:not(:last-child) {
@include m-theme() {
border-bottom: 1px solid themed($m-grey-50);
}
}
.m-countryInput__countryList .m-countryInput__flagBox,
.m-countryInput__countryList .m-countryInput__countryName,
.m-countryInput__countryList .m-countryInput__dialCode {
vertical-align: middle;
}
.m-countryInput__countryList .m-countryInput__flagBox,
.m-countryInput__countryList .m-countryInput__countryName {
margin-right: 6px;
}
}
// minds-country-input {
// display: inline-block;
// max-width: 100%;
// position: relative;
// &::before {
// content: '\25bc';
// position: absolute;
// pointer-events: none;
// top: 0;
// bottom: 1px;
// padding-top: 0.7em;
// line-height: 1;
// right: 0;
// width: 2em;
// text-align: center;
// transform: scale(0.84, 0.42);
// filter: progid:DXImageTransform.Microsoft.Matrix(M11=.84, M12=0, M21=0, M22=.42, SizingMethod='auto expand');
// @include m-theme() {
// color: themed($m-grey-500);
// }
// }
// select {
// padding: 8px 40px 8px 8px;
// max-width: 100%;
// appearance: none;
// display: block;
// width: 100%;
// font-family: 'Roboto', Helvetica, sans-serif;
// @include m-theme() {
// border: 1px solid themed($m-grey-100);
// }
// }
// }
// import {
// Component,
// EventEmitter,
// OnInit,
// AfterViewInit,
// OnChanges,
// Input,
// Output,
// forwardRef,
// Inject,
// PLATFORM_ID,
// ElementRef,
// QueryList,
// ViewChildren,
// } from '@angular/core';
// import { isPlatformBrowser } from '@angular/common';
// import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
// import { verticallyScrollElementIntoView } from '../../../../helpers/scrollable-container-visibility';
// import * as moment from 'moment';
// // export const COUNTRY_INPUT_VALUE_ACCESSOR: any = {
// // provide: NG_VALUE_ACCESSOR,
// // useExisting: forwardRef(() => CountryInputV2Component),
// // multi: true,
// // };
// @Component({
// selector: 'm-countryInput',
// templateUrl: 'country-input-v2.component.html',
// // providers: [COUNTRY_INPUT_VALUE_ACCESSOR],
// })
// export class CountryInputV2Component {
// @Input() initCountryCode: string = '';
// @Input('allowedCountries') set _allowed(allowed: string[]) {
// if (!allowed) {
// this.filteredCountries = this.countries;
// return;
// }
// this.filteredCountries = this.countries.filter(item => {
// return allowed.indexOf(item.code) > -1;
// });
// }
// @Output() countryChange: EventEmitter<any> = new EventEmitter();
// countries;
// filteredCountries: Array<{ name: string; code: string }> = [];
// showDropdown: boolean = false;
// countryCode: string;
// init: boolean = false;
// countryEls;
// selectedCountry;
// selectedCountryIndex = 0;
// focused: boolean = false;
// focusedCountryIndex = 0;
// toggleTimeout;
// scrollTimeout;
// @ViewChildren('countryEl') countryElsList: QueryList<ElementRef>;
// propagateChange = (_: any) => {};
// constructor() {}
// ngOnInit() {}
// ngAfterViewInit() {
// this.countryEls = this.countryElsList.toArray();
// }
// ngOnChanges(changes: any) {
// this.propagateChange(changes);
// }
// ngOnDestroy() {
// this.showDropdown = false;
// }
// }
......@@ -11,8 +11,9 @@ import {
ViewChildren,
QueryList,
OnDestroy,
Inject,
PLATFORM_ID,
} from '@angular/core';
import { Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { verticallyScrollElementIntoView } from '../../../helpers/scrollable-container-visibility';
......@@ -27,8 +28,10 @@ import * as moment from 'moment';
export class PhoneInputCountryV2Component
implements OnInit, AfterViewInit, OnDestroy {
@Input() showDropdown: boolean = false;
@Input() initCountryCode: string;
@Input() allowedCountries: string[];
@Output() toggledDropdown: EventEmitter<any> = new EventEmitter();
@Output('country') selectedCountryEvt: EventEmitter<any> = new EventEmitter();
@Output() countrySelected: EventEmitter<any> = new EventEmitter();
@ViewChild('input', { static: false }) input: ElementRef;
@ViewChild('dropdown', { static: true }) dropdown: ElementRef;
......@@ -51,7 +54,12 @@ export class PhoneInputCountryV2Component
ngOnInit() {
this.closeDropdown();
this.fetchCountryData();
if (this.initCountryCode) {
this.setInitCountry();
}
this.onCountrySelect(this.selectedCountryIndex);
}
......@@ -63,7 +71,7 @@ export class PhoneInputCountryV2Component
this.focusedCountryIndex = i;
this.selectedCountryIndex = i;
this.selectedCountry = this.countries[i];
this.selectedCountryEvt.next(this.selectedCountry);
this.countrySelected.next(this.selectedCountry);
if (this.showDropdown) {
this.closeDropdown();
}
......@@ -155,19 +163,47 @@ export class PhoneInputCountryV2Component
}
}
countryIsAllowed(iso2) {
return this.allowedCountries.indexOf(iso2) > -1;
}
protected fetchCountryData(): void {
for (let i = 0; i < this.allowedCountries.length; i++) {
this.allowedCountries[i] = this.allowedCountries[i].toLowerCase();
}
this.countryCodeData.countries.forEach(c => {
const country = new Country();
country.name = c[0].toString();
country.iso2 = c[1].toString();
country.dialCode = c[2].toString();
country.priority = +c[3] || 0;
country.areaCode = +c[4] || null;
country.flagClass = country.iso2.toLocaleLowerCase();
this.countries.push(country);
if (
this.allowedCountries.length === 0 ||
this.countryIsAllowed(c[1].toString())
) {
this.pushCountry(c);
}
});
}
pushCountry(c) {
const country = new Country();
country.name = c[0].toString();
country.iso2 = c[1].toString();
country.dialCode = c[2].toString();
country.priority = +c[3] || 0;
country.areaCode = +c[4] || null;
country.flagClass = country.iso2.toLocaleLowerCase();
this.countries.push(country);
}
setInitCountry() {
this.initCountryCode = this.initCountryCode.toLowerCase();
const initCountryIndex = this.countries.findIndex(c => {
return this.initCountryCode === c.iso2;
});
if (initCountryIndex > -1) {
this.selectedCountryIndex = initCountryIndex;
}
}
ngOnDestroy() {
if (this.toggleTimeout) {
clearTimeout(this.toggleTimeout);
......
<div
class="m-phoneInput__wrapper m-walletForm__row--input"
class="m-phoneInput__wrapper"
[ngClass]="{
dropdownShown: showDropdown,
focused: showDropdown || inputFocused,
......@@ -8,7 +8,9 @@
#wrapper
>
<m-phoneInput__country
(country)="countrySelected($event)"
[initCountryCode]="initCountryCode"
[allowedCountries]="allowedCountries"
(countrySelected)="countrySelected($event)"
(toggledDropdown)="toggledDropdown($event)"
[showDropdown]="showDropdown"
></m-phoneInput__country>
......@@ -26,7 +28,5 @@
(click)="clickedInput($event)"
(focusout)="inputFocused = false"
#input
required
autofocus
/>
</div>
......@@ -9,11 +9,8 @@ import {
Input,
HostListener,
} from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Country } from './country';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CountryCode } from './countries';
export const PHONE_INPUT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
......@@ -29,6 +26,8 @@ export const PHONE_INPUT_VALUE_ACCESSOR: any = {
export class PhoneInputV2Component
implements ControlValueAccessor, OnInit, OnChanges, OnDestroy {
@Input() invalid: boolean = false;
@Input() initCountryCode: string = '';
@Input() allowedCountries: string[] = [];
phoneNumber: string = '';
showDropdown: boolean = false;
......@@ -37,13 +36,24 @@ export class PhoneInputV2Component
@ViewChild('wrapper', { static: true }) wrapper: ElementRef;
@ViewChild('input', { static: true }) input: ElementRef;
selectedCountry;
init: boolean = false;
propagateChange = (_: any) => {};
constructor(private fb: FormBuilder) {}
constructor() {}
ngOnInit() {}
countrySelected($event) {
this.selectedCountry = $event;
this.onPhoneNumberChange();
if (this.init) {
this.input.nativeElement.focus();
this.inputFocused = true;
}
this.init = true;
}
public onPhoneNumberChange(): void {
this.propagateChange(this.number);
}
......@@ -64,10 +74,6 @@ export class PhoneInputV2Component
return this.selectedCountry.dialCode + this.phoneNumber;
}
ngOnChanges(changes: any) {
this.propagateChange(changes);
}
writeValue(value: any) {
if (value && value.length > 10) {
this.phoneNumber = value.substring(value.length - 11, value.length - 1);
......@@ -84,13 +90,6 @@ export class PhoneInputV2Component
this.showDropdown = $event.showDropdown;
}
countrySelected($event) {
this.selectedCountry = $event;
this.onPhoneNumberChange();
this.input.nativeElement.focus();
this.inputFocused = true;
}
clickedInput($event) {
$event.stopPropagation();
this.inputFocused = true;
......@@ -102,6 +101,10 @@ export class PhoneInputV2Component
this.showDropdown = false;
}
ngOnChanges(changes: any) {
this.propagateChange(changes);
}
ngOnDestroy() {
this.showDropdown = false;
}
......
......@@ -5,7 +5,7 @@ m-shadowboxHeader {
font-weight: 400;
text-decoration: none;
@include m-theme() {
color: themed($m-blue);
color: themed($m-link);
}
}
}
......@@ -48,7 +48,7 @@ m-shadowboxHeader {
z-index: 2;
opacity: 0;
transition: opacity 0.2s ease, width 0.4s ease;
cursor: pointer;
&.m-shadowboxHeader__overflowFade--right {
@include m-theme() {
right: 0;
......@@ -72,6 +72,7 @@ m-shadowboxHeader {
&.visible {
opacity: 1;
width: 24px;
cursor: pointer;
}
}
......@@ -95,7 +96,7 @@ m-shadowboxHeader {
}
&:hover {
@include m-theme() {
border: 1px solid themed($m-blue);
border: 1px solid themed($m-link);
}
}
&.m-shadowboxHeader__overflowScrollButton--right {
......@@ -118,7 +119,7 @@ m-shadowboxHeader {
line-height: 32px;
font-weight: 500;
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
font-size: 24px;
}
}
......@@ -126,7 +127,7 @@ m-shadowboxHeader {
line-height: 22px;
margin: 0;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
font-size: 15px;
}
}
......
......@@ -11,7 +11,7 @@
outline: 0;
&.green {
@include m-theme() {
background-color: themed($m-btn--primary);
background-color: themed($m-aqua);
color: themed($m-white);
}
.m-shadowboxSubmitButton__status--saving {
......@@ -59,7 +59,7 @@
}
&.green {
@include m-theme() {
background-color: themed($m-btn--primary);
background-color: rgba(themed($m-aqua), 0.8);
}
}
&.red {
......@@ -84,7 +84,7 @@
}
&.green {
@include m-theme() {
background-color: themed($m-btn--primary);
background-color: themed($m-aqua);
}
}
&.red {
......
......@@ -67,7 +67,7 @@ m-sidebarMenu {
a.selected,
&:hover a {
@include m-theme() {
color: themed($m-blue);
color: themed($m-link);
}
}
&:last-child {
......
m-walletBalance--cash {
display: block;
max-width: 700px;
max-width: 680px;
> * {
font-weight: 300;
font-size: 15px;
......@@ -12,6 +12,7 @@ m-walletBalance--cash {
.m-walletBalance--cash__colContainer {
display: flex;
justify-content: space-between;
flex-flow: row wrap;
}
.m-walletBalance--cash__colTitle {
......
@mixin m-walletColor--medium {
@include m-theme() {
color: themed($m-grey-300);
}
}
@mixin m-walletColor--dark {
@include m-theme() {
color: themed($m-grey-800);
}
}
@mixin m-walletText--15 {
font-size: 15px;
line-height: 20px;
......@@ -41,14 +31,14 @@ m-walletDashboard {
margin-top: 6px;
font-size: 18px;
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
}
.m-shadowboxHeaderTab__value {
font-weight: 300;
font-size: 16px;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
}
}
......@@ -57,7 +47,7 @@ m-walletDashboard {
display: flex;
flex-flow: row nowrap;
@include m-theme() {
border-bottom: 1px solid themed($m-grey-100);
border-bottom: 1px solid themed($m-borderColor--tertiary);
}
}
.m-walletDashboardViews__tab {
......@@ -71,18 +61,18 @@ m-walletDashboard {
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
border-bottom: 3px solid themed($m-white);
}
&.active {
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
border-bottom: 3px solid themed($m-blue);
}
}
&:hover {
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
}
}
......@@ -167,6 +157,22 @@ m-walletDashboard {
justify-content: flex-end;
align-items: center;
}
.m-walletForm__multifieldGroup {
margin-top: 58px;
}
.m-walletForm__buttonsContainer {
display: flex;
flex-flow: row wrap-reverse;
justify-content: center;
}
.m-walletForm__nameFieldsContainer {
display: flex;
box-sizing: border-box;
[class*='m-walletForm__field'] {
flex: 1 0 50%;
}
}
[class*='m-walletForm__field'] {
font-size: 15px;
line-height: 20px;
......@@ -197,7 +203,7 @@ m-walletDashboard {
flex-flow: row nowrap;
position: relative;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
}
&[class*='--validation'] {
......@@ -209,7 +215,7 @@ m-walletDashboard {
margin: 0;
font-weight: 300;
@include m-theme() {
color: themed($m-red-dark);
color: themed($m-alert); //red-dark
}
}
}
......@@ -224,7 +230,7 @@ m-walletDashboard {
input,
.m-phoneInput__wrapper {
@include m-theme() {
border-color: themed($m-red-dark) !important;
border-color: themed($m-alert) !important; //red-dark
}
}
}
......@@ -233,11 +239,13 @@ m-walletDashboard {
align-self: flex-end;
}
label,
input,
.m-walletForm__row--validation {
flex: 1 1 auto;
max-width: auto;
}
input {
flex: 1 1 100%;
}
}
input {
outline: 0;
......@@ -259,7 +267,7 @@ m-walletDashboard {
border-radius: 2px;
@include m-theme() {
box-shadow: 0 1px 4px 0 rgba(themed($m-black), 0.1);
border: 1px solid themed($m-grey-50);
border: 1px solid themed($m-borderColor--primary);
}
&:focus {
&:not(:read-only) {
......@@ -314,7 +322,7 @@ m-walletDashboard {
.m-walletSettings {
// font-weight: 300;
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
m-shadowboxSubmitButton {
margin: 27px 0 0 0;
......@@ -348,35 +356,40 @@ m-walletDashboard {
margin: 23px 0 0 0;
// font-weight: 300;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
}
input {
outline: 0;
font-size: 15px;
line-height: 20px;
font-weight: 300;
width: 0;
min-width: 0;
padding: 10px 20px;
border-radius: 2px;
cursor: text;
// input {
// outline: 0;
// font-size: 15px;
// line-height: 20px;
// font-weight: 300;
// width: 0;
// min-width: 0;
// padding: 10px 20px;
// border-radius: 2px;
// cursor: text;
@include m-theme() {
color: themed($m-grey-800);
box-shadow: 0 1px 4px 0 rgba(themed($m-black), 0.1);
border: 1px solid themed($m-grey-50);
}
// @include m-theme() {
// color: themed($m-textColor--primary);
// box-shadow: 0 1px 4px 0 rgba(themed($m-black), 0.1);
// border: 1px solid themed($m-borderColor--primary);
// }
// &:not(.m-phoneInput__input) {
// @include m-theme() {
// border: 1px solid themed($m-borderColor--primary);
// }
// }
&:focus {
&:not(:read-only) {
@include m-theme() {
border-color: themed($m-blue);
}
}
}
}
// &:focus {
// &:not(:read-only) {
// @include m-theme() {
// border-color: themed($m-blue);
// }
// }
// }
// }
.m-walletSettingsView--addressCurrent {
h2 {
margin-bottom: 23px;
......@@ -395,7 +408,7 @@ m-walletDashboard {
div:first-child {
margin-right: 18px;
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
}
a {
......@@ -413,7 +426,7 @@ m-walletDashboard {
line-height: 16px;
margin: 31px 0 0 0;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
i {
font-size: 18px;
......@@ -430,7 +443,7 @@ m-walletDashboard {
}
p {
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
}
.m-walletSettingsView__setupOption--custom {
......@@ -445,7 +458,7 @@ m-walletDashboard {
}
span {
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
}
}
......@@ -477,7 +490,7 @@ m-walletDashboard {
}
span.m-walletSettings__address--emphasis {
@include m-theme() {
color: themed($m-grey-800);
color: themed($m-textColor--primary);
}
}
......@@ -489,7 +502,7 @@ m-walletDashboard {
text-decoration: none;
@include m-theme() {
color: themed($m-grey-300);
color: themed($m-textColor--tertiary);
}
&:hover {
span {
......
......@@ -270,10 +270,22 @@ export class WalletDashboardService {
// }
}
async updateStripeAccount() {
async createStripeAccount(form) {
try {
const response = <any>(
await this.client.post('api/v2/payments/stripe/connect')
await this.client.post('api/v1/merchant/onboard', form)
);
return response;
} catch (e) {
console.error(e);
return e;
}
}
async updateStripeAccount(form) {
try {
const response = <any>(
await this.client.post('api/v2/payments/stripe/connect', form)
);
return response;
} catch (e) {
......@@ -293,19 +305,19 @@ export class WalletDashboardService {
return e;
}
}
async removeStripeBank() {
return true;
// TODOOJM this endpoint doesn't exist yet.
// try {
// const response = <any>(
// await this.client.delete('api/v2/payments/stripe/connect/bank')
// );
// return response;
// } catch (e) {
// console.error(e);
// return e;
// }
try {
const response = <any>(
await this.client.delete('api/v2/payments/stripe/connect/bank')
);
return response;
} catch (e) {
console.error(e);
return e;
}
}
// async uploadDocument(fileInput: HTMLInputElement, documentType: string) {
// const file = fileInput ? fileInput.files[0] : null;
// this.editing = true;
......
......@@ -384,8 +384,8 @@ const fakeData = {
},
receiver: {
guid: '930229554033729555',
name: 'omadrid2',
username: 'omadrid2',
name: 'FAILomadrid2',
username: 'FAILomadrid2',
},
wallet_address: 'offchain',
tx: 'oc:1052397161095897106',
......
......@@ -4,10 +4,10 @@ m-walletRewardsPopup {
top: 0;
left: 0;
font-weight: 300;
@include m-walletColor--medium;
@include m-walletText--13;
@include m-theme() {
background-color: themed($m-white);
color: themed($m-textColor--secondary);
box-shadow: 0 0 10px 0 rgba(themed($m-black), 0.1);
}
......@@ -27,8 +27,10 @@ m-walletRewardsPopup {
margin: 10px 20px 20px 20px;
span {
@include m-walletColor--dark;
@include m-walletText--14;
@include m-theme() {
color: themed($m-textColor--primary);
}
}
}
.m-walletRewardsPopup__notice {
......
<div class="mdl-spinner mdl-js-spinner is-active" [mdl] *ngIf="!loaded"></div>
<div class="m-walletBankForm" *ngIf="loaded">
<!-- HAS NOT SET UP BANK ACCOUNT / IS UPDATING BANK ACCOUNT ------------------ -->
<ng-container *ngIf="!leftMonetization">
<form
[formGroup]="bankForm"
*ngIf="!account.bankAccount || !account.bankAccount.last4 || editing"
>
<p>Enter bank account details to receive payments.</p>
<!-- ***INPUT BANKCOUNTRY DROPDOWN-->
<div class="m-walletForm__field--text stretchedField" *ngIf="editingBank">
<div class="m-walletSettings__row--label">
<label for="bankCountry" i18n>Country</label>
</div>
<div class="m-walletForm__row--input">
<minds-country-input
type="text"
id="bankCountry"
name="bankCountry"
formControlName="bankCountry"
class="form-control"
data-minds="bankCountry"
[allowed]="allowedCountries"
[country]="bankCountry.value"
(countryChange)="bankCountry.setValue($event)"
></minds-country-input>
<!-- <m-countryInput
type="text"
id="bankCountry"
name="bankCountry"
formControlName="bankCountry"
class="form-control"
data-minds="bankCountry"
[allowedCountries]="allowedCountries"
[initCountryCode]="bankCountry.value"
(countryChange)="bankCountry.setValue($event)"
></m-countryInput > -->
</div>
</div>
<!-- ***INPUT ACCOUNT NUMBER -->
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletForm__row--label">
<label for="accountNumber" i18n>Bank Account Number / IBAN</label
><m-tooltip icon="help">placeholder</m-tooltip>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="accountNumber"
name="accountNumber"
formControlName="accountNumber"
class="form-control"
data-minds="accountNumber"
/>
</div>
</div>
<!-- ***INPUT ROUTING NUMBER -->
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletForm__row--label">
<label for="routingNumber" i18n>Routing Number / Sort Code</label>
<m-tooltip icon="help">placeholder</m-tooltip>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="routingNumber"
name="routingNumber"
formControlName="routingNumber"
class="form-control"
data-minds="routingNumber"
/>
</div>
</div>
<!-- FORM BUTTONS -------------- -->
<div class="m-walletForm__buttonsContainer">
<!-- TODOOJM consider a confirmation popup on cancel -->
<m-shadowboxSubmitButton
(click)="showModal = true; modalContent = 'leaveEditMode'"
[disabled]="inProgress"
color="grey"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton
(click)="createAccount()"
[disabled]="inProgress"
>Update Personal Information</m-shadowboxSubmitButton
>
</div>
</form>
<!-- BANK ACCOUNT IS ALREADY SET UP ------------------ -->
<div
class="m-walletSettingsView--accountSplash"
*ngIf="account.bankAccount.last4"
>
<p>Your bank account details where cash rewards are deposited.</p>
<div class="m-walletSettingsView--accountSplash__bankPreviewWrapper">
<span>
{{ account.bankAccount.bank_name }}
</span>
<span>****{{ account.bankAccount.last4 }}</span>
</div>
<div class="m-walletSettingsView--accountSplash__linkContainer">
<a (click)="enterEditMode()">Update</a>
<a (click)="showModal = true; modalContent = 'removeBank'">Remove</a>
</div>
</div>
<div>
<h4>Leave Monetization Program</h4>
<p>
For security reasons, you won't be able to rejoin the monetization
program.
</p>
<m-shadowboxSubmitButton
color="red"
(click)="showModal = true; modalContent = 'leaveMonetization'"
>Leave Monetization Program</m-shadowboxSubmitButton
>
</div>
<!-- CONFIRMATION MODAL: LEAVE EDIT MODE -------------------- -->
<m-walletModal
[showModal]="showModal && modalContent === 'leaveEditMode'"
(closeModal)="showModal = false"
>
<p>
Are you sure you want to stop? Any bank information you've entered will
be lost.
</p>
<div class="m-walletSettings--cash__leaveModalButtons">
<m-shadowboxSubmitButton color="grey" (click)="showModal = false"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton color="red" (click)="leaveEditMode()"
>I'm sure</m-shadowboxSubmitButton
>
</div>
</m-walletModal>
<!-- CONFIRMATION MODAL: LEAVE MONETIZATION -------------------- -->
<m-walletModal
[showModal]="showModal && modalContent === 'leaveMonetization'"
(closeModal)="showModal = false"
>
<p *ngIf="modalContent === 'leaveMonetization'">
Are you sure you want to leave the monetization program? You won't be
able to rejoin again.
</p>
<p *ngIf="modalContent === 'removeBank'">
Are you sure you want to remove your bank account information? You won't
be able to receive payments until you add another one.
</p>
<div class="m-walletSettings--cash__leaveModalButtons">
<m-shadowboxSubmitButton color="grey" (click)="showModal = false"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton color="red" (click)="leaveMonetization()"
>I'm sure</m-shadowboxSubmitButton
>
</div>
</m-walletModal>
<!-- CONFIRMATION MODAL: REMOVE BANK -------------------- -->
<m-walletModal
[showModal]="showModal && modalContent === 'removeBank'"
(closeModal)="showModal = false"
>
<p>
Are you sure you want to remove your bank account information? You won't
be able to receive payments until you add another one.
</p>
<div class="m-walletSettings--cash__leaveModalButtons">
<m-shadowboxSubmitButton color="grey" (click)="showModal = false"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton color="red" (click)="removeBank()"
>I'm sure</m-shadowboxSubmitButton
>
</div>
</m-walletModal>
</ng-container>
<ng-container *ngIf="leftMonetization">
<p>You have left the monetization program.</p>
</ng-container>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WalletBankFormComponent } from './bank-form.component';
describe('WalletBankFormComponent', () => {
let component: WalletBankFormComponent;
let fixture: ComponentFixture<WalletBankFormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WalletBankFormComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WalletBankFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { requiredFor, optionalFor } from './../settings-cash.validators';
import { WalletDashboardService } from '../../dashboard.service';
import { FormToastService } from '../../../../../common/services/form-toast.service';
import { ConfigsService } from '../../../../../common/services/configs.service';
import localLabels from './local-labels';
@Component({
selector: 'm-walletBankForm',
templateUrl: './bank-form.component.html',
})
export class WalletBankFormComponent implements OnInit {
@Input() allowedCountries: string[];
account;
form;
loaded: boolean = false;
inProgress: boolean = false;
editing: boolean = false;
showModal: boolean = false;
modalContent: 'leaveEditMode' | 'leaveMonetization' | 'removeBank';
leftMonetization: boolean = false;
initCountry: string;
constructor(
private cd: ChangeDetectorRef,
protected walletService: WalletDashboardService,
private fb: FormBuilder,
private formToastService: FormToastService,
private configs: ConfigsService
) {}
ngOnInit() {
this.form = this.fb.group({
country: ['', Validators.required],
accountNumber: ['', Validators.required],
routingNumber: ['', requiredFor(['US'])],
});
this.getAccount();
}
async getAccount() {
this.inProgress = true;
this.detectChanges();
this.walletService
.getStripeAccount()
.then((account: any) => {
this.account = account;
this.initCountry = account.bankAccount.country || account.country;
this.country.patchValue(this.initCountry);
this.country.setValue(account.country);
})
.catch(e => {
this.formToastService.error(e.message);
});
this.loaded = true;
this.inProgress = false;
this.detectChanges();
}
async removeBank() {
this.inProgress = true;
this.detectChanges();
this.walletService
.removeStripeBank()
.then((response: any) => {
this.inProgress = false;
this.formToastService.success(
'Your bank account was successfully removed.'
);
this.getAccount();
})
.catch(e => {
this.inProgress = false;
this.formToastService.error(e.message);
});
this.detectChanges();
}
async leaveMonetization() {
this.showModal = false;
this.detectChanges();
this.walletService
.leaveMonetization()
.then((response: any) => {
this.configs.set('merchant', []);
// this.getAccount();
this.leftMonetization = true;
})
.catch(e => {
this.formToastService.error(e.message);
});
this.detectChanges();
}
async addBank() {
this.walletService
.addStripeBank(this.form.value)
.then((response: any) => {
this.editing = false;
const toasterMessage = this.isMonetized()
? 'Your bank account has been successfully updated'
: 'Your request to join the monetization program has been submitted';
this.formToastService.success(toasterMessage);
this.getAccount();
// if(filling out form for the first time){
// emit 'pending' to parent
// } else emit 'hasAccount' to parent
})
.catch(e => {
// this.error = e.message;
// todoojm - error handling
});
this.inProgress = false;
this.detectChanges();
}
enterEditMode() {
// TODOOJM see if this is necessary by checking what value country goes to after form.reset
this.country.patchValue(this.initCountry);
this.editing = true;
this.detectChanges();
}
leaveEditMode() {
this.editing = false;
this.form.reset();
this.detectChanges();
}
isCountry(countries: string[]) {
return countries.indexOf(this.country.value) > -1;
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
isMonetized() {
// TODOOJM uncomment after form is done
// if (this.user && this.user.merchant.id) {
// return true;
// }
return false;
}
get accountNumber() {
return this.form.get('accountNumber');
}
get routingNumber() {
return this.form.get('routingNumber');
}
get country() {
return this.form.get('country');
}
}
const localLabels: any = {
// IBAN -----------------------
AU: {
isIban: true,
accountLengthMin: 20,
accountLengthMax: 20,
routingLabel: 'IBAN',
routingTooltip: null,
},
BE: {
isIban: true,
accountLengthMin: 16,
accountLengthMax: 16,
routingLabel: 'IBAN',
routingTooltip: null,
},
CH: {
isIban: true,
accountLengthMin: 21,
accountLengthMax: 21,
routingLabel: 'IBAN',
routingTooltip: null,
},
DE: {
isIban: true,
accountLengthMin: 22,
accountLengthMax: 22,
routingLabel: 'IBAN',
routingTooltip: null,
},
DK: {
isIban: true,
accountLengthMin: 18,
accountLengthMax: 18,
routingLabel: 'IBAN',
routingTooltip: null,
},
ES: {
isIban: true,
accountLengthMin: 24,
accountLengthMax: 24,
routingLabel: 'IBAN',
routingTooltip: null,
},
FI: {
isIban: true,
accountLengthMin: 18,
accountLengthMax: 18,
routingLabel: 'IBAN',
routingTooltip: null,
},
FR: {
isIban: true,
accountLengthMin: 27,
accountLengthMax: 27,
routingLabel: 'IBAN',
routingTooltip: null,
},
IE: {
isIban: true,
accountLengthMin: 22,
accountLengthMax: 22,
routingLabel: 'IBAN',
routingTooltip: null,
},
IT: {
isIban: true,
accountLengthMin: 27,
accountLengthMax: 27,
routingLabel: 'IBAN',
routingTooltip: null,
},
LU: {
isIban: true,
accountLengthMin: 20,
accountLengthMax: 20,
routingLabel: 'IBAN',
routingTooltip: null,
},
NL: {
isIban: true,
accountLengthMin: 18,
accountLengthMax: 18,
routingLabel: 'IBAN',
routingTooltip: null,
},
NO: {
isIban: true,
accountLengthMin: 15,
accountLengthMax: 15,
routingLabel: 'IBAN',
routingTooltip: null,
},
PT: {
isIban: true,
accountLengthMin: 25,
accountLengthMax: 25,
routingLabel: 'IBAN',
routingTooltip: null,
},
SE: {
isIban: true,
accountLengthMin: 24,
accountLengthMax: 24,
routingLabel: 'IBAN',
routingTooltip: null,
},
// NOT IBAN -----------------------
AT: {
isIban: false,
accountLengthMin: null,
routingLabel: 'BSB',
routingTooltip: 'Enter your 6-digit BSB code',
routingLength: 8,
},
CA: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: 'Your routing number should by 8-digits long and',
},
GB: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: null,
},
HK: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: null,
},
NZ: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: null,
},
SG: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: null,
},
US: {
isIban: false,
accountLengthMin: null,
routingLabel: null,
routingTooltip: null,
},
};
export default localLabels;
<div class="mdl-spinner mdl-js-spinner is-active" [mdl] *ngIf="!loaded"></div>
<div class="m-walletOnboardingExtrasForm" *ngIf="loaded">
<p>
You are required to provide additional information so we can verify your
identity in order to receive payouts.
<ng-container
*ngIf="
account.requirement.indexOf('individual.verification.document') > -1
"
>
<b (click)="file.click()">Upload Photo ID</b>
<br />
<br />
<button (click)="file.click()" class="m-btn m-btn--action m-btn--slim">
<ng-container *ngIf="!inProgress">Select & Upload</ng-container>
<ng-container *ngIf="inProgress">Uploading...</ng-container>
</button>
<input
type="file"
#file
name="file"
(change)="uploadDocument(file, 'document')"
accept="image/*"
style="display: none;"
/>
</ng-container>
<ng-container
*ngIf="
account.requirement.indexOf(
'individual.verification.additional_document'
) > -1
"
>
<b (click)="file.click()">Upload a document with proof of address</b>
<br />
<br />
<button (click)="file.click()" class="m-btn m-btn--action m-btn--slim">
<ng-container *ngIf="!inProgress">Select & Upload</ng-container>
<ng-container *ngIf="inProgress">Uploading...</ng-container>
</button>
<input
type="file"
#file
name="file"
(change)="uploadDocument(file, 'additional_document')"
accept="image/*"
style="display: none;"
/>
</ng-container>
<ng-container *ngIf="account.requirement.indexOf('tos_acceptance.') > -1">
<b>
Accept the
<a href="https://stripe.com/legal" target="_blank">
Stripe Services Agreement
</a>
</b>
<br />
<br />
<button (click)="acceptTos()" class="m-btn m-btn--action m-btn--slim">
<ng-container *ngIf="!inProgress">Accept Terms</ng-container>
<ng-container *ngIf="inProgress">Accepting...</ng-container>
</button>
</ng-container>
<ng-container *ngIf="account.requirement.indexOf('individual.phone') > -1">
<b>Provide a phone number</b>
<br />
<m-phone-input #phone></m-phone-input>
<br />
<button
(click)="updateField('phone', phone.value)"
class="m-btn m-btn--action m-btn--slim"
>
<ng-container *ngIf="!inProgress">Save</ng-container>
<ng-container *ngIf="inProgress">Saving...</ng-container>
</button>
</ng-container>
<ng-container *ngIf="account.requirement.indexOf('external_account') > -1">
<b>Complete the payout method step below</b>
</ng-container>
<ng-container
*ngIf="account.requirement.indexOf('individual.id_number') > -1"
>
<b
>Provide your Personal ID / Social Security Number (SSN) / National
Insurance Number</b
>
<br />
<input
class="m-input m-revenueOptions__input"
#personalId
placeholder="Personal Id"
/>
<br />
<button
(click)="updateField('id_number', personalId.value)"
class="m-btn m-btn--action m-btn--slim"
>
<ng-container *ngIf="!inProgress">Save</ng-container>
<ng-container *ngIf="inProgress">Saving...</ng-container>
</button>
</ng-container>
</p>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WalletCashOnboardingExtrasComponent } from './cash-onboarding-extras.component';
describe('WalletCashOnboardingExtrasComponent', () => {
let component: WalletCashOnboardingExtrasComponent;
let fixture: ComponentFixture<WalletCashOnboardingExtrasComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WalletCashOnboardingExtrasComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WalletCashOnboardingExtrasComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
// Show this when stripe requires additional info/documents from certain users
// from certain countries/regions (e.g. Australia, NZ, Europe)
// before their accounts can be verified
import { Component, OnInit, ChangeDetectorRef, Input } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { WalletDashboardService } from '../../dashboard.service';
import { Client, Upload } from '../../../../../services/api';
@Component({
selector: 'm-walletCashOnboardingExtras',
templateUrl: './cash-onboarding-extras.component.html',
})
export class WalletCashOnboardingExtrasComponent implements OnInit {
loaded: boolean = false;
inProgress: boolean = true;
account;
error: string = '';
constructor(
protected walletService: WalletDashboardService,
private client: Client,
private cd: ChangeDetectorRef,
private upload: Upload
) {}
ngOnInit() {
this.getAccount();
}
async getAccount() {
this.error = '';
this.inProgress = true;
this.detectChanges();
this.walletService
.getStripeAccount()
.then((account: any) => {
this.account = account;
})
.catch(e => {
this.error = e.message;
});
this.inProgress = false;
this.detectChanges();
}
async uploadDocument(fileInput: HTMLInputElement, documentType: string) {
const file = fileInput ? fileInput.files[0] : null;
this.inProgress = true;
this.detectChanges();
await this.upload.post(
'api/v2/payments/stripe/connect/document/' + documentType,
[file]
);
this.inProgress = false;
this.account = null;
this.getAccount();
}
async updateField(fieldName: string, value: string) {
this.inProgress = true;
this.detectChanges();
let body = {};
body[fieldName] = value;
await this.client.post('api/v2/payments/stripe/connect/update', body);
this.inProgress = false;
this.account = null;
this.getAccount();
}
async acceptTos() {
this.inProgress = true;
this.detectChanges();
await this.client.put('api/v2/payments/stripe/connect/terms');
this.inProgress = false;
this.account = null;
this.getAccount();
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
}
<div class="mdl-spinner mdl-js-spinner is-active" [mdl] *ngIf="!loaded"></div>
<div class="m-walletCashOnboarding" *ngIf="loaded">
<div class="m-walletCashOnboardingView--addDetails" *ngIf="!editing">
<m-shadowboxSubmitButton
(click)="toggleEditMode(true)"
[disabled]="inProgress"
>Set up cash payments</m-shadowboxSubmitButton
>
</div>
<div class="m-walletCashOnboardingView--form" *ngIf="editing">
<form [formGroup]="accountForm" *ngIf="!isMonetized() && editingAccount">
<p>Enter personal details to setup your cash payment account.</p>
<!-- ------------------------------------------------------------ -->
<!-- **** INPUT: COUNTRY DROPDOWN -->
<div class="m-walletForm__multifieldGroup">
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletSettings__row--label">
<label for="country" i18n>Country</label>
</div>
<div class="m-walletForm__row--input">
<minds-country-input
type="text"
id="country"
name="country"
formControlName="country"
class="form-control"
data-minds="country"
[allowed]="allowedCountries"
[country]="country.value"
(countryChange)="country.setValue($event)"
></minds-country-input>
<!-- <m-countryInput
type="text"
id="country"
name="country"
formControlName="country"
class="form-control"
data-minds="country"
[allowedCountries]="allowedCountries"
[initCountryCode]="country.value"
(countryChange)="country.setValue($event)"
></minds-country-input> -->
</div>
</div>
<!-- (NAMES) -->
<div class="m-walletForm__nameFieldsContainer">
<!-- **** INPUT: FIRST NAME -->
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletForm__row--label">
<label for="firstName" i18n>First Name</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="firstName"
name="firstName"
formControlName="firstName"
class="form-control"
data-minds="firstName"
/>
</div>
</div>
<!-- **** INPUT: LAST NAME -->
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletForm__row--label">
<label for="lastName" i18n>Last Name</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="lastName"
name="lastName"
formControlName="lastName"
class="form-control"
data-minds="lastName"
/>
</div>
</div>
</div>
<!-- **** INPUT: DATE OF BIRTH -->
<div class="m-walletForm__field--text">
<div class="m-walletForm__row--label">
<label for="dob" i18n>Date of Birth</label>
</div>
<div class="m-walletForm__row--input">
<minds-date-input
id="dob"
name="dob"
class="form-control"
formControlName="dob"
data-minds="dob"
[date]="dob.value"
(dateChange)="dob.setValue($event)"
></minds-date-input>
</div>
</div>
<!-- **** INPUT: PHONE NUMBER -->
<div class="m-walletForm__field--text">
<div class="m-walletForm__row--label">
<label for="phoneNumber" i18n>Phone Number</label>
</div>
<div class="m-walletForm__row--input">
<m-phoneInput
id="phoneNumber"
name="phoneNumber"
formControlName="phoneNumber"
class="form-control"
data-minds="phoneNumber"
initCountryCode="US"
[allowedCountries]="allowedCountries"
>
</m-phoneInput>
</div>
</div>
<!-- **** INPUT: PERSONAL ID# -->
<div
class="m-walletForm__field--text stretchedField"
*ngIf="isCountry(['HK', 'SG'])"
>
<div class="m-walletForm__row--label">
<label for="personalId" i18n *ngIf="isCountry(['HK'])"
>Hong Kong Identity Card (HKID)</label
>
<label for="personalId" i18n *ngIf="isCountry(['SG'])"
>National Registration Identity Card (NRIC)</label
>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="personalId"
name="personalId"
formControlName="personalId"
class="form-control"
/>
</div>
</div>
<!-- **** INPUT: SSN -->
<div
class="m-walletForm__field--text stretchedField"
*ngIf="isCountry(['US'])"
>
<div class="m-walletForm__row--label">
<label for="ssn" i18n>SSN (last 4 digits)</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="ssn"
name="ssn"
formControlName="ssn"
class="form-control"
/>
</div>
</div>
</div>
<!-- ------------------------------------------------------------ -->
<!-- **** INPUT: ADDRESS -- STREET -->
<div class="m-walletForm__multifieldGroup">
<div class="m-walletForm__field--text stretchedField">
<div class="m-walletForm__row--label">
<label for="street" i18n>Address</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="street"
name="street"
formControlName="street"
class="form-control"
/>
</div>
</div>
<!-- **** INPUT: ADDRESS -- CITY -->
<div
class="m-walletForm__field--text stretchedField"
*ngIf="!isCountry(['SG'])"
>
<div class="m-walletForm__row--label">
<label for="city" i18n>City</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="city"
name="city"
formControlName="city"
class="form-control"
/>
</div>
</div>
<!-- **** INPUT: ADDRESS -- STATE -->
<div
class="m-walletForm__field--text stretchedField"
*ngIf="isCountry(['US'])"
>
<div class="m-walletForm__row--label">
<label for="state" i18n>State</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="city"
name="city"
formControlName="city"
class="form-control"
/>
</div>
</div>
<div
class="m-walletForm__field--text stretchedField"
*ngIf="isCountry(['AU', 'CA', 'IE'])"
>
<div class="m-walletForm__row--label">
<label for="state" i18n>State / Province</label>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="state"
name="state"
formControlName="state"
class="form-control"
/>
</div>
</div>
<!-- **** INPUT: ADDRESS -- ZIP -->
<div
class="m-walletForm__field--text stretchedField"
*ngIf="!isCountry(['HK'])"
>
<div class="m-walletForm__row--label">
<label for="postCode" i18n *ngIf="isCountry(['US'])"
>Zip Code</label
>
<label for="postCode" i18n *ngIf="!isCountry(['US'])"
>Postal Code</label
>
</div>
<div class="m-walletForm__row--input">
<input
type="text"
id="postCode"
name="postCode"
formControlName="postCode"
class="form-control"
/>
</div>
</div>
</div>
<!-- ------------------------------------------------------------ -->
<!-- **** INPUT: TOS CHECKBOX -->
<div class="m-walletSettings__field--checkbox">
<div class="m-walletSettings__row--input">
<m-formInput__checkbox formControlName="stripeAgree">
I have read and agree to the
<a href="https://stripe.com/legal" target="_blank">
Stripe Services Agreement </a
>.
</m-formInput__checkbox>
</div>
</div>
<!-- ------------------------------------------------------------ -->
<!-- FORM BUTTONS -------------- -->
<div class="m-walletForm__buttonsContainer">
<!-- TODOOJM confirmation popup on cancel -->
<m-shadowboxSubmitButton
(click)="toggleEditMode(false)"
[disabled]="inProgress"
color="grey"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton
(click)="createAccount()"
[disabled]="inProgress"
>Update Personal Information</m-shadowboxSubmitButton
>
</div>
</form>
</div>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WalletCashOnboardingComponent } from './cash-onboarding.component';
describe('WalletCashOnboardingComponent', () => {
let component: WalletCashOnboardingComponent;
let fixture: ComponentFixture<WalletCashOnboardingComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WalletCashOnboardingComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WalletCashOnboardingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { requiredFor, optionalFor } from './../settings-cash.validators';
import { WalletDashboardService } from '../../dashboard.service';
import { FormToastService } from '../../../../../common/services/form-toast.service';
@Component({
selector: 'm-walletCashOnboarding',
templateUrl: './cash-onboarding.component.html',
})
export class WalletCashOnboardingComponent implements OnInit {
@Input() allowedCountries: string[];
form;
user;
loaded: boolean = false;
inProgress: boolean = false;
editing;
constructor(
private cd: ChangeDetectorRef,
protected walletService: WalletDashboardService,
private fb: FormBuilder,
private formToastService: FormToastService
) {}
ngOnInit() {
this.form = this.fb.group({
country: ['US', Validators.required],
firstName: ['', optionalFor(['JP'])],
lastName: ['', optionalFor(['JP'])],
gender: ['', requiredFor(['JP'])],
dob: ['', Validators.required],
phoneNumber: ['', requiredFor(['JP'])],
ssn: ['', requiredFor(['US'])],
personalIdNumber: ['', requiredFor(['CA', 'HK', 'SG'])],
street: ['', optionalFor(['JP'])],
city: ['', optionalFor(['JP', 'SG'])],
state: ['', requiredFor(['AU', 'CA', 'IE', 'US'])],
postCode: ['', optionalFor(['HK', 'IE', 'JP'])],
stripeAgree: ['', Validators.required],
});
this.getAccount();
}
async getAccount() {
this.inProgress = true;
this.detectChanges();
this.walletService
.getStripeAccount()
.then((account: any) => {})
.catch(e => {
this.formToastService.error(e.message);
});
this.loaded = true;
this.inProgress = false;
this.detectChanges();
}
async createAccount() {
this.inProgress = true;
// this.error = '';
const formVal = this.form.value;
formVal.stripeAgree = this.stripeAgree.value;
console.log('formVal w/ agree', formVal);
this.walletService
.createStripeAccount(formVal)
.then((response: any) => {
console.log('createAccount response', response);
this.inProgress = false;
// Is this kind of stuff necessary anymore?
if (!this.user.programs) {
this.user.programs = [];
}
this.user.programs.push('affiliate');
this.user.merchant = {
id: response.id,
service: 'stripe',
status: 'awaiting-document',
exclusive: {
enabled: true,
amount: 10,
},
};
})
.catch(e => {
this.inProgress = false;
// TODOOJM handle errors inline
// this.error = e.message;
});
this.detectChanges();
}
toggleEditMode(bool) {
this.editing = bool;
this.detectChanges();
}
isCountry(countries: string[]) {
return countries.indexOf(this.country.value) > -1;
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
}
isMonetized() {
// TODOOJM uncomment after form is done
// if (this.user && this.user.merchant.id) {
// return true;
// }
return false;
}
get country() {
return this.form.get('country');
}
get firstName() {
return this.form.get('firstName');
}
get lastName() {
return this.form.get('lastName');
}
get gender() {
return this.form.get('gender');
}
get dob() {
return this.form.get('dob');
}
get phoneNumber() {
return this.form.get('phoneNumber');
}
get ssn() {
return this.form.get('ssn');
}
get personalIdNumber() {
return this.form.get('personalIdNumber');
}
get street() {
return this.form.get('street');
}
get city() {
return this.form.get('city');
}
get state() {
return this.form.get('state');
}
get postCode() {
return this.form.get('postCode');
}
get stripeAgree() {
return this.form.get('stripeAgree');
}
}
<div class="mdl-spinner mdl-js-spinner is-active" [mdl] *ngIf="!loaded"></div>
<div class="m-walletSettings" *ngIf="loaded">
<h4>Bank Information</h4>
<p>Add your bank account details where rewards are deposited.</p>
<ng-container *ngIf="!account">
<div class="m-walletSettingsView--addAccount">
<m-shadowboxSubmitButton (click)="editBank()" [disabled]="inProgress"
>Add your bank details</m-shadowboxSubmitButton
>
</div>
</ng-container>
<ng-container *ngIf="account">
<div class="m-walletSettingsView--accountSplash" *ngIf="!editingBank">
<div class="m-walletSettingsView--accountSplash__bankPreviewWrapper">
<span>
{{ payoutMethod.account.bank_name }}
</span>
<span>****{{ payoutMethod.account.last4 }}</span>
</div>
<div class="m-walletSettingsView--accountSplash__linkContainer">
<a (click)="editBank()">Update</a>
<a (click)="removeBank()">Remove</a>
</div>
</div>
<div>
<h4>Leave Monetization Program</h4>
<p>
For security reasons, you won't be able to rejoin the monetization
program.
</p>
<m-shadowboxSubmitButton color="red" (click)="showModal = true"
>Leave Monetization Program</m-shadowboxSubmitButton
>
</div>
<!-- <div class="m-walletSettingsView--editingBank" *ngIf="editingBank"></div> -->
</ng-container>
<m-walletModal [showModal]="showModal" (closeModal)="showModal = false">
<p>
Are you sure you want to leave the monetization program? You won't be able
to rejoin again.
</p>
<div class="m-walletSettings--cash__leaveModalButtons">
<m-shadowboxSubmitButton color="grey" (click)="showModal = false"
>Cancel</m-shadowboxSubmitButton
>
<m-shadowboxSubmitButton color="red" (click)="leaveMonetization()"
>I'm sure</m-shadowboxSubmitButton
>
</div>
</m-walletModal>
<!-- ONBOARDING FORM ------------------ -->
<m-walletCashOnboarding
*ngIf="view === 'onboardingForm'"
[allowedCountries]="allowedCountries"
(accountCreated)="getAccount(); checkAdditionalReqts()"
></m-walletCashOnboarding>
<!-- ADDITIONAL REQUIREMENTS FORM ----------- -->
<m-walletCashOnboardingExtras
*ngIf="view === 'additionalReqtsForm'"
(submittedRequirements)="getAccount(); checkAdditionalReqts()"
></m-walletCashOnboardingExtras>
<!-- BANK FORM --------------------------- -->
<m-walletBankForm
*ngIf="view === 'bankForm'"
[allowedCountries]="allowedCountries"
></m-walletBankForm>
<!-- PENDING APPROVAL ----------------------- -->
<div *ngIf="view === 'pendingApproval'"></div>
<!-- ERROR ---------------------------------- -->
<div *ngIf="view === 'error'">
<p>{{ error }}</p>
</div>
</div>
......@@ -20,17 +20,31 @@ m-walletSettings--cash {
.m-walletSettingsView--accountSplash__linkContainer {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
flex: 0 0 auto;
justify-content: space-between;
flex: 1 0 auto;
max-width: 146px;
a:last-child {
margin-left: 8px;
}
}
.m-walletSettings--cash__leaveModalButtons {
// FORM -------------------
[class*='m-walletForm__field'] {
margin-bottom: 19px;
}
.m-walletForm__nameFieldsContainer {
display: flex;
flex-flow: row wrap-reverse;
justify-content: center;
box-sizing: border-box;
[class*='m-walletForm__field'] {
flex: 1 0 50%;
&:first-child {
margin-right: 19px;
}
}
}
.m-tooltip--bubble {
right: 12px;
}
}
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { WalletDashboardService } from '../dashboard.service';
import { FormToastService } from '../../../../common/services/form-toast.service';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { Session } from '../../../../services/session';
import { ConfigsService } from '../../../../common/services/configs.service';
@Component({
selector: 'm-walletSettings--cash',
templateUrl: './settings-cash.component.html',
})
export class WalletSettingsCashComponent implements OnInit {
// TODOOJM $account make this observable
account: any;
payoutMethod = {
account: null,
country: 'US',
};
loaded: boolean = false;
inProgress: boolean = true;
editingBank: boolean = false;
showModal: boolean = false;
form;
user;
account;
error: string = '';
view:
| 'onboardingForm'
| 'additionalReqtsForm'
| 'bankForm'
| 'pendingApproval'
| 'error';
allowedCountries: string[] = [
'AT',
'AU',
'BE',
'CA',
'CH',
'DE',
'DK',
'ES',
'FI',
'FR',
'GB',
'HK',
'IE',
'IT',
'LU',
'NL',
'NO',
'NZ',
'PT',
'SE',
'SG',
'US',
];
constructor(
protected walletService: WalletDashboardService,
private formToastService: FormToastService,
private cd: ChangeDetectorRef,
protected session: Session,
private configs: ConfigsService
protected session: Session
) {}
ngOnInit() {
this.getAccount();
this.loaded = true;
this.detectChanges();
}
async getAccount() {
this.walletService
.getStripeAccount()
.then((account: any) => {
console.log(this.account);
this.account = account;
this.payoutMethod.country = account.country;
this.form.controls.country.setValue(account.country);
if (account.bankAccount.last4) {
this.payoutMethod.account = account.bankAccount;
}
})
.catch(e => {
this.formToastService.error(e.message);
});
this.user = this.session.getLoggedInUser();
this.form = new FormGroup({
accountNumber: new FormControl('', {
validators: [Validators.required],
}),
routingNumber: new FormControl(''),
country: new FormControl('US'),
});
this.setFormView();
this.loaded = true;
this.inProgress = false;
this.detectChanges();
}
async addBank() {
setFormView() {
this.inProgress = true;
this.detectChanges();
this.walletService
.addStripeBank(this.form.value)
.then((response: any) => {
this.inProgress = false;
this.editingBank = false;
this.formToastService.success(
'Your bank account was successfully added.'
);
this.getAccount();
})
.catch(e => {
this.inProgress = false;
this.formToastService.error(e.message);
});
this.detectChanges();
}
const hasMerchant = this.user && this.user.merchant.id;
async leaveMonetization() {
this.showModal = false;
this.detectChanges();
this.walletService
.leaveMonetization()
.then((response: any) => {
this.configs.set('merchant', []);
this.getAccount();
})
.catch(e => {
this.formToastService.error(e.message);
});
this.detectChanges();
}
if (!hasMerchant) {
this.view = 'onboardingForm';
} else {
this.getAccount();
if (this.error) {
return;
}
// if pending (???) pending; return
editBank() {
this.editingBank = true;
this.detectChanges();
// if additional reqts, additinoalReqts
// else bankForm
}
}
async removeBank() {
this.inProgress = true;
this.detectChanges();
async getAccount() {
this.error = '';
this.walletService
.removeStripeBank()
.then((response: any) => {
this.inProgress = false;
this.formToastService.success(
'Your bank account was successfully removed.'
);
this.getAccount();
.getStripeAccount()
.then((account: any) => {
this.account = account;
// TODOOJM handle view selection
// if (!this.account.bankAccount || !this.account.bankAccount.last4) {
// this.view = 'bankForm';
// } else {
// }
})
.catch(e => {
this.inProgress = false;
this.formToastService.error(e.message);
this.error = e.message;
this.view = 'error';
});
this.inProgress = false;
this.detectChanges();
}
get accountNumber() {
return this.form.get('accountNumber');
}
get routingNumber() {
return this.form.get('routingNumber');
}
get country() {
return this.form.get('country');
switchView(view) {
this.view = view;
this.detectChanges();
}
detectChanges() {
......@@ -142,132 +115,3 @@ export class WalletSettingsCashComponent implements OnInit {
this.cd.detectChanges();
}
}
// export class RevenueOptionsComponent {
// form: FormGroup;
// inProgress: boolean = true;
// editing: boolean = false;
// payoutMethod = {
// account: null,
// country: 'US',
// };
// account;
// error: string = '';
// leaving: boolean = false;
// leaveError: string = '';
// constructor(
// private client: Client,
// private upload: Upload,
// private cd: ChangeDetectorRef,
// private fb: FormBuilder,
// private router: Router
// ) {}
// ngOnInit() {
// this.getSettings();
// this.form = this.fb.group({
// accountNumber: ['', Validators.required],
// routingNumber: [''],
// country: ['US'],
// });
// }
// getSettings() {
// this.inProgress = true;
// this.client.get('api/v2/payments/stripe/connect').then(({ account }) => {
// this.inProgress = false;
// this.account = account;
// this.payoutMethod.country = account.country;
// this.form.controls.country.setValue(account.country);
// if (account.bankAccount.last4) {
// this.payoutMethod.account = account.bankAccount;
// }
// this.detectChanges();
// });
// }
// addBank() {
// this.inProgress = true;
// this.error = '';
// // this.editing = false;
// this.detectChanges();
// this.client
// .post('api/v2/payments/stripe/connect/bank', this.form.value)
// .then((response: any) => {
// this.inProgress = false;
// this.editing = false;
// this.getSettings();
// })
// .catch(e => {
// this.inProgress = false;
// this.error = e.message;
// this.detectChanges();
// });
// }
// leave() {
// this.leaving = true;
// this.detectChanges();
// this.client
// .delete('api/v2/payments/stripe/connect')
// .then((response: any) => {
// (<any>window).Minds.user.merchant = [];
// this.router.navigate(['/newsfeed']);
// })
// .catch(e => {
// this.leaving = false;
// this.leaveError = e.message;
// this.detectChanges();
// });
// }
// edit() {
// this.editing = true;
// this.detectChanges();
// }
// cancelEditing() {
// this.editing = false;
// this.detectChanges();
// }
// async uploadDocument(fileInput: HTMLInputElement, documentType: string) {
// const file = fileInput ? fileInput.files[0] : null;
// this.editing = true;
// this.detectChanges();
// await this.upload.post(
// 'api/v2/payments/stripe/connect/document/' + documentType,
// [file]
// );
// this.editing = false;
// this.account = null;
// this.getSettings();
// }
// async updateField(fieldName: string, value: string) {
// this.editing = true;
// this.detectChanges();
// let body = {};
// body[fieldName] = value;
// await this.client.post('api/v2/payments/stripe/connect/update', body);
// this.editing = false;
// this.account = null;
// this.getSettings();
// }
// async acceptTos() {
// this.editing = true;
// this.detectChanges();
// await this.client.put('api/v2/payments/stripe/connect/terms');
// this.editing = false;
// this.account = null;
// this.getSettings();
// }
// detectChanges() {
// this.cd.markForCheck();
// this.cd.detectChanges();
// }
// }
import { ValidatorFn, AbstractControl } from '@angular/forms';
const _isCountry = (currentCountry, countries: string[]) => {
return countries.indexOf(currentCountry) > -1;
};
export function requiredFor(
countryCodes: string[],
{ ignore = false }: { ignore?: boolean } = {}
): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
if (ignore) {
return null;
}
const country = control.root.get('country');
if (!country) {
return { required: true };
}
const selected = country.value;
if (!_isCountry(selected, countryCodes)) {
return null;
}
return !control.value ? { required: true } : null;
};
}
export function optionalFor(
countryCodes: string[],
{ ignore = false }: { ignore?: boolean } = {}
): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
if (ignore) {
return null;
}
const country = control.root.get('country');
if (!country) {
return { required: true };
}
const selected = country.value;
if (_isCountry(selected, countryCodes)) {
return null;
}
return !control.value ? { required: true } : null;
};
}
......@@ -3,10 +3,7 @@
<div class="m-walletTransactionsTable__row--date" *ngIf="tx.displayDate">
{{ tx.displayDate }}
</div>
<div
class="m-walletTransactionsTable__row--details"
[ngClass]="{ 'm-walletTransactionsTable__transactionFailed': tx?.failed }"
>
<div class="m-walletTransactionsTable__row--details">
<div class="m-walletTransactionsTable__time">{{ tx.displayTime }}</div>
<ng-container [ngSwitch]="tx.superType">
<!-- REWARDS -->
......
......@@ -3,8 +3,10 @@
.m-walletTransactions {
margin: 40px 70px;
font-weight: 300;
@include m-walletColor--medium;
@include m-walletText--14;
@include m-theme() {
color: themed($m-textColor--secondary);
}
}
.m-walletTransactions--cash {
.m-walletTransactionsTable__row--top {
......@@ -25,7 +27,9 @@
.m-walletTransactionsTable__row--top {
margin-bottom: 10px;
.m-walletTransactionsTable__time {
@include m-walletColor--dark;
@include m-theme() {
color: themed($m-textColor--primary);
}
}
}
......@@ -52,7 +56,9 @@
m-walletTransactionsTable {
.m-walletTransactionsTable__row--date {
margin: 52px 0 27px 0;
@include m-walletColor--dark;
@include m-theme() {
color: themed($m-textColor--primary);
}
}
.m-walletTransactionsTable__row--details {
margin-bottom: 21px;
......@@ -66,11 +72,7 @@ m-walletTransactionsTable {
}
}
}
.m-walletTransactionsTable__transactionFailed {
.m-walletTransactionsTable__amountWrapper span {
text-decoration: line-through;
}
}
.m-walletTransactionsTable__avatar {
border-radius: 100%;
height: 27px;
......@@ -79,7 +81,7 @@ m-walletTransactionsTable {
.m-walletTransactionsTable__otherUserLink {
font-weight: 300;
@include m-theme() {
color: themed($m-blue);
color: themed($m-link);
}
}
.m-walletTransactionsTable__amountWrapper {
......@@ -87,39 +89,42 @@ m-walletTransactionsTable {
i {
transform-origin: center center;
&.positive {
transform: rotate(-90deg);
transform: rotate(-90deg) translateX(2px);
@include m-theme() {
color: themed($m-green-dark);
}
}
&.negative {
transform: rotate(90deg);
transform: rotate(90deg) translateX(-4px);
@include m-theme() {
color: themed($m-red-dark);
}
}
&.neutral {
transform: translateY(-2px);
@include m-theme() {
color: themed($m-blue);
}
}
&.failed {
@include m-theme() {
color: themed($m-grey-100);
}
}
}
span {
@include m-walletColor--medium;
@include m-walletText--14;
@include m-theme() {
color: themed($m-textColor--secondary);
}
}
}
.m-walletTransactionsTable__total--int {
@include m-walletColor--dark;
@include m-walletText--15;
@include m-theme() {
color: themed($m-textColor--primary);
}
}
.m-walletTransactionsTable__total--frac {
@include m-walletColor--medium;
@include m-walletText--12;
@include m-theme() {
color: themed($m-textColor--secondary);
}
}
}
......@@ -17,7 +17,6 @@ import * as moment from 'moment';
import { Subscription } from 'rxjs';
@Component({
// moduleId: module.id,
selector: 'm-walletTransactions--tokens',
templateUrl: './transactions-tokens.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
......@@ -177,52 +176,49 @@ export class WalletTransactionsTokensComponent implements OnInit, OnDestroy {
formatResponse(transactions) {
transactions.forEach(tx => {
const formattedTx: any = {};
if (!tx.failed) {
const formattedTx: any = {};
const txAmount = toFriendlyCryptoVal(tx.amount);
formattedTx.amount = txAmount;
const txAmount = toFriendlyCryptoVal(tx.amount);
formattedTx.amount = txAmount;
formattedTx.runningTotal = this.formatAmount(this.runningTotal);
if (!tx.failed && tx.type !== 'withdraw') {
this.runningTotal -= txAmount;
}
formattedTx.runningTotal = this.formatAmount(this.runningTotal);
formattedTx.type = tx.contract;
formattedTx.failed = tx.failed;
formattedTx.timestamp = tx.timestamp;
formattedTx.type = tx.contract;
formattedTx.timestamp = tx.timestamp;
if (tx.contract.indexOf('offchain:') !== -1) {
formattedTx.superType = tx.contract.substr(9);
} else {
formattedTx.superType = tx.contract;
}
if (tx.contract.indexOf('offchain:') !== -1) {
formattedTx.superType = tx.contract.substr(9);
} else {
formattedTx.superType = tx.contract;
}
if (formattedTx.superType === 'reward') {
formattedTx.showRewardsPopup = false;
}
if (formattedTx.superType === 'reward') {
formattedTx.showRewardsPopup = false;
}
if (formattedTx.superType === 'wire') {
formattedTx.otherUser = this.getOtherUser(tx);
}
if (formattedTx.superType === 'wire') {
formattedTx.otherUser = this.getOtherUser(tx);
}
formattedTx.delta = this.getDelta(tx);
formattedTx.delta = this.getDelta(tx);
const txMoment = moment(tx.timestamp * 1000).local();
formattedTx.displayDate = null;
formattedTx.displayTime = txMoment.format('hh:mm a');
const txMoment = moment(tx.timestamp * 1000).local();
formattedTx.displayDate = null;
formattedTx.displayTime = txMoment.format('hh:mm a');
if (this.isNewDay(this.currentDayInLoop, txMoment)) {
this.currentDayInLoop = txMoment;
if (this.isNewDay(this.currentDayInLoop, txMoment)) {
this.currentDayInLoop = txMoment;
// If tx occured yesterday, use 'yesterday' instead of date
const yesterday = moment().subtract(1, 'day');
if (txMoment.isSame(yesterday, 'day')) {
formattedTx.displayDate = 'Yesterday';
} else {
formattedTx.displayDate = moment(txMoment).format('ddd MMM Do');
// If tx occured yesterday, use 'yesterday' instead of date
const yesterday = moment().subtract(1, 'day');
if (txMoment.isSame(yesterday, 'day')) {
formattedTx.displayDate = 'Yesterday';
} else {
formattedTx.displayDate = moment(txMoment).format('ddd MMM Do');
}
}
this.transactions.push(formattedTx);
}
this.transactions.push(formattedTx);
});
this.inProgress = false;
}
......@@ -276,9 +272,6 @@ export class WalletTransactionsTokensComponent implements OnInit, OnDestroy {
if (tx.type !== 'withdraw') {
delta = tx.amount < 0 ? 'negative' : 'positive';
}
if (tx.failed) {
delta = 'failed';
}
return delta;
}
......
......@@ -22,6 +22,9 @@ import { WalletBalanceCashComponent } from './balance-cash/balance-cash.componen
import { WalletPendingCashPayoutComponent } from './pending-cash-payout/pending-cash-payout.component';
import { WalletTransactionsTokensComponent } from './transactions-tokens/transactions-tokens.component';
import { WalletTransactionsCashComponent } from './transactions-cash/transactions-cash.component';
import { WalletCashOnboardingComponent } from './settings-cash/cash-onboarding/cash-onboarding.component';
import { WalletCashOnboardingExtrasComponent } from './settings-cash/cash-onboarding-extras/cash-onboarding-extras.component';
import { WalletBankFormComponent } from './settings-cash/bank-form/bank-form.component';
//////////////////////////////////////////////////
// TODO add a wildcard and the parameter routes as children once feature-flag is lifted
......@@ -82,6 +85,9 @@ export const WALLET_V2_ROUTES: Routes = [
WalletPendingCashPayoutComponent,
WalletTransactionsTokensComponent,
WalletTransactionsCashComponent,
WalletCashOnboardingComponent,
WalletCashOnboardingExtrasComponent,
WalletBankFormComponent,
],
exports: [WalletDashboardComponent],
providers: [WalletDashboardService],
......
......@@ -73,7 +73,7 @@ $amber: #ffc108;
$amber-medium: #fed12f;
$amber-light: #ffecb3;
$red-dark: #c62828;
$red: #f44336;
$red: #e03c20;
$red-light: #e57373;
$black: #000;
......