119 lines
4.4 KiB
Vue
119 lines
4.4 KiB
Vue
<script setup>
|
||
import {ref, onMounted, nextTick, inject, computed, watch} from 'vue'
|
||
import { VOnboardingWrapper, VOnboardingStep } from 'v-onboarding'
|
||
import { useOnboardingStore } from '../../Stores/onboarding'
|
||
import { router } from '@inertiajs/vue3'
|
||
import { route } from 'ziggy-js'
|
||
import {NCard, NSpace, NButton, NTag} from 'naive-ui'
|
||
|
||
const wrapper = ref(null)
|
||
const store = useOnboardingStore()
|
||
const currentRoute = ref(route().current())
|
||
|
||
const currentSteps = computed(() => store.currentTourSteps)
|
||
|
||
onMounted(async () => {
|
||
if (store.isActive && store.activeStepIndex !== null) {
|
||
await nextTick()
|
||
wrapper.value?.goToStep(store.activeStepIndex)
|
||
}
|
||
})
|
||
|
||
// Следим за изменением индекса шага
|
||
watch(() => store.activeStepIndex, async (newIndex, oldIndex) => {
|
||
if (newIndex === null || !store.isActive) return
|
||
|
||
const steps = store.currentTourSteps
|
||
const step = steps[newIndex]
|
||
if (!step) return
|
||
|
||
const stepRoute = step.route
|
||
// Если шаг на другой странице — переходим
|
||
if (stepRoute && stepRoute !== currentRoute.value) {
|
||
// Переход на нужную страницу (индекс уже сохранён в сторе)
|
||
router.visit(route(stepRoute))
|
||
// Не возвращаем false, просто делаем переход
|
||
// После перехода onMounted восстановит шаг
|
||
} else {
|
||
wrapper.value?.goToStep(store.activeStepIndex)
|
||
}
|
||
}, { immediate: true }) // immediate, чтобы сработало при первом запуске
|
||
|
||
// Обработчик кнопки "Далее" в обычных шагах
|
||
const handleNext = (next, exit, isLast) => {
|
||
if (isLast) {
|
||
exit()
|
||
store.finish()
|
||
} else {
|
||
// Вызываем next() – это переключит шаг внутри библиотеки,
|
||
// но нам также нужно обновить store.activeStepIndex, чтобы watch сработал
|
||
const nextIndex = store.activeStepIndex + 1
|
||
store.setStep(nextIndex) // обновляем стор
|
||
next() // говорим библиотеке переключиться
|
||
}
|
||
}
|
||
// Обработчик кнопки "Назад" в обычных шагах
|
||
const handlePrevious = (previous, exit, isFirst) => {
|
||
if (isFirst) {
|
||
|
||
} else {
|
||
// Вызываем next() – это переключит шаг внутри библиотеки,
|
||
// но нам также нужно обновить store.activeStepIndex, чтобы watch сработал
|
||
const nextIndex = store.activeStepIndex - 1
|
||
store.setStep(nextIndex) // обновляем стор
|
||
previous() // говорим библиотеке переключиться
|
||
}
|
||
}
|
||
|
||
const onFinish = () => {
|
||
store.finish()
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<VOnboardingWrapper
|
||
ref="wrapper"
|
||
:steps="currentSteps"
|
||
@finish="onFinish"
|
||
>
|
||
<template #default="{ step, next, previous, exit, isFirst, isLast }">
|
||
<VOnboardingStep>
|
||
<NCard
|
||
style="max-width: 320px;"
|
||
:title="step.content.title"
|
||
class="rounded-lg! mt-1"
|
||
size="small"
|
||
>
|
||
<p>{{ step.content.description }}</p>
|
||
<template #footer>
|
||
<NSpace justify="end">
|
||
<NButton
|
||
v-if="!isFirst"
|
||
size="small"
|
||
@click="handlePrevious(previous, exit, isFirst)"
|
||
>
|
||
Назад
|
||
</NButton>
|
||
<NButton
|
||
type="primary"
|
||
size="small"
|
||
:disabled="step.manual"
|
||
@click="handleNext(next, exit, isLast)"
|
||
>
|
||
{{ isLast ? 'Завершить' : 'Далее' }}
|
||
</NButton>
|
||
</NSpace>
|
||
</template>
|
||
</NCard>
|
||
</VOnboardingStep>
|
||
</template>
|
||
</VOnboardingWrapper>
|
||
</template>
|
||
|
||
<style>
|
||
:root {
|
||
--v-onboarding-overlay-z: 9999;
|
||
--v-onboarding-step-z: 9999;
|
||
}
|
||
</style>
|