Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
188 lines
5.8 KiB
Vue
188 lines
5.8 KiB
Vue
<template>
|
||
<div v-if="! settings.error" class="tw:relative">
|
||
<TopLead/>
|
||
<ul class="nav nav-tabs">
|
||
<li :class="{active: route.name === 'general'}">
|
||
<RouterLink :to="{name: 'general'}">
|
||
<i class="fa fa-cog"></i> Общие
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'telegram'}">
|
||
<RouterLink :to="{name: 'telegram'}">
|
||
<i class="fa fa-paper-plane"></i> Telegram
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'metrics'}">
|
||
<RouterLink :to="{name: 'metrics'}">
|
||
<i class="fa fa-line-chart"></i> Метрика
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'store'}">
|
||
<RouterLink :to="{name: 'store'}">
|
||
<i class="fa fa-shopping-bag"></i> Витрина
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'texts'}">
|
||
<RouterLink :to="{name: 'texts'}">
|
||
<i class="fa fa-file-text"></i> Тексты
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'orders'}">
|
||
<RouterLink :to="{name: 'orders'}">
|
||
<i class="fa fa-shopping-cart"></i> Заказы
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'mainpage'}">
|
||
<RouterLink :to="{name: 'mainpage'}">
|
||
<i class="fa fa-home"></i> Главная страница
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'formbuilder'}">
|
||
<RouterLink :to="{name: 'formbuilder'}">
|
||
<i class="fa fa-wpforms"></i> Форма заказа
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'customers'}">
|
||
<RouterLink :to="{name: 'customers'}">
|
||
<i class="fa fa-users"></i> Покупатели
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'pulse'}">
|
||
<RouterLink :to="{name: 'pulse'}">
|
||
<i class="fa fa-heartbeat pulse-icon tw:text-red-200"></i> MegaPay Pulse <span class="pulse-beta-label tw:ml-1 tw:px-1.5 tw:py-0.5 tw:text-xs tw:font-semibold tw:text-white tw:rounded">BETA</span>
|
||
</RouterLink>
|
||
</li>
|
||
|
||
<li :class="{active: route.name === 'cron'}">
|
||
<RouterLink :to="{name: 'cron'}">
|
||
<i class="fa fa-clock-o"></i> CRON
|
||
</RouterLink>
|
||
</li>
|
||
</ul>
|
||
|
||
<section class="form-horizontal tab-content">
|
||
<RouterView/>
|
||
</section>
|
||
|
||
<section>
|
||
<Divider/>
|
||
<div class="tw:flex tw:items-center tw:justify-start tw:gap-4">
|
||
<Button
|
||
label="Сохранить настройки"
|
||
:disabled="!settings.hasUnsavedChanges"
|
||
v-tooltip.top="settings.hasUnsavedChanges ? 'Сохранить изменения' : 'Нет изменений для сохранения'"
|
||
@click="settings.saveSettings"
|
||
/>
|
||
<div v-if="settings.hasUnsavedChanges"
|
||
class="tw:flex tw:items-center tw:gap-2 tw:text-red-600">
|
||
<i class="fa fa-exclamation-triangle"></i>
|
||
<span class="tw:text-sm">Есть несохранённые изменения</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<div v-if="settings.isLoading"
|
||
class="tw:w-full tw:h-full tw:absolute tw:top-0 tw:left-0 tw:z-30 tw:backdrop-blur-sm">
|
||
<div
|
||
class="tw:fixed tw:top-0 tw:left-0 tw:w-full tw:h-full tw:flex tw:justify-center tw:items-center tw:z-40 tw:text-4xl">
|
||
<i class="fa fa-spin fa-spinner tw:mr-5"></i>
|
||
<div>Загрузка...</div>
|
||
</div>
|
||
</div>
|
||
<Toast position="top-right"/>
|
||
<ConfirmDialog/>
|
||
<ConfirmPopup group="popup"/>
|
||
</div>
|
||
|
||
<div v-else
|
||
class="tw:w-full tw:h-full tw:absolute tw:top-0 tw:left-0 tw:z-30 tw:backdrop-blur-sm">
|
||
<div
|
||
class="tw:fixed tw:top-0 tw:left-0 tw:w-full tw:h-full tw:flex tw:flex-col tw:justify-center tw:items-center tw:z-40">
|
||
<i class="fa fa-ban tw:text-4xl"></i>
|
||
<div class="tw:text-4xl">{{ settings.error }}</div>
|
||
<div>Обратитесь в поддержку</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {RouterView, useRoute} from 'vue-router';
|
||
import {useSettingsStore} from "@/stores/settings.js";
|
||
import Toast from 'primevue/toast';
|
||
import {toastBus} from '@/utils/toastHelper';
|
||
import {useToast} from "primevue";
|
||
import Button from 'primevue/button';
|
||
import TopLead from "@/components/TopLead.vue";
|
||
import Divider from 'primevue/divider';
|
||
import ConfirmDialog from 'primevue/confirmdialog';
|
||
import ConfirmPopup from 'primevue/confirmpopup';
|
||
import {onBeforeUnmount, onMounted} from "vue";
|
||
|
||
const route = useRoute();
|
||
const settings = useSettingsStore();
|
||
const toast = useToast();
|
||
toastBus.on('show', (data) => toast.add(data));
|
||
|
||
// Защита от обновления страницы или закрытия вкладки
|
||
function handleBeforeUnload(event) {
|
||
if (settings.hasUnsavedChanges) {
|
||
event.preventDefault();
|
||
event.returnValue = 'У вас есть несохранённые изменения. Вы уверены, что хотите покинуть страницу?';
|
||
return event.returnValue;
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
window.addEventListener('beforeunload', handleBeforeUnload);
|
||
});
|
||
|
||
onBeforeUnmount(() => {
|
||
window.removeEventListener('beforeunload', handleBeforeUnload);
|
||
});
|
||
</script>
|
||
|
||
|
||
<style scoped>
|
||
@keyframes heartbeat {
|
||
0%, 100% {
|
||
transform: scale(1);
|
||
}
|
||
10%, 30% {
|
||
transform: scale(1.1);
|
||
}
|
||
20%, 40% {
|
||
transform: scale(1);
|
||
}
|
||
50% {
|
||
transform: scale(1.15);
|
||
}
|
||
}
|
||
|
||
.pulse-icon {
|
||
animation: heartbeat 1.5s ease-in-out infinite;
|
||
display: inline-block;
|
||
}
|
||
|
||
.nav-tabs li.active .pulse-icon {
|
||
color: #ef4444; /* red-500 */
|
||
}
|
||
|
||
.pulse-beta-label {
|
||
background-color: #fdba74; /* orange-300 - тусклый */
|
||
transition: background-color 0.2s ease;
|
||
}
|
||
|
||
.nav-tabs li.active .pulse-beta-label {
|
||
background-color: #f97316; /* orange-500 - яркий */
|
||
}
|
||
</style>
|