Initial commit
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<section class="welcome-section">
|
||||
<WelcomeFirst v-if="isFirst" :name="name" :userType="userType"></WelcomeFirst>
|
||||
<WelcomeCompact v-if="!isFirst" :name="name" :userType="userType">
|
||||
<template v-if="trialEndDate">
|
||||
<span v-html="trialTimeLeft" class="title is-small"></span>
|
||||
<a class="title is-small" :href="accountUpgradeURL" v-if="accountUpgradeURL">
|
||||
{{ $t('HomePage.WelcomeSection.subscribeNow') }}
|
||||
</a>
|
||||
</template>
|
||||
</WelcomeCompact>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import distanceInWordsStrict from 'date-fns/distance_in_words_strict';
|
||||
import WelcomeCompact from './WelcomeCompact';
|
||||
import WelcomeFirst from './WelcomeFirst';
|
||||
import WelcomeBasic from './WelcomeBasic';
|
||||
import { isOrganizationAdmin } from 'new-dashboard/core/models/organization';
|
||||
|
||||
export default {
|
||||
name: 'Welcome',
|
||||
components: {
|
||||
WelcomeBasic,
|
||||
WelcomeCompact,
|
||||
WelcomeFirst
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isFirst: state => state.config.isFirstTimeViewingDashboard,
|
||||
accountUpgradeURL: state => state.config.upgrade_url,
|
||||
trialEndDate: state => state.user.trial_ends_at,
|
||||
user: state => state.user,
|
||||
name: state => state.user.name || state.user.username,
|
||||
organization: state => state.user.organization,
|
||||
notifications: state => state.user.organizationNotifications
|
||||
}),
|
||||
trialTimeLeft () {
|
||||
return this.$t(`HomePage.WelcomeSection.trialMessage`, { date: distanceInWordsStrict(this.trialEndDate, new Date(), { partialMethod: 'round' }) });
|
||||
},
|
||||
userType () {
|
||||
if (this.isOrganizationAdmin()) {
|
||||
return 'organizationAdmin';
|
||||
}
|
||||
|
||||
if (this.isOrganizationUser()) {
|
||||
return 'organizationUser';
|
||||
}
|
||||
|
||||
if (this.isIndividualUser()) {
|
||||
return 'individual';
|
||||
}
|
||||
|
||||
if (this.isPersonal30()) {
|
||||
return '30day';
|
||||
}
|
||||
|
||||
if (this.isFreeUser()) {
|
||||
return 'free';
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isPersonal30 () {
|
||||
const personal30User = ['PERSONAL30'];
|
||||
return personal30User.includes(this.user.account_type);
|
||||
},
|
||||
isFreeUser () {
|
||||
const freeUser = ['FREE'];
|
||||
return freeUser.includes(this.user.account_type);
|
||||
},
|
||||
isIndividualUser () {
|
||||
const individualUsers = ['Individual'];
|
||||
return individualUsers.includes(this.user.account_type);
|
||||
},
|
||||
isOrganizationAdmin () {
|
||||
if (!this.isOrganizationUser()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isOrganizationAdmin(this.user.organization, this.user);
|
||||
},
|
||||
isOrganizationUser () {
|
||||
return Boolean(this.organization);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<section class="welcome-basic">
|
||||
<div class="container">
|
||||
<div class="welcome-basic__greeting title is-title">{{ greeting }}</div>
|
||||
<span v-if="hasNotifications" class="notification-led"></span>
|
||||
<div class="welcome-basic__text text is-caption">{{ text }}</div>
|
||||
<div class="welcome-basic__actions">
|
||||
<button v-if="!hasNotifications" class="button button--small is-primary">Learn More</button>
|
||||
<button v-if="hasNotifications" class="button button--small is-primary">Go to Notifications</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'WelcomeBasic',
|
||||
props: {
|
||||
username: String,
|
||||
notifications: Array
|
||||
},
|
||||
computed: {
|
||||
greeting () {
|
||||
return this.$t('HomePage.WelcomeSection.greeting', {username: this.$props.username});
|
||||
},
|
||||
text () {
|
||||
return this.hasNotifications
|
||||
? 'You have unread notifications, do you want to read them now?'
|
||||
: 'We just released CARTO VL, our new vector rendering Javascript library to create amazing LI applications.';
|
||||
},
|
||||
hasNotifications () {
|
||||
return this.$props.notifications.length > 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "new-dashboard/styles/variables";
|
||||
|
||||
.welcome-basic {
|
||||
position: relative;
|
||||
padding: 124px 0;
|
||||
text-align: center;
|
||||
|
||||
.notification-led {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: $notification__bg-color;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&__greeting {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&__text {
|
||||
max-width: 724px;
|
||||
margin: 16px auto 48px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<section class="welcome-compact">
|
||||
<div class="container welcome-compact__content">
|
||||
<div class="welcome-compact__greeting title is-caption">{{ greeting }}</div>
|
||||
<div class="welcome-compact__actions">
|
||||
<OnboardingButton :isFirstTimeViewingDashboard="false"></OnboardingButton>
|
||||
<CreateButton class="button--ghost" visualizationType="map" :disabled="isViewer">{{ $t(`HomePage.WelcomeSection.actions.createMap`) }}</CreateButton>
|
||||
<CreateButton class="button--ghost" visualizationType="dataset" :disabled="!canCreateDatasets">{{ $t(`HomePage.WelcomeSection.actions.createDataset`) }}</CreateButton>
|
||||
</div>
|
||||
|
||||
<div class="welcome-compact__extra">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CreateButton from 'new-dashboard/components/CreateButton.vue';
|
||||
import OnboardingButton from 'new-dashboard/components/Onboarding/OnboardingButton.vue';
|
||||
|
||||
export default {
|
||||
name: 'WelcomeCompact',
|
||||
components: {
|
||||
CreateButton,
|
||||
OnboardingButton
|
||||
},
|
||||
props: {
|
||||
name: String
|
||||
},
|
||||
computed: {
|
||||
greeting () {
|
||||
return this.$t('HomePage.WelcomeSection.greeting', {name: this.$props.name});
|
||||
},
|
||||
canCreateDatasets () {
|
||||
return this.$store.getters['user/canCreateDatasets'];
|
||||
},
|
||||
isViewer () {
|
||||
return this.$store.getters['user/isViewer'];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "new-dashboard/styles/variables";
|
||||
|
||||
.welcome-compact__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 940px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.welcome-compact {
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid #E6E8EB;
|
||||
|
||||
&__greeting {
|
||||
display: inline-block;
|
||||
margin-right: 64px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
&__extra {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.button--ghost {
|
||||
margin-right: 48px;
|
||||
padding: 0;
|
||||
background: none;
|
||||
color: #047AE6;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.button--outline {
|
||||
margin-left: 24px;
|
||||
padding: 9px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<section class="welcome-first">
|
||||
<div class="container">
|
||||
<div class="welcome-first__greeting title is-title">{{ greeting }}</div>
|
||||
<div class="welcome-first__text text is-caption" v-html="text"></div>
|
||||
<div class="welcome-first__actions">
|
||||
<OnboardingButton v-if="!isOrganizationAdmin" :isFirstTimeViewingDashboard="true"></OnboardingButton>
|
||||
<a class="button button--border"
|
||||
:href="`${ baseUrl }/organization`"
|
||||
v-if="isOrganizationAdmin">
|
||||
{{ $t('HomePage.WelcomeSection.firstTime.manageOrganization') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import differenceInDays from 'date-fns/difference_in_days';
|
||||
import CreateButton from 'new-dashboard/components/CreateButton.vue';
|
||||
import OnboardingButton from 'new-dashboard/components/Onboarding/OnboardingButton.vue';
|
||||
|
||||
export default {
|
||||
name: 'WelcomeFirst',
|
||||
components: {
|
||||
CreateButton,
|
||||
OnboardingButton
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
userType: String
|
||||
},
|
||||
computed: {
|
||||
greeting () {
|
||||
return this.$t('HomePage.WelcomeSection.greeting', {name: this.$props.name});
|
||||
},
|
||||
text () {
|
||||
const organizationName = this.$store.state.user.organization && this.$store.state.user.organization.name;
|
||||
|
||||
const firstTimeMessage = this.$t('HomePage.WelcomeSection.firstTime.message');
|
||||
const planMessage = this.$t(`HomePage.WelcomeSection.firstTime.planMessage.${this.userType}`, {
|
||||
organizationName,
|
||||
trialLength: this.trialLength
|
||||
});
|
||||
|
||||
return `${firstTimeMessage} ${planMessage}`;
|
||||
},
|
||||
baseUrl () {
|
||||
return this.$store.state.user.base_url;
|
||||
},
|
||||
isOrganizationAdmin () {
|
||||
return this.userType === 'organizationAdmin';
|
||||
},
|
||||
isOrganizationUser () {
|
||||
return this.userType === 'organizationUser';
|
||||
},
|
||||
organizationMail () {
|
||||
const organization = this.$store.state.user.organization;
|
||||
return organization.admin_email;
|
||||
},
|
||||
canCreateDatasets () {
|
||||
return this.$store.getters['user/canCreateDatasets'];
|
||||
},
|
||||
isViewer () {
|
||||
return this.$store.getters['user/isViewer'];
|
||||
},
|
||||
trialLength () {
|
||||
const trialEndDate = this.$store.state.user.trial_ends_at;
|
||||
const createdAt = this.$store.state.user.created_at;
|
||||
return trialEndDate ? differenceInDays(trialEndDate, createdAt) : null;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "new-dashboard/styles/variables";
|
||||
|
||||
.welcome-first {
|
||||
position: relative;
|
||||
padding: 124px 0;
|
||||
background: $primary-color;
|
||||
color: $white;
|
||||
text-align: center;
|
||||
|
||||
&__text {
|
||||
max-width: 724px;
|
||||
margin: 16px auto 48px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button.button--border {
|
||||
border: 1px solid $white;
|
||||
background: none;
|
||||
color: $white;
|
||||
text-transform: uppercase;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user