web/satellite: added create project prompt modal for free tier users
Added new modal when free tier user tries to create new project. This modal prompts to upgrade account. Change-Id: I0e787e35b099387a08186c7df7fc080092d2366c
This commit is contained in:
parent
95ae739d9c
commit
aba7de6c32
@ -60,9 +60,9 @@ func TestNavigation(t *testing.T) {
|
||||
page.MustElement("[aria-roledescription=project-selection]").MustClick()
|
||||
page.MustElementR("p", "Create new").MustClick()
|
||||
waitVueTick(page)
|
||||
createProjectTitle := page.MustElement("[aria-roledescription=title]").MustText()
|
||||
require.Contains(t, createProjectTitle, "Create a Project")
|
||||
page.MustNavigateBack()
|
||||
createProjectPromptTitle := page.MustElement("[aria-roledescription=modal-title]").MustText()
|
||||
require.Contains(t, createProjectPromptTitle, "Get more projects\nwhen you upgrade")
|
||||
page.MustElement(".close-cross-container").MustClick()
|
||||
|
||||
// project dashboard route
|
||||
page.MustElementR("p", "Dashboard").MustClick()
|
||||
|
@ -0,0 +1,136 @@
|
||||
// Copyright (C) 2022 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<div class="prompt">
|
||||
<div class="prompt__modal">
|
||||
<img
|
||||
class="prompt__modal__icon"
|
||||
src="@/../static/images/account/billing/paidTier/prompt.png"
|
||||
alt="Prompt Image"
|
||||
>
|
||||
<h1 class="prompt__modal__title" aria-roledescription="modal-title">
|
||||
Get more projects<br>when you upgrade
|
||||
</h1>
|
||||
<p class="prompt__modal__info">
|
||||
Upgrade your Free Account to create<br>more projects and gain access to higher limits.
|
||||
</p>
|
||||
<VButton
|
||||
width="256px"
|
||||
height="56px"
|
||||
border-radius="8px"
|
||||
label="Upgrade to Pro Account ->"
|
||||
:on-press="onClick"
|
||||
/>
|
||||
<div class="close-cross-container" @click="onClose">
|
||||
<CloseCrossIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
|
||||
import { APP_STATE_MUTATIONS } from "@/store/mutationConstants";
|
||||
import { PAYMENTS_MUTATIONS } from "@/store/modules/payments";
|
||||
import VButton from '@/components/common/VButton.vue';
|
||||
|
||||
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
|
||||
|
||||
// @vue/component
|
||||
@Component({
|
||||
components: {
|
||||
VButton,
|
||||
CloseCrossIcon,
|
||||
},
|
||||
})
|
||||
export default class CreateProjectPromptModal extends Vue {
|
||||
@Prop({default: () => false})
|
||||
public readonly onClose: () => void;
|
||||
|
||||
/**
|
||||
* Holds on button click logic.
|
||||
* Closes this modal and opens upgrade account modal.
|
||||
*/
|
||||
public onClick(): void {
|
||||
this.$store.commit(APP_STATE_MUTATIONS.TOGGLE_CREATE_PROJECT_PROMPT_POPUP);
|
||||
this.$store.commit(PAYMENTS_MUTATIONS.TOGGLE_IS_ADD_PM_MODAL_SHOWN);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.prompt {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
background: rgb(27 37 51 / 75%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'font_regular', sans-serif;
|
||||
|
||||
&__modal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 0 32px rgb(0 0 0 / 4%);
|
||||
width: 600px;
|
||||
position: relative;
|
||||
padding: 50px 0 65px;
|
||||
|
||||
&__icon {
|
||||
max-height: 154px;
|
||||
max-width: 118px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-family: 'font_bold', sans-serif;
|
||||
font-size: 28px;
|
||||
line-height: 34px;
|
||||
color: #1b2533;
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__info {
|
||||
font-family: 'font_regular', sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 21px;
|
||||
text-align: center;
|
||||
color: #354049;
|
||||
margin: 15px 0 45px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close-cross-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 30px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover .close-cross-svg-path {
|
||||
fill: #2683ff;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 900px) {
|
||||
|
||||
.prompt {
|
||||
padding: 150px 0 20px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -64,7 +64,9 @@ import { OBJECTS_ACTIONS } from "@/store/modules/objects";
|
||||
import { PAYMENTS_ACTIONS } from "@/store/modules/payments";
|
||||
import { ACCESS_GRANTS_ACTIONS } from "@/store/modules/accessGrants";
|
||||
import { BUCKET_ACTIONS } from "@/store/modules/buckets";
|
||||
import { APP_STATE_MUTATIONS } from "@/store/mutationConstants";
|
||||
import { Project } from "@/types/projects";
|
||||
import { User } from "@/types/users";
|
||||
|
||||
import ProjectIcon from '@/../static/images/navigation/project.svg';
|
||||
import ArrowImage from '@/../static/images/navigation/arrowExpandRight.svg';
|
||||
@ -223,7 +225,15 @@ export default class NewProjectSelection extends Vue {
|
||||
public onCreateLinkClick(): void {
|
||||
if (this.$route.name !== RouteConfig.CreateProject.name) {
|
||||
this.analytics.linkEventTriggered(AnalyticsEvent.PATH_SELECTED, "Create New Project");
|
||||
this.$router.push(RouteConfig.CreateProject.path);
|
||||
|
||||
const user: User = this.$store.getters.user;
|
||||
const ownProjectsCount: number = this.$store.getters.projectsCount;
|
||||
|
||||
if (!user.paidTier && user.projectLimit === ownProjectsCount) {
|
||||
this.$store.commit(APP_STATE_MUTATIONS.TOGGLE_CREATE_PROJECT_PROMPT_POPUP);
|
||||
} else {
|
||||
this.$router.push(RouteConfig.CreateProject.path);
|
||||
}
|
||||
}
|
||||
|
||||
this.closeDropdown();
|
||||
|
@ -30,6 +30,7 @@ class ViewsState {
|
||||
public isPaymentSelectionShown = false,
|
||||
public isUploadCancelPopupVisible = false,
|
||||
public isSuccessfulPasswordResetShown = false,
|
||||
public isCreateProjectPromptModalShown = false,
|
||||
|
||||
public onbAGStepBackRoute = "",
|
||||
public onbAPIKeyStepBackRoute = "",
|
||||
@ -117,6 +118,9 @@ export const appStateModule = {
|
||||
[APP_STATE_MUTATIONS.TOGGLE_UPLOAD_CANCEL_POPUP](state: State): void {
|
||||
state.appState.isUploadCancelPopupVisible = !state.appState.isUploadCancelPopupVisible;
|
||||
},
|
||||
[APP_STATE_MUTATIONS.TOGGLE_CREATE_PROJECT_PROMPT_POPUP](state: State): void {
|
||||
state.appState.isCreateProjectPromptModalShown = !state.appState.isCreateProjectPromptModalShown;
|
||||
},
|
||||
[APP_STATE_MUTATIONS.SHOW_SET_DEFAULT_PAYMENT_METHOD_POPUP](state: State, id: string): void {
|
||||
state.appState.setDefaultPaymentMethodID = id;
|
||||
},
|
||||
|
@ -29,6 +29,7 @@ export const APP_STATE_MUTATIONS = {
|
||||
TOGGLE_EDIT_PROFILE_POPUP: 'TOGGLE_EDIT_PROFILE_POPUP',
|
||||
TOGGLE_CHANGE_PASSWORD_POPUP: 'TOGGLE_CHANGE_PASSWORD_POPUP',
|
||||
TOGGLE_UPLOAD_CANCEL_POPUP: 'TOGGLE_UPLOAD_CANCEL_POPUP',
|
||||
TOGGLE_CREATE_PROJECT_PROMPT_POPUP: 'TOGGLE_CREATE_PROJECT_PROMPT_POPUP',
|
||||
SHOW_DELETE_PAYMENT_METHOD_POPUP: 'SHOW_DELETE_PAYMENT_METHOD_POPUP',
|
||||
SHOW_SET_DEFAULT_PAYMENT_METHOD_POPUP: 'SHOW_SET_DEFAULT_PAYMENT_METHOD_POPUP',
|
||||
CLOSE_ALL: 'CLOSE_ALL',
|
||||
|
@ -49,6 +49,8 @@
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<!-- TODO: put all the modals to one single wrapper component and move out all the logic from here -->
|
||||
<CreateProjectPromptModal v-if="isCreateProjectPromptModal" :on-close="toggleCreateProjectPromptModal" />
|
||||
<AddPaymentMethodModal v-if="isAddPMModal" :on-close="togglePMModal" />
|
||||
<MFARecoveryCodesPopup v-if="isMFACodesPopup" :toggle-modal="toggleMFACodesPopup" />
|
||||
</div>
|
||||
@ -58,6 +60,7 @@
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import AddPaymentMethodModal from '@/components/account/billing/paidTier/AddPaymentMethodModal.vue';
|
||||
import CreateProjectPromptModal from "@/components/account/billing/paidTier/CreateProjectPromptModal.vue";
|
||||
import PaidTierBar from '@/components/infoBars/PaidTierBar.vue';
|
||||
import MFARecoveryCodeBar from '@/components/infoBars/MFARecoveryCodeBar.vue';
|
||||
import BetaSatBar from '@/components/infoBars/BetaSatBar.vue';
|
||||
@ -79,6 +82,7 @@ import { CouponType } from '@/types/coupons';
|
||||
import { CreditCard } from '@/types/payments';
|
||||
import { Project } from '@/types/projects';
|
||||
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
|
||||
import { APP_STATE_MUTATIONS } from "@/store/mutationConstants";
|
||||
import { AppState } from '@/utils/constants/appStateEnum';
|
||||
import { LocalData } from '@/utils/localData';
|
||||
import { User } from "@/types/users";
|
||||
@ -93,6 +97,7 @@ const {
|
||||
// @vue/component
|
||||
@Component({
|
||||
components: {
|
||||
CreateProjectPromptModal,
|
||||
NavigationArea,
|
||||
NewNavigationArea,
|
||||
DashboardHeader,
|
||||
@ -206,6 +211,13 @@ export default class DashboardArea extends Vue {
|
||||
this.$store.commit(PAYMENTS_MUTATIONS.TOGGLE_IS_ADD_PM_MODAL_SHOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles create project prompt modal.
|
||||
*/
|
||||
public toggleCreateProjectPromptModal(): void {
|
||||
this.$store.commit(APP_STATE_MUTATIONS.TOGGLE_CREATE_PROJECT_PROMPT_POPUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles MFA recovery codes popup visibility.
|
||||
*/
|
||||
@ -269,6 +281,13 @@ export default class DashboardArea extends Vue {
|
||||
return this.$store.state.paymentsModule.isAddPMModalShown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if create project prompt modal is shown.
|
||||
*/
|
||||
public get isCreateProjectPromptModal(): boolean {
|
||||
return this.$store.state.appStateModule.appState.isCreateProjectPromptModalShown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns credit cards from store.
|
||||
*/
|
||||
|
BIN
web/satellite/static/images/account/billing/paidTier/prompt.png
Normal file
BIN
web/satellite/static/images/account/billing/paidTier/prompt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
@ -16,6 +16,7 @@ exports[`Dashboard renders correctly when data is loaded 1`] = `
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -27,5 +28,6 @@ exports[`Dashboard renders correctly when data is loading 1`] = `
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user