36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
/**
|
||
* Запуск экскурсии по ссылке из чата бота: /?tour=<имя> (спека ИИ-бота §4).
|
||
* Невошедшего роутер сам отправит на /login с redirect=fullPath — query
|
||
* переживает вход (router/index.ts beforeEach), поэтому отдельной логики
|
||
* логина здесь нет. Мусорное имя — молча чистим query (не пугаем клиента).
|
||
*/
|
||
import { ref, type Ref } from 'vue';
|
||
import type { Router } from 'vue-router';
|
||
import { findTour, type TourScenario } from '../tours/catalog';
|
||
|
||
interface RouteLike {
|
||
query: Record<string, unknown>;
|
||
}
|
||
|
||
export function useTourLauncher(route: Ref<RouteLike>, router: Router) {
|
||
const activeTour = ref<TourScenario | null>(null);
|
||
|
||
async function checkQuery(): Promise<void> {
|
||
const name = typeof route.value.query.tour === 'string' ? route.value.query.tour : '';
|
||
if (name === '') return;
|
||
const tour = findTour(name);
|
||
if (tour === null) {
|
||
await router.replace({ query: { ...route.value.query, tour: undefined } });
|
||
return;
|
||
}
|
||
activeTour.value = tour;
|
||
await router.push({ path: tour.steps[0].route, query: {} });
|
||
}
|
||
|
||
function finishTour(): void {
|
||
activeTour.value = null;
|
||
}
|
||
|
||
return { activeTour, checkQuery, finishTour };
|
||
}
|