web/satellite: referral links and registration (#3678)
This commit is contained in:
parent
526a126a5a
commit
90b631c8bf
@ -12,6 +12,7 @@ import { HttpClient } from '@/utils/httpClient';
|
||||
export class AuthHttpApi {
|
||||
private readonly http: HttpClient = new HttpClient();
|
||||
private readonly ROOT_PATH: string = '/api/v0/auth';
|
||||
private readonly REFERRAL_PATH: string = '/api/v0/referrals';
|
||||
|
||||
/**
|
||||
* Used to resend an registration confirmation email
|
||||
@ -189,4 +190,34 @@ export class AuthHttpApi {
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register account by referral link
|
||||
*
|
||||
* @param user - stores user information
|
||||
* @param referralToken - referral registration token
|
||||
* @returns id of created user
|
||||
* @throws Error
|
||||
*/
|
||||
public async referralRegister(user: {fullName: string; shortName: string; email: string; password: string}, referralToken: string): Promise<string> {
|
||||
const path = `${this.REFERRAL_PATH}/register`;
|
||||
const body = {
|
||||
referralToken,
|
||||
password: user.password,
|
||||
fullName: user.fullName,
|
||||
shortName: user.shortName,
|
||||
email: user.email,
|
||||
};
|
||||
|
||||
const response = await this.http.post(path, JSON.stringify(body), false);
|
||||
if (!response.ok) {
|
||||
if (response.status === 400) {
|
||||
throw new Error('we are unable to create your account. This is an invite-only alpha, please join our waitlist to receive an invitation');
|
||||
}
|
||||
|
||||
throw new Error('can not register user');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
}
|
||||
|
@ -13,19 +13,15 @@ export class ReferralHttpApi {
|
||||
private readonly ROOT_PATH: string = '/api/v0/referrals';
|
||||
|
||||
/**
|
||||
* Used to get referral links
|
||||
* Used to get referral tokens
|
||||
*
|
||||
* @throws Error
|
||||
*/
|
||||
public async getLinks(): Promise<any> {
|
||||
const path = `${this.ROOT_PATH}`;
|
||||
public async getTokens(): Promise<string[]> {
|
||||
const path = `${this.ROOT_PATH}/tokens`;
|
||||
const response = await this.http.get(path, true);
|
||||
|
||||
// TODO: remove mock and add types after final referral manager implementation
|
||||
return [];
|
||||
|
||||
if (response.ok) {
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
@ -33,6 +29,6 @@ export class ReferralHttpApi {
|
||||
throw new ErrorUnauthorized();
|
||||
}
|
||||
|
||||
throw new Error('can not get referral links');
|
||||
throw new Error('can not get referral tokens');
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ export default class AccountArea extends Vue {}
|
||||
.account-area-container {
|
||||
padding: 0 39px 0 65px;
|
||||
margin-right: 16px;
|
||||
height: 100%;
|
||||
|
||||
&__navigation {
|
||||
position: absolute;
|
||||
|
@ -117,6 +117,7 @@ export default class ProfileArea extends Vue {
|
||||
.profile-container {
|
||||
position: relative;
|
||||
font-family: 'font_regular', sans-serif;
|
||||
padding-bottom: 100px;
|
||||
user-select: none;
|
||||
|
||||
&__title {
|
||||
|
@ -8,29 +8,17 @@
|
||||
<p class="referral-container__title-container__text">Decentralized Future</p>
|
||||
</div>
|
||||
<div class="referral-container__available" v-if="isAvailableLinks">
|
||||
<p class="referral-container__available__title">You Have {{ 5 }} Invitations To Share!</p>
|
||||
<div class="referral-container__copy-and-share-container__link-holder">
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">https://us-central-1.tardigrade.io/ref/?uuid=96a33796-2c9b-47</p>
|
||||
<div class="copy-button" v-clipboard="'test'" @click="copyLink">Copy</div>
|
||||
</div>
|
||||
<div class="referral-container__copy-and-share-container__link-holder">
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">https://us-central-1.tardigrade.io/ref/?uuid=96a33796-2c9b-47</p>
|
||||
<div class="copy-button" v-clipboard="'test'" @click="copyLink">Copy</div>
|
||||
</div>
|
||||
<div class="referral-container__copy-and-share-container__link-holder">
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">https://us-central-1.tardigrade.io/ref/?uuid=96a33796-2c9b-47</p>
|
||||
<div class="copy-button" v-clipboard="'test'" @click="copyLink">Copy</div>
|
||||
</div>
|
||||
<div class="referral-container__copy-and-share-container__link-holder">
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">https://us-central-1.tardigrade.io/ref/?uuid=96a33796-2c9b-47</p>
|
||||
<div class="copy-button" v-clipboard="'test'" @click="copyLink">Copy</div>
|
||||
</div>
|
||||
<div class="referral-container__copy-and-share-container__link-holder">
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">https://us-central-1.tardigrade.io/ref/?uuid=96a33796-2c9b-47</p>
|
||||
<div class="copy-button" v-clipboard="'test'" @click="copyLink">Copy</div>
|
||||
<p class="referral-container__available__title">You Have {{ referralLinks.length }} Invitations To Share!</p>
|
||||
<div
|
||||
class="referral-container__copy-and-share-container__link-holder"
|
||||
v-for="link in referralLinks"
|
||||
:key="link.url"
|
||||
>
|
||||
<p class="referral-container__copy-and-share-container__link-holder__link">{{ link.url }}</p>
|
||||
<div class="copy-button" v-clipboard="link.url" @click="copyLink">Copy</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="referral-container__not-available" v-if="!isAvailableLinks">
|
||||
<div class="referral-container__not-available" v-else>
|
||||
<p class="referral-container__not-available__text">No available referral links. Try again later.</p>
|
||||
<NoLinksIcon />
|
||||
</div>
|
||||
@ -44,6 +32,7 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
import NoLinksIcon from '@/../static/images/referral/NoLinks.svg';
|
||||
|
||||
import { REFERRAL_ACTIONS } from '@/store/modules/referral';
|
||||
import { ReferralLink } from '@/types/referral';
|
||||
|
||||
Vue.use(VueClipboards);
|
||||
|
||||
@ -58,11 +47,15 @@ export default class ReferralArea extends Vue {
|
||||
}
|
||||
|
||||
public get isAvailableLinks(): boolean {
|
||||
return this.$store.state.referralModule.referralLinks.length !== 0;
|
||||
return this.$store.state.referralModule.referralTokens.length !== 0;
|
||||
}
|
||||
|
||||
public get referralLinks(): ReferralLink[] {
|
||||
return this.$store.getters.referralLinks;
|
||||
}
|
||||
|
||||
public async beforeMount() {
|
||||
await this.$store.dispatch(REFERRAL_ACTIONS.GET_LINKS);
|
||||
await this.$store.dispatch(REFERRAL_ACTIONS.GET_TOKENS);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -79,6 +72,7 @@ export default class ReferralArea extends Vue {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 50px 0 100px 0;
|
||||
|
||||
&__title-container {
|
||||
display: flex;
|
||||
|
@ -346,7 +346,6 @@ export default class ApiKeysArea extends Vue {
|
||||
.api-keys-area {
|
||||
position: relative;
|
||||
padding: 40px 65px 55px 65px;
|
||||
height: 85vh;
|
||||
font-family: 'font_regular', sans-serif;
|
||||
|
||||
&__title {
|
||||
|
@ -40,7 +40,7 @@ export default class VBanner extends Vue {
|
||||
padding: 20px 20px 20px 20px;
|
||||
border-radius: 12px;
|
||||
background-color: #d0e3fe;
|
||||
margin: 32px 65px 32px 55px;
|
||||
margin: 32px 65px 15px 55px;
|
||||
|
||||
&__text {
|
||||
font-family: 'font_medium', sans-serif;
|
||||
|
@ -155,7 +155,6 @@ export default class ProjectDetailsArea extends Vue {
|
||||
.project-details {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 85vh;
|
||||
font-family: 'font_regular', sans-serif;
|
||||
|
||||
&__title {
|
||||
|
@ -54,7 +54,6 @@ export default class ProjectOverviewArea extends Vue {
|
||||
.project-overview {
|
||||
padding: 40px 65px 55px 65px;
|
||||
position: relative;
|
||||
height: 85vh;
|
||||
|
||||
&__navigation {
|
||||
position: absolute;
|
||||
|
@ -2,26 +2,26 @@
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import { StoreModule } from '@/store';
|
||||
import { ReferralApi } from '@/types/referral';
|
||||
import { ReferralApi, ReferralLink } from '@/types/referral';
|
||||
|
||||
export const REFERRAL_ACTIONS = {
|
||||
GET_LINKS: 'getReferralLinks',
|
||||
GET_TOKENS: 'getReferralTokens',
|
||||
};
|
||||
|
||||
export const REFERRAL_MUTATIONS = {
|
||||
SET_LINKS: 'setReferralLinks',
|
||||
SET_TOKENS: 'setReferralTokens',
|
||||
};
|
||||
|
||||
const {
|
||||
GET_LINKS,
|
||||
GET_TOKENS,
|
||||
} = REFERRAL_ACTIONS;
|
||||
|
||||
const {
|
||||
SET_LINKS,
|
||||
SET_TOKENS,
|
||||
} = REFERRAL_MUTATIONS;
|
||||
|
||||
export class ReferralState {
|
||||
public referralLinks = [];
|
||||
public referralTokens: string[] = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,17 +33,24 @@ export function makeReferralModule(api: ReferralApi): StoreModule<ReferralState>
|
||||
return {
|
||||
state: new ReferralState(),
|
||||
mutations: {
|
||||
[SET_LINKS](state: ReferralState, referralLinks): void {
|
||||
state.referralLinks = referralLinks;
|
||||
[SET_TOKENS](state: ReferralState, referralTokens: string[]): void {
|
||||
state.referralTokens = referralTokens;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
[GET_LINKS]: async function ({commit}: any): Promise<any> {
|
||||
const referralLinks = await api.getLinks();
|
||||
[GET_TOKENS]: async function ({commit}: any): Promise<string[]> {
|
||||
const referralTokens = await api.getTokens();
|
||||
|
||||
commit(GET_LINKS, referralLinks);
|
||||
commit(SET_TOKENS, referralTokens);
|
||||
|
||||
return referralLinks;
|
||||
return referralTokens;
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
referralLinks: (state: ReferralState): ReferralLink[] => {
|
||||
return state.referralTokens.map(token => {
|
||||
return new ReferralLink(token);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -11,5 +11,16 @@ export interface ReferralApi {
|
||||
* @returns links
|
||||
* @throws Error
|
||||
*/
|
||||
getLinks(): Promise<any>;
|
||||
getTokens(): Promise<string[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* ReferralLink creates url from token
|
||||
*/
|
||||
export class ReferralLink {
|
||||
public url: string = '';
|
||||
|
||||
constructor(token: string = '') {
|
||||
this.url = `${location.host}/register?referralToken=${token}`;
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,13 @@
|
||||
<div class="dashboard-container__wrap__column">
|
||||
<DashboardHeader/>
|
||||
<div class="dashboard-container__main-area">
|
||||
<VBanner
|
||||
v-if="isBannerShown"
|
||||
text="You have no payment method added."
|
||||
additional-text="To start work with your account please add Credit Card or add $50.00 or more worth of STORJ tokens to your balance."
|
||||
/>
|
||||
<div class="dashboard-container__main-area__banner-area">
|
||||
<VBanner
|
||||
v-if="isBannerShown"
|
||||
text="You have no payment method added."
|
||||
additional-text="To start work with your account please add Credit Card or add $50.00 or more worth of STORJ tokens to your balance."
|
||||
/>
|
||||
</div>
|
||||
<div class="dashboard-container__main-area__content">
|
||||
<router-view/>
|
||||
</div>
|
||||
@ -33,7 +35,6 @@ import DashboardHeader from '@/components/header/HeaderArea.vue';
|
||||
import NavigationArea from '@/components/navigation/NavigationArea.vue';
|
||||
|
||||
import { ErrorUnauthorized } from '@/api/errors/ErrorUnauthorized';
|
||||
import { PaymentsHttpApi } from '@/api/payments';
|
||||
import { RouteConfig } from '@/router';
|
||||
import { BUCKET_ACTIONS } from '@/store/modules/buckets';
|
||||
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
|
||||
@ -49,7 +50,6 @@ import {
|
||||
} from '@/utils/constants/actionNames';
|
||||
import { AppState } from '@/utils/constants/appStateEnum';
|
||||
import { LocalData } from '@/utils/localData';
|
||||
import { MetaUtils } from '@/utils/meta';
|
||||
|
||||
const {
|
||||
SETUP_ACCOUNT,
|
||||
@ -207,27 +207,16 @@ export default class DashboardArea extends Vue {
|
||||
width: 100%;
|
||||
height: calc(100vh - 50px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media screen and (max-height: 900px) {
|
||||
&__banner-area {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.dashboard-container__main-area__content {
|
||||
height: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 700px) {
|
||||
|
||||
.dashboard-container__main-area__content {
|
||||
height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 500px) {
|
||||
|
||||
.dashboard-container__main-area__content {
|
||||
height: 300px;
|
||||
&__content {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ export default class RegisterArea extends Vue {
|
||||
|
||||
// tardigrade logic
|
||||
private secret: string = '';
|
||||
private referralToken: string = '';
|
||||
private refUserId: string = '';
|
||||
|
||||
private userId: string = '';
|
||||
@ -62,6 +63,10 @@ export default class RegisterArea extends Vue {
|
||||
this.secret = this.$route.query.token.toString();
|
||||
}
|
||||
|
||||
if (this.$route.query.referralToken) {
|
||||
this.referralToken = this.$route.query.referralToken.toString();
|
||||
}
|
||||
|
||||
const { ids = '' } = this.$route.params;
|
||||
let decoded = '';
|
||||
try {
|
||||
@ -165,7 +170,9 @@ export default class RegisterArea extends Vue {
|
||||
|
||||
private async createUser(): Promise<void> {
|
||||
try {
|
||||
this.userId = await this.auth.register(this.user, this.secret, this.refUserId);
|
||||
this.userId = this.referralToken ?
|
||||
await this.auth.referralRegister(this.user, this.referralToken) :
|
||||
await this.auth.register(this.user, this.secret, this.refUserId);
|
||||
|
||||
LocalData.setUserId(this.userId);
|
||||
|
||||
|
@ -8,7 +8,9 @@ exports[`Dashboard renders correctly when data is loaded 1`] = `
|
||||
<div class="dashboard-container__wrap__column">
|
||||
<dashboardheader-stub></dashboardheader-stub>
|
||||
<div class="dashboard-container__main-area">
|
||||
<vbanner-stub text="You have no payment method added." additionaltext="To start work with your account please add Credit Card or add $50.00 or more worth of STORJ tokens to your balance."></vbanner-stub>
|
||||
<div class="dashboard-container__main-area__banner-area">
|
||||
<vbanner-stub text="You have no payment method added." additionaltext="To start work with your account please add Credit Card or add $50.00 or more worth of STORJ tokens to your balance."></vbanner-stub>
|
||||
</div>
|
||||
<div class="dashboard-container__main-area__content">
|
||||
<router-view-stub name="default"></router-view-stub>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user