Files
app-v2/src/App.vue
2025-10-27 22:02:29 +03:00

143 lines
4.1 KiB
Vue

<script setup lang="ts">
import SpaceList from "@/components/space-list/SpaceList.vue";
import Toolbar from "@/components/Toolbar.vue";
import { useSpaceStore } from "@/stores/spaceStore";
import { useToolbarStore } from "@/stores/toolbar-store";
import router from "@/router";
import { useRoute, onBeforeRouteUpdate } from "vue-router";
import { computed, onMounted, onBeforeUnmount, ref, watch } from "vue";
const spaceStore = useSpaceStore();
const toolbarStore = useToolbarStore();
const route = useRoute();
const platform = ref<string>("unknown")
const tgApp = (window as any)?.Telegram?.WebApp;
const isTelegram = computed(() => !!tgApp);
const isSpaceSelectorVisible = ref(false);
const isSpaceSelected = computed(
() => spaceStore.selectedSpaceId === undefined || isSpaceSelectorVisible.value
);
const menu = [
{ name: "Dashboard", icon: "pi pi-chart-bar", link: "/" },
{ name: "Transactions", icon: "pi pi-cog", link: "/transactions" },
{ name: "Settings", icon: "pi pi-list", link: "/settings" },
];
function spaceSelected() {
router.push("/");
isSpaceSelectorVisible.value = false;
}
let backHandler: (() => void) | null = null;
function setupBackButton() {
if (!tgApp) return;
if (route.path !== "/") {
tgApp.BackButton.show();
// снять старый обработчик
if (backHandler) tgApp.BackButton.offClick(backHandler);
// навесить новый
backHandler = () => {
if (window.history.length > 1) {
router.back();
} else {
tgApp.BackButton.hide();
}
};
tgApp.BackButton.onClick(backHandler);
} else {
tgApp.BackButton.hide();
}
}
onMounted(() => {
toolbarStore.registerHandler("openSpacePicker", () => {
isSpaceSelectorVisible.value = true;
});
if (tgApp) {
try {
tgApp.expand?.();
platform.value = tgApp.platform
if (['ios', 'android'].includes(platform.value)) {
tgApp.requestFullscreen?.();
}
tgApp.lockOrientation?.();
tgApp.disableVerticalSwipes()
tgApp.ready();
setupBackButton();
} catch (err) {
console.warn("Telegram WebApp init error:", err);
}
}
});
// 🔁 следим за изменением маршрута
watch(
() => route.path,
() => setupBackButton()
);
onBeforeUnmount(() => {
toolbarStore.unregisterHandler("openSpacePicker");
tgApp?.BackButton?.hide();
if (backHandler) tgApp?.BackButton?.offClick(backHandler);
});
</script>
<template>
<!-- {{platform}}-->
<!-- {{['ios', 'android'].includes(platform) }}-->
<div class="flex flex-col tg " :class="['ios', 'android'].includes(platform) ? '!pt-10' : '!pt-1'">
<SpaceList v-if="isSpaceSelected" @space-selected="spaceSelected" />
<div v-else class="flex flex-col w-full gap-4">
<div class="w-full flex flex-row items-end justify-end pt-4 pe-4">
<Toolbar />
</div>
<div class="flex flex-col w-full h-full items-end px-4 gap-4">
<router-view class="w-full pb-4" />
</div>
<nav
class="fixed inset-x-0 bottom-4 z-50 w-full flex justify-center items-center"
style="padding-bottom: var(--tg-content-safe-area-inset-bottom) !important;"
>
<div class="flex h-full items-center justify-between py-2 bg-white rounded-4xl px-6 w-fit">
<!-- <div class="flex h-full justify-items-center items-center justify-between py-2 bg-white rounded-4xl !px-6 w-fit">-->
<router-link
v-for="item in menu"
:key="item.link"
:to="item.link"
class="flex w-fit h-full flex-col items-center gap-2 !py-2 !px-4"
:class="route.path == item.link ? 'bg-green-100 rounded-2xl ' : ''"
>
<i class="!text-lg" :class="item.icon" />
<span class="font-medium text-gray-900">{{ item.name }}</span>
</router-link>
</div>
</nav>
<div class="h-16" />
</div>
</div>
</template>
<style scoped>
.tg {
width: 100% !important;
margin:
var(--tg-content-safe-area-inset-top)
var(--tg-content-safe-area-inset-right)
0
var(--tg-content-safe-area-inset-left) !important;
}
</style>