152 lines
5.0 KiB
Vue
152 lines
5.0 KiB
Vue
<template>
|
||
|
||
<div id="app" class="flex flex-col h-screen bg-gray-100">
|
||
<Toast/>
|
||
<!-- MenuBar всегда фиксирован сверху -->
|
||
<MenuBar v-if="userStore.user" class="w-full sticky hidden lg:block top-0 z-10"/>
|
||
<ToolBar class=" fixed visible lg:invisible bottom-0 z-10"/>
|
||
|
||
<!-- Контентная часть заполняет оставшееся пространство -->
|
||
<div class="flex flex-col flex-grow">
|
||
<!-- {{ tg_id }}-->
|
||
<Button label="Sub" :class="checkNotif ? 'flex' : '!hidden'" @click="checkSubscribe"/>
|
||
|
||
<router-view/>
|
||
<div class="bg-gray-100 h-12 block lg:hidden"></div>
|
||
</div>
|
||
|
||
<div id="footer" class="flex flex-col w-full h-fit bg-gray-200 p-4 gap-4">
|
||
<div class="flex flex-row items-center gap-6 ">
|
||
<div class="flex flex-row items-center gap-2 min-w-fit">
|
||
<img alt="logo" src="/apple-touch-icon.png" width="48" height="48"/>
|
||
<div class="flex flex-col items-start">
|
||
<p class="text-lg font-bold">Luminic Space</p>
|
||
<p>Ваше пространство</p>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="flex flex-row w-full gap-4">
|
||
<router-link to="/about" class="hover:underline">О проекте</router-link>
|
||
<router-link to="/spaces" class="hover:underline">Пространства</router-link>
|
||
<router-link to="/analytics" class="hover:underline">Аналитика</router-link>
|
||
<router-link to="/budgets" class="hover:underline">Бюджеты</router-link>
|
||
<router-link to="/transactions" class="hover:underline">Транзакции</router-link>
|
||
<router-link to="/settings" class="hover:underline">Настройки</router-link>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="flex flex-row justify-between">
|
||
<div>Ваши предложения можно направлять в <a href="https://t.me/voroninv" class="hover:underline text-blue-600">https://t.me/@voroninv</a>
|
||
</div>
|
||
<div>v0.0.2</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<TransactionForm v-if="visible" :visible="visible"
|
||
:transaction-type="drawerStore.transactionType ? drawerStore.transactionType : 'INSTANT'"
|
||
:category-type="drawerStore.categoryType ? drawerStore.categoryType : 'EXPENSE'"
|
||
:categoryId="drawerStore.categoryId" @close-drawer="closeDrawer"/>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import MenuBar from "./components/MenuBar.vue";
|
||
import ToolBar from "@/components/ToolBar.vue";
|
||
import Button from "primevue/button";
|
||
import {computed, onMounted, ref} from "vue";
|
||
import {subscribeUserToPush} from "@/services/pushManager";
|
||
import apiClient from '@/services/axiosSetup';
|
||
import {useUserStore} from "@/stores/userStore";
|
||
import {useDrawerStore} from '@/stores/drawerStore'
|
||
import TransactionForm from "@/components/transactions/TransactionForm.vue";
|
||
import {useSpaceStore} from "@/stores/spaceStore";
|
||
import Toast from "primevue/toast";
|
||
|
||
|
||
const drawerStore = useDrawerStore();
|
||
|
||
const visible = computed(() => drawerStore.visible);
|
||
const closeDrawer = () => {
|
||
drawerStore.setVisible(false);
|
||
};
|
||
|
||
const checkNotif = computed(() => {
|
||
|
||
return !tg_id.value && 'Notification' in window && Notification.permission === 'default'
|
||
})
|
||
|
||
const tg_id = computed(() => {
|
||
if (window.Telegram?.WebApp) {
|
||
const tg = window.Telegram.WebApp;
|
||
tg.expand(); // Разворачиваем приложение на весь экран
|
||
return tg.initDataUnsafe.user?.id ?? null; // Если tg_id нет, возвращаем null
|
||
}
|
||
return null;
|
||
});
|
||
|
||
const checkSubscribe = async () => {
|
||
if ("Notification" in window) {
|
||
if (Notification.permission === 'default') {
|
||
await Notification.requestPermission().then(sendSubscribe)
|
||
} else if (Notification.permission === 'granted') {
|
||
await sendSubscribe()
|
||
} else {
|
||
// Пользователь ранее отклонил запрос
|
||
}
|
||
} else {
|
||
|
||
// You may want to use an alternative method, like alerts or modals
|
||
}
|
||
}
|
||
|
||
const sendSubscribe = async () => {
|
||
try {
|
||
const subscription = await subscribeUserToPush();
|
||
// Отправка подписки на сервер для хранения
|
||
await apiClient.post("/subscriptions/subscribe", subscription)
|
||
} catch (error) {
|
||
console.error("Failed to subscribe to push:", error);
|
||
}
|
||
}
|
||
|
||
const token = ref(localStorage.getItem("token"));
|
||
|
||
const userStore = useUserStore();
|
||
const user = computed(() => userStore.user);
|
||
|
||
const spaceStore = useSpaceStore()
|
||
|
||
|
||
onMounted(async () => {
|
||
|
||
if (!userStore.user && localStorage.getItem("token")) {
|
||
|
||
await userStore.fetchUserProfile();
|
||
await checkSubscribe();
|
||
await spaceStore.fetchSpaces()
|
||
}
|
||
|
||
|
||
});
|
||
|
||
|
||
// @Options({
|
||
// components: {
|
||
// TransactionEditDrawer, SpeedDial,
|
||
// MenuBar,
|
||
// },
|
||
// })
|
||
// export default class App extends Vue {}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* Пример настройки высоты для поддержки flexbox */
|
||
#app {
|
||
min-height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
</style>
|