feat: add onboarding tutorial for new users
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 3m4s
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 3m4s
- Introduced a modular tutorial layer to guide new parents through the app setup process. - Implemented a 3-step forced intro after first sign-in (PIN setup → child creation → chore creation). - Added just-in-time contextual hints for various features as users encounter them. - Persisted user progress on the backend with new fields in the User model. - Created a new tutorial controller and step registry in the frontend for managing tutorial states. - Added Help button for easy access to tutorial tips and a restart option in the user profile. - Ensured accessibility and mobile responsiveness for the tutorial overlay. - Included tests for backend and frontend functionalities related to the tutorial.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
import { ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import EntityEditForm from '../shared/EntityEditForm.vue'
|
||||
import { maybeShow as tutorialMaybeShow } from '@/tutorial/controller'
|
||||
import '@/assets/styles.css'
|
||||
|
||||
const props = defineProps<{ id?: string }>()
|
||||
@@ -46,6 +47,7 @@ const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
onMounted(async () => {
|
||||
if (!isEdit.value) tutorialMaybeShow('edit-reward-name')
|
||||
if (isEdit.value && props.id) {
|
||||
loading.value = true
|
||||
try {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import ItemList from '../shared/ItemList.vue'
|
||||
import MessageBlock from '@/components/shared/MessageBlock.vue'
|
||||
@@ -47,11 +47,6 @@ import type { Reward } from '@/common/models'
|
||||
import { REWARD_FIELDS } from '@/common/models'
|
||||
|
||||
import { eventBus } from '@/common/eventBus'
|
||||
import {
|
||||
maybeShow as tutorialMaybeShow,
|
||||
markStepSeen as tutorialMark,
|
||||
tutorialReady,
|
||||
} from '@/tutorial/controller'
|
||||
|
||||
const $router = useRouter()
|
||||
|
||||
@@ -67,15 +62,6 @@ function handleRewardModified(event: any) {
|
||||
}
|
||||
}
|
||||
|
||||
watch([rewardCountRef, tutorialReady], ([count, ready]) => {
|
||||
if (!ready) return
|
||||
if (count === 0) {
|
||||
tutorialMaybeShow('create-reward', () => document.querySelector('.fab') as HTMLElement | null)
|
||||
} else if (typeof count === 'number' && count > 0) {
|
||||
void tutorialMark('has-created-reward')
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
eventBus.on('reward_modified', handleRewardModified)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user