Skip to content

Commit

Permalink
feat(): Onboarding Checklist
Browse files Browse the repository at this point in the history
  • Loading branch information
cbernard authored and ManuBernard committed Jul 25, 2022
1 parent 637f0af commit 0f061d7
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/components/TimelineOnboarding.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { useI18n } from '@/composables/useI18n';
import { useOnboardingChecklist } from '@/composables/useOnboardingChecklist';
import { lsSet, lsGet } from '@/helpers/utils';
const { t } = useI18n();
const { onboardingChecklist } = useOnboardingChecklist();
const showOnboarding = ref(true);
const checkListCompleted = computed(() => {
let completed = true;
onboardingChecklist.value.forEach(checkListItem => {
if (!checkListItem.checked) {
completed = false;
return;
}
});
return completed;
});
if (lsGet('timelineOnboarding') == 'hidden') {
showOnboarding.value = false;
}
watch(checkListCompleted, completed => {
if (completed) lsSet('timelineOnboarding', 'hidden');
});
function closeOnboarding() {
lsSet('timelineOnboarding', 'hidden');
showOnboarding.value = false;
}
</script>

<template>
<transition name="fade">
<div
v-if="showOnboarding"
class="border-skin-border bg-skin-block-bg text-white md:rounded-lg md:border"
>
<div class="p-4">
<div class="flex">
<div class="flex-grow">
<h3 class="text-bold">{{ t('onboarding.title') }}</h3>
<p>{{ t('onboarding.subtitle') }}</p>
</div>
<div class="mt-2">
<button
class="opacity-50 transition-opacity hover:opacity-100"
:aria-label="t('onboarding.close')"
@click="closeOnboarding"
>
<svg class="h-[24px] w-[24px]" fill="none" viewBox="0 0 12 12">
<path
d="M4 8l2-2m0 0l2-2M6 6L4 4m2 2l2 2"
stroke="currentColor"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
</div>

<ul class="mt-4 flex-col space-y-2">
<li
v-for="checkListItem in onboardingChecklist"
:key="checkListItem.name"
class="flex items-center"
>
<div class="w-4">
<i-ho-check
v-if="checkListItem.checked"
class="text-[17px] text-green"
/>
<div v-else class="h-3 w-3 border"></div>
</div>
{{ checkListItem.name }}
</li>
</ul>
<transition name="fade">
<div v-if="checkListCompleted" class="mt-4">
<h3>🎉 {{ t('onboarding.congratulations') }}</h3>
</div>
</transition>
</div>
</div>
</transition>
</template>
85 changes: 85 additions & 0 deletions src/composables/useOnboardingChecklist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { computed, ref, watch } from 'vue';
import { useProfiles } from '@/composables/useProfiles';
import { useWeb3 } from '@/composables/useWeb3';
import { useI18n } from '@/composables/useI18n';
import { useApolloQuery } from '@/composables/useApolloQuery';
import { PROPOSALS_QUERY } from '@/helpers/queries';
import { ACTIVITY_VOTES_QUERY } from '@/helpers/queries';
import { useFollowSpace } from '@/composables/useFollowSpace';

const { t } = useI18n();

const { apolloQuery } = useApolloQuery();
const { profiles } = useProfiles();
const { web3Account } = useWeb3();
const { followingSpaces } = useFollowSpace();

const profile = computed(() => profiles.value[web3Account.value]);

const hasSetPublicProfile = computed(() =>
profile.value?.name ? true : false
);
const hasFollowedSpace = computed(() => followingSpaces.value.length);
const hasVoted = ref(false);
const hasCreatedProposal = ref(false);

const onboardingChecklist = ref([
{
checked: hasSetPublicProfile,
name: t('onboarding.profile')
},
{
checked: hasFollowedSpace,
name: t('onboarding.space')
},
{
checked: hasVoted,
name: t('onboarding.vote')
},
{
checked: hasCreatedProposal,
name: t('onboarding.proposal')
}
]);

async function loadVotes() {
const votes = await apolloQuery(
{
query: ACTIVITY_VOTES_QUERY,
variables: {
voter: profile.value.id
}
},
'votes'
);

hasVoted.value = votes.length ? true : false;
}

async function loadProposals() {
const proposals = await apolloQuery(
{
query: PROPOSALS_QUERY,
variables: {
first: 1,
skip: 0,
state: 'all',
author_in: [profile.value.id]
}
},
'proposals'
);

hasCreatedProposal.value = proposals.length ? true : false;
}

watch(profiles, p => {
if (profile.value) {
loadVotes();
loadProposals();
}
});

export function useOnboardingChecklist() {
return { onboardingChecklist };
}
10 changes: 10 additions & 0 deletions src/locales/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -612,5 +612,15 @@
"empty": "There are no assets in this contract"
},
"24hChange": "24h change"
},
"onboarding": {
"title": "New to Snapshot?",
"subtitle": "Here is a quick check list to get started:",
"close": "Hide onboarding cheklist",
"profile": "Set your public profile",
"space": "Join your favorite space",
"vote": "Cast your first vote",
"proposal": "Create a proposal",
"congratulations": "Congratulations"
}
}
10 changes: 10 additions & 0 deletions src/locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -602,5 +602,15 @@
"empty": "There are no assets in this contract"
},
"24hChange": "24h change"
},
"onboarding": {
"title": "Nouveau sur Snapshot ?",
"subtitle": "Voici une checklist rapide pour commencer :",
"close": "Cacher la checklist",
"profile": "Définir votre profil public",
"space": "Rejoindre votre espace préféré",
"vote": "Votre premier vote",
"proposal": "Créer une proposition",
"congratulations": "Félicitations"
}
}
3 changes: 3 additions & 0 deletions src/views/TimelineView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ function selectState(e) {
</template>
</BaseDropdown>
</div>
<TimelineOnboarding class="mb-4" />
<div class="border-skin-border bg-skin-block-bg md:rounded-lg md:border">
<LoadingRow
v-if="
Expand Down

0 comments on commit 0f061d7

Please sign in to comment.