Rework onboarding

Close #435

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2020-11-13 13:39:52 +01:00
parent 347448700d
commit 223512f8ae
14 changed files with 308 additions and 100 deletions

View File

@@ -64,7 +64,7 @@
</form>
<div v-if="validationSent && !userAlreadyActivated">
<b-message type="is-success" closable="false">
<b-message type="is-success" :closable="false">
<h2 class="title">
{{
$t("Your account is nearly ready, {username}", {

View File

@@ -850,7 +850,7 @@ export default class EditEvent extends Vue {
this.$buefy.dialog.confirm({
title,
message,
confirmText: this.$t("Abandon edition") as string,
confirmText: this.$t("Abandon editing") as string,
cancelText: this.$t("Continue editing") as string,
type: "is-warning",
hasIcon: true,

View File

@@ -168,19 +168,18 @@
<b-message v-else type="is-danger">{{ $t("No events found") }}</b-message>
</section>
</div>
<settings-onboard v-else-if="config && loggedUser && loggedUser.settings == undefined" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { Component, Vue, Watch } from "vue-property-decorator";
import { IParticipant, Participant, ParticipantRole } from "../types/participant.model";
import { FETCH_EVENTS } from "../graphql/event";
import EventListCard from "../components/Event/EventListCard.vue";
import EventCard from "../components/Event/EventCard.vue";
import { CURRENT_ACTOR_CLIENT, LOGGED_USER_PARTICIPATIONS } from "../graphql/actor";
import { IPerson, Person } from "../types/actor";
import { ICurrentUser } from "../types/current-user.model";
import { ICurrentUser, IUser } from "../types/current-user.model";
import { CURRENT_USER_CLIENT, USER_SETTINGS } from "../graphql/user";
import RouteName from "../router/name";
import { IEvent } from "../types/event.model";
@@ -386,6 +385,13 @@ export default class Home extends Vue {
viewEvent(event: IEvent): void {
this.$router.push({ name: RouteName.EVENT, params: { uuid: event.uuid } });
}
@Watch("loggedUser")
detectEmptyUserSettings(loggedUser: IUser): void {
if (loggedUser && loggedUser.id && loggedUser.settings === null) {
this.$router.push({ name: RouteName.WELCOME_SCREEN, params: { step: "1" } });
}
}
}
</script>

View File

@@ -322,20 +322,6 @@ export default class AccountSettings extends Vue {
}
}
</script>
<style lang="scss">
.setting-title {
margin-top: 2rem;
margin-bottom: 1rem;
h2 {
display: inline;
background: $secondary;
padding: 2px 7.5px;
text-transform: uppercase;
font-size: 1.25rem;
}
}
</style>
<style lang="scss" scoped>
.cancel-button {

View File

@@ -1,48 +1,94 @@
<template>
<div class="section container">
<h1 class="title">{{ $t("Let's define a few settings") }}</h1>
<settings-onboarding />
<notifications-onboarding />
<section class="has-text-centered section">
<b-button @click="refresh()" type="is-success" size="is-big">
<b-steps v-model="realActualStepIndex" :has-navigation="false">
<b-step-item step="1" :label="$t('Settings')">
<settings-onboarding />
</b-step-item>
<b-step-item step="2" :label="$t('Participation notifications')">
<notifications-onboarding />
</b-step-item>
<b-step-item step="3" :label="$t('Profiles and federation')">
<profile-onboarding />
</b-step-item>
</b-steps>
<section class="has-text-centered section buttons">
<b-button
outlined
:disabled="realActualStepIndex < 1"
tag="router-link"
:to="{
name: RouteName.WELCOME_SCREEN,
params: { step: actualStepIndex - 1 },
}"
>
{{ $t("Previous") }}
</b-button>
<b-button
outlined
type="is-success"
v-if="realActualStepIndex < 2"
tag="router-link"
:to="{
name: RouteName.WELCOME_SCREEN,
params: { step: actualStepIndex + 1 },
}"
>
{{ $t("Next") }}
</b-button>
<b-button
v-if="realActualStepIndex >= 2"
type="is-success"
size="is-big"
tag="router-link"
:to="{ name: RouteName.HOME }"
>
{{ $t("All good, let's continue!") }}
</b-button>
</section>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import { SET_USER_SETTINGS } from "../../graphql/user";
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { TIMEZONES } from "../../graphql/config";
import RouteName from "../../router/name";
import { IConfig } from "../../types/config.model";
@Component({
components: {
NotificationsOnboarding: () => import("../../components/Settings/NotificationsOnboarding.vue"),
SettingsOnboarding: () => import("../../components/Settings/SettingsOnboarding.vue"),
ProfileOnboarding: () => import("../../components/Account/ProfileOnboarding.vue"),
},
apollo: {
config: TIMEZONES,
},
})
export default class SettingsOnboard extends Vue {
@Prop({ required: false, default: 1, type: Number }) step!: number;
config!: IConfig;
@Watch("config")
async timezoneLoaded() {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (this.config && this.config.timezones.includes(timezone)) {
await this.$apollo.mutate<{ setUserSettings: string }>({
mutation: SET_USER_SETTINGS,
variables: {
timezone,
},
});
RouteName = RouteName;
actualStepIndex = this.step;
@Watch("step")
updateActualStep(): void {
if (this.step) {
this.actualStepIndex = this.step;
}
}
refresh() {
location.reload();
get realActualStepIndex(): number {
return this.actualStepIndex - 1;
}
}
</script>
<style scoped lang="scss">
.section.container {
.has-text-centered.section.buttons {
justify-content: center;
}
}
</style>