Add onboarding visited flag to user
This commit is contained in:
parent
5778f98448
commit
f588abee43
|
|
@ -5,5 +5,6 @@ query MeQuery {
|
||||||
...UserParts
|
...UserParts
|
||||||
isTeacher
|
isTeacher
|
||||||
permissions
|
permissions
|
||||||
|
onboardingVisited
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
mutation UpdateOnboardingProgress {
|
||||||
|
updateOnboardingProgress {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -127,6 +127,12 @@ function redirectStudentsWithoutClass() {
|
||||||
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0);
|
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function redirectUsersToOnboarding(to) {
|
||||||
|
return privateApolloClient.query({
|
||||||
|
query: ME_QUERY,
|
||||||
|
}).then(({data}) => !data.me.onboardingVisited);
|
||||||
|
}
|
||||||
|
|
||||||
function networkErrorCallback(statusCode) {
|
function networkErrorCallback(statusCode) {
|
||||||
if (statusCode === 402) {
|
if (statusCode === 402) {
|
||||||
router.push({name: 'licenseActivation'}, 0);
|
router.push({name: 'licenseActivation'}, 0);
|
||||||
|
|
@ -156,6 +162,11 @@ router.beforeEach(async (to, from, next) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((to.name.indexOf('onboarding') === -1) && await redirectUsersToOnboarding()) {
|
||||||
|
next({name: 'onboarding-start'})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="['onboarding', {'onboarding--illustration': illustration}]" >
|
<div :class="['onboarding', {'onboarding--illustration': illustration}]">
|
||||||
<div class="onboarding__illustration">
|
<div class="onboarding__illustration">
|
||||||
<component :is="illustration" />
|
<component :is="illustration"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="onboarding__content">
|
<div class="onboarding__content">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
<router-link
|
<a
|
||||||
:to="next"
|
class="onboarding__button button button--primary button--big"
|
||||||
class="onboarding__button button button--primary button--big">{{ nextLabel }}
|
@click="next">{{ nextLabel }}
|
||||||
</router-link>
|
</a>
|
||||||
<router-link
|
<a
|
||||||
:to="{name:'home'}"
|
class="onboarding__secondary-link"
|
||||||
class="onboarding__secondary-link">Einführung überspringen</router-link>
|
@click.prevent="completeOnboarding">Einführung überspringen</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
import PortfolioIllustration from '@/components/illustrations/PortfolioIllustration';
|
import PortfolioIllustration from '@/components/illustrations/PortfolioIllustration';
|
||||||
import RoomsIllustration from '@/components/illustrations/RoomsIllustration';
|
import RoomsIllustration from '@/components/illustrations/RoomsIllustration';
|
||||||
|
|
||||||
|
import UPDATE_ONBOARDING_PROGRESS from '@/graphql/gql/mutations/updateOnboardingProgress.gql';
|
||||||
|
import ME_QUERY from '@/graphql/gql/meQuery';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
contents: ContentsIllustration,
|
contents: ContentsIllustration,
|
||||||
|
|
@ -29,17 +32,37 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
next() {
|
|
||||||
return {
|
|
||||||
name: this.$route.meta.next
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nextLabel() {
|
nextLabel() {
|
||||||
return this.$route.name === 'onboarding-start' ? 'Einführung starten' : 'Weiter'
|
return this.$route.name === 'onboarding-start' ? 'Einführung starten' : 'Weiter'
|
||||||
},
|
},
|
||||||
illustration() {
|
illustration() {
|
||||||
return this.$route.meta.illustration
|
return this.$route.meta.illustration
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
next() {
|
||||||
|
const next = this.$route.meta.next;
|
||||||
|
if (next === 'home') {
|
||||||
|
this.completeOnboarding();
|
||||||
|
}
|
||||||
|
this.$router.push({name: next});
|
||||||
|
},
|
||||||
|
completeOnboarding() {
|
||||||
|
const router = this.$router;
|
||||||
|
this.$apollo.mutate({
|
||||||
|
mutation: UPDATE_ONBOARDING_PROGRESS,
|
||||||
|
update(store, {data: {updateOnboardingProgress: {success}}}) {
|
||||||
|
const query = ME_QUERY;
|
||||||
|
const data = store.readQuery({query});
|
||||||
|
if (data) {
|
||||||
|
data.me.onboardingVisited = success;
|
||||||
|
store.writeQuery({query, data})
|
||||||
|
}
|
||||||
|
router.push({name: 'home'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -142,10 +165,12 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: $large-spacing;
|
margin-bottom: $large-spacing;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__secondary-link {
|
&__secondary-link {
|
||||||
@include inline-title;
|
@include inline-title;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
@include desktop {
|
@include desktop {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,15 @@
|
||||||
class="button">Alle News anzeigen
|
class="button">Alle News anzeigen
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="start-page__onboarding">
|
||||||
|
<h2 class="start-page__heading">Kennen Sie schon alle Bereiche von mySkillbox?</h2>
|
||||||
|
<p class="start-page__paragraph">Schauen Sie sich jetzt die Einführung zu mySkillbox an.</p>
|
||||||
|
<router-link
|
||||||
|
:to="{name: 'onboarding-start'}"
|
||||||
|
class="button button--primary">Los geht's
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -130,6 +139,11 @@
|
||||||
@include meta-title;
|
@include meta-title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__paragraph {
|
||||||
|
@include regular-text;
|
||||||
|
margin-bottom: $large-spacing;
|
||||||
|
}
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
padding-top: 2*$large-spacing;
|
padding-top: 2*$large-spacing;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 2.2.12 on 2020-07-07 15:01
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('books', '0022_recentmodule'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='recentmodule',
|
||||||
|
options={'get_latest_by': 'visited'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='recentmodule',
|
||||||
|
name='module',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recent_modules', to='books.Module'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.12 on 2020-07-07 15:01
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0020_user_recent_modules'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='onboarding_visited',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -24,6 +24,7 @@ class User(AbstractUser):
|
||||||
hep_id = models.PositiveIntegerField(null=True, blank=False)
|
hep_id = models.PositiveIntegerField(null=True, blank=False)
|
||||||
hep_group_id = models.PositiveIntegerField(null=True, blank=False)
|
hep_group_id = models.PositiveIntegerField(null=True, blank=False)
|
||||||
license_expiry_date = models.DateField(blank=False, null=True, default=None)
|
license_expiry_date = models.DateField(blank=False, null=True, default=None)
|
||||||
|
onboarding_visited = models.BooleanField(default=False)
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,19 @@ class CreateSchoolClass(relay.ClientIDMutation):
|
||||||
return cls(success=True, school_class=school_class)
|
return cls(success=True, school_class=school_class)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateOnboardingProgress(graphene.Mutation):
|
||||||
|
success = graphene.Boolean()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mutate(cls, root, info, **kwargs):
|
||||||
|
user = info.context.user
|
||||||
|
if not user.onboarding_visited:
|
||||||
|
user.onboarding_visited = True
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
return cls(success=True)
|
||||||
|
|
||||||
|
|
||||||
class ProfileMutations:
|
class ProfileMutations:
|
||||||
update_password = UpdatePassword.Field()
|
update_password = UpdatePassword.Field()
|
||||||
update_avatar = UpdateAvatar.Field()
|
update_avatar = UpdateAvatar.Field()
|
||||||
|
|
@ -217,3 +230,4 @@ class ProfileMutations:
|
||||||
add_remove_member = AddRemoveMember.Field()
|
add_remove_member = AddRemoveMember.Field()
|
||||||
update_school_class = UpdateSchoolClass.Field()
|
update_school_class = UpdateSchoolClass.Field()
|
||||||
create_school_class = CreateSchoolClass.Field()
|
create_school_class = CreateSchoolClass.Field()
|
||||||
|
update_onboarding_progress = UpdateOnboardingProgress.Field()
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class UserNode(DjangoObjectType):
|
||||||
filter_fields = ['username', 'email']
|
filter_fields = ['username', 'email']
|
||||||
only_fields = ['username', 'email', 'first_name', 'last_name', 'school_classes', 'last_module',
|
only_fields = ['username', 'email', 'first_name', 'last_name', 'school_classes', 'last_module',
|
||||||
'last_topic', 'avatar_url',
|
'last_topic', 'avatar_url',
|
||||||
'selected_class', 'expiry_date']
|
'selected_class', 'expiry_date', 'onboarding_visited']
|
||||||
interfaces = (relay.Node,)
|
interfaces = (relay.Node,)
|
||||||
|
|
||||||
def resolve_pk(self, info, **kwargs):
|
def resolve_pk(self, info, **kwargs):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue