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
239 lines
9.8 KiB
Vue
239 lines
9.8 KiB
Vue
<template>
|
||
<BaseViewWrapper>
|
||
<div class="account-page">
|
||
<!-- Профиль пользователя -->
|
||
<div class="card card-border bg-base-100 mb-4">
|
||
<div class="card-body">
|
||
<div class="flex items-center gap-4">
|
||
<div class="avatar">
|
||
<div v-if="tgData?.user?.photo_url" class="w-16 h-16 rounded-full">
|
||
<img :src="tgData?.user?.photo_url" alt="avatar"/>
|
||
</div>
|
||
<div v-else class="bg-primary text-primary-content w-16 h-16 rounded-full flex items-center justify-center">
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-8">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<div class="flex-1">
|
||
<h2 class="text-xl font-bold">
|
||
{{ username }}
|
||
</h2>
|
||
<p v-if="tgData?.user?.username" class="text-sm text-base-content/70">
|
||
@{{ tgData.user.username }}
|
||
</p>
|
||
<p v-if="daysWithUs !== null" class="text-sm text-base-content/40">
|
||
Вы с нами {{ daysWithUs }} {{ daysWord }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Список пунктов меню -->
|
||
<div class="menu bg-base-100 rounded-box card card-border w-full mb-4">
|
||
<li class="w-full">
|
||
<a @click="openManagerChat" class="flex items-center gap-3 w-full">
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 8.07 8.07 0 0 0-1.603-.093C9.5 7.5 8.25 8.25 8.25 9.75v4.286c0 .597.237 1.17.659 1.591l3.682 3.682a2.25 2.25 0 0 0 1.591.659h4.286c.597 0 1.17-.237 1.591-.659l3.682-3.682a2.25 2.25 0 0 0 .659-1.591V10.608c0-1.136-.847-2.1-1.98-2.193a48.138 48.138 0 0 0-1.02-.072Z" />
|
||
</svg>
|
||
<span>Связаться с нами</span>
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5 ml-auto">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
</div>
|
||
|
||
<!-- Кнопка добавления на главный экран -->
|
||
<div v-if="isHomeScreenSupported" class="card card-border bg-base-100">
|
||
<div class="card-body p-4">
|
||
<button
|
||
v-if="!isHomeScreenAdded"
|
||
@click="addToHomeScreen"
|
||
class="btn btn-outline w-full justify-center gap-3 mb-2"
|
||
>
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 16.875h3.375m0 0h3.375m-3.375 0V13.5m0 3.375v3.375M6 10.5h2.25a2.25 2.25 0 0 0 2.25-2.25V6a2.25 2.25 0 0 0-2.25-2.25H6A2.25 2.25 0 0 0 3.75 6v2.25A2.25 2.25 0 0 0 6 10.5Zm0 9.75h2.25A2.25 2.25 0 0 0 10.5 18v-2.25a2.25 2.25 0 0 0-2.25-2.25H6a2.25 2.25 0 0 0-2.25 2.25V18A2.25 2.25 0 0 0 6 20.25Zm9.75-9.75H18a2.25 2.25 0 0 0 2.25-2.25V6A2.25 2.25 0 0 0 18 3.75h-2.25A2.25 2.25 0 0 0 13.5 6v2.25a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||
</svg>
|
||
<span>Добавить на главный экран</span>
|
||
</button>
|
||
<div v-else class="flex items-center justify-center gap-3 mb-2 p-3 bg-success/10 rounded-lg">
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6 text-success">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||
</svg>
|
||
<span class="text-success font-medium">Приложение уже добавлено на главный экран</span>
|
||
</div>
|
||
<p v-if="!isHomeScreenAdded" class="text-xs text-base-content/50 text-center">
|
||
Добавьте приложение на главный экран для быстрого доступа
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</BaseViewWrapper>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {computed, ref} from "vue";
|
||
import {useTgData} from "@/composables/useTgData.js";
|
||
import {useSettingsStore} from "@/stores/SettingsStore.js";
|
||
import BaseViewWrapper from "@/views/BaseViewWrapper.vue";
|
||
import {onMounted, onUnmounted} from "vue";
|
||
import {useRoute} from "vue-router";
|
||
import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js";
|
||
import {usePulseStore} from "@/stores/Pulse.js";
|
||
import {useHapticFeedback} from "@/composables/useHapticFeedback.js";
|
||
|
||
defineOptions({
|
||
name: 'Account'
|
||
});
|
||
|
||
const tgData = useTgData();
|
||
const settings = useSettingsStore();
|
||
const route = useRoute();
|
||
const yaMetrika = useYaMetrikaStore();
|
||
const pulse = usePulseStore();
|
||
const haptic = useHapticFeedback();
|
||
|
||
const username = computed(() => {
|
||
if (tgData?.user?.first_name || tgData?.user?.last_name) {
|
||
const parts = [tgData.user.first_name, tgData.user.last_name].filter(Boolean);
|
||
return parts.join(' ') || 'Пользователь';
|
||
}
|
||
return tgData?.user?.username ? `@${tgData.user.username}` : 'Пользователь';
|
||
});
|
||
|
||
const isHomeScreenSupported = ref(false);
|
||
const isHomeScreenAdded = ref(false);
|
||
const daysWithUs = ref(null);
|
||
|
||
// Функция для склонения слова "день" по правилам русского языка
|
||
function getDaysWord(days) {
|
||
const lastDigit = days % 10;
|
||
const lastTwoDigits = days % 100;
|
||
|
||
// Исключения для 11-14
|
||
if (lastTwoDigits >= 11 && lastTwoDigits <= 14) {
|
||
return 'дней';
|
||
}
|
||
|
||
// Склонение по последней цифре
|
||
if (lastDigit === 1) {
|
||
return 'день';
|
||
} else if (lastDigit >= 2 && lastDigit <= 4) {
|
||
return 'дня';
|
||
} else {
|
||
return 'дней';
|
||
}
|
||
}
|
||
|
||
const daysWord = computed(() => {
|
||
if (daysWithUs.value === null) return '';
|
||
return getDaysWord(daysWithUs.value);
|
||
});
|
||
|
||
function openManagerChat() {
|
||
if (!settings.manager_username) {
|
||
window.Telegram.WebApp.showAlert('Менеджер недоступен');
|
||
return;
|
||
}
|
||
|
||
haptic.selectionChanged();
|
||
|
||
// Формируем ссылку для открытия чата с менеджером
|
||
const managerUsername = String(settings.manager_username).trim();
|
||
const username = managerUsername.startsWith('@')
|
||
? managerUsername.substring(1)
|
||
: managerUsername;
|
||
|
||
const chatUrl = `https://t.me/${username}`;
|
||
window.Telegram.WebApp.openTelegramLink(chatUrl);
|
||
}
|
||
|
||
function handleHomeScreenAdded() {
|
||
haptic.notificationOccurred('success');
|
||
window.Telegram.WebApp.showAlert('Приложение успешно добавлено на главный экран!');
|
||
isHomeScreenAdded.value = true;
|
||
}
|
||
|
||
function checkHomeScreenSupport() {
|
||
if (window.Telegram?.WebApp?.checkHomeScreenStatus) {
|
||
window.Telegram.WebApp.checkHomeScreenStatus((status) => {
|
||
isHomeScreenSupported.value = status !== 'unsupported';
|
||
if (status === 'added') {
|
||
isHomeScreenAdded.value = true;
|
||
}
|
||
});
|
||
} else if (window.Telegram?.WebApp?.addToHomeScreen) {
|
||
// Если есть метод addToHomeScreen, значит функция поддерживается
|
||
isHomeScreenSupported.value = true;
|
||
}
|
||
}
|
||
|
||
function addToHomeScreen() {
|
||
haptic.selectionChanged();
|
||
|
||
// Используем Telegram Web App API для добавления на главный экран
|
||
if (window.Telegram?.WebApp?.addToHomeScreen) {
|
||
window.Telegram.WebApp.addToHomeScreen();
|
||
} else {
|
||
// Fallback для старых версий или если метод недоступен
|
||
window.Telegram.WebApp.showAlert('Функция добавления на главный экран недоступна в вашей версии Telegram.');
|
||
}
|
||
}
|
||
|
||
function calculateDaysWithUs() {
|
||
const createdAt = pulse.customer_created_at;
|
||
|
||
if (createdAt) {
|
||
const createdDate = new Date(createdAt);
|
||
const now = new Date();
|
||
const diffTime = now - createdDate;
|
||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||
// Если 0 дней, показываем 1 день
|
||
daysWithUs.value = diffDays === 0 ? 1 : diffDays;
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
window.document.title = 'Профиль';
|
||
yaMetrika.pushHit(route.path, {
|
||
title: 'Профиль',
|
||
});
|
||
|
||
// Вычисляем количество дней с момента первого визита
|
||
calculateDaysWithUs();
|
||
|
||
// Проверяем поддержку функции добавления на главный экран
|
||
checkHomeScreenSupport();
|
||
|
||
// Регистрируем обработчик события успешного добавления на главный экран
|
||
if (window.Telegram?.WebApp?.onEvent) {
|
||
window.Telegram.WebApp.onEvent('homeScreenAdded', handleHomeScreenAdded);
|
||
}
|
||
});
|
||
|
||
onUnmounted(() => {
|
||
// Удаляем обработчик события при размонтировании компонента
|
||
if (window.Telegram?.WebApp?.offEvent) {
|
||
window.Telegram.WebApp.offEvent('homeScreenAdded', handleHomeScreenAdded);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
.account-page {
|
||
padding-bottom: 1rem;
|
||
}
|
||
|
||
.menu li > a {
|
||
padding: 1rem;
|
||
width: 100%;
|
||
}
|
||
|
||
.menu li > a:active {
|
||
background-color: hsl(var(--b2));
|
||
}
|
||
</style>
|
||
|