Files
interview-demo-code/frontend/admin/src/App.vue
Nikita Kiselev 87eb66f06b
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
WIP
2026-03-11 21:52:01 +03:00

188 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>