import {defineStore} from "pinia"; import {isNotEmpty} from "@/helpers.js"; import {storeOrder} from "@/utils/ftch.js"; import {useCartStore} from "@/stores/CartStore.js"; import {YA_METRIKA_GOAL} from "@/constants/yaMetrikaGoals.js"; import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js"; import {useSettingsStore} from "@/stores/SettingsStore.js"; import {usePulseStore} from "@/stores/Pulse.js"; import {TC_PULSE_EVENTS} from "@/constants/tPulseEvents.js"; import {nextTick} from "vue"; /** * Helper функция для получения haptic feedback (можно использовать в store) * @returns {object} Объект с методами haptic feedback */ function getHapticFeedback() { const settings = useSettingsStore(); const haptic = window.Telegram?.WebApp?.HapticFeedback; // Возвращаем обёртку с методами, которые проверяют настройку при каждом вызове return { impactOccurred: (style) => { const isHapticEnabled = settings.haptic_enabled !== false; if (!haptic || !isHapticEnabled || !haptic.impactOccurred) { return; } haptic.impactOccurred(style); }, selectionChanged: () => { const isHapticEnabled = settings.haptic_enabled !== false; if (!haptic || !isHapticEnabled || !haptic.selectionChanged) { return; } haptic.selectionChanged(); }, notificationOccurred: (type) => { const isHapticEnabled = settings.haptic_enabled !== false; if (!haptic || !isHapticEnabled || !haptic.notificationOccurred) { return; } haptic.notificationOccurred(type); }, }; } export const useCheckoutStore = defineStore('checkout', { state: () => ({ form: {}, order: null, isLoading: false, validationErrors: {}, errorMessage: '', }), getters: { hasError: (state) => { return (field) => isNotEmpty(state.validationErrors[field]); }, }, actions: { async makeOrder() { try { this.errorMessage = ''; this.isLoading = true; const data = window.Telegram.WebApp.initDataUnsafe; console.log("Allows write to PM: ", data.user.allows_write_to_pm); if (!data.user.allows_write_to_pm) { console.log("Sending request"); const granted = await new Promise(resolve => { window.Telegram.WebApp.requestWriteAccess((granted) => { resolve(granted); }); }); if (granted) { data.user.allows_write_to_pm = true; console.log('Пользователь разрешил отправку сообщений'); } else { alert('Вы не дали разрешение — бот не сможет отправлять вам уведомления'); } } const response = await storeOrder({ ...this.form, tgData: data, }); this.order = response.data; if (!this.order.id) { console.debug(response.data); throw new Error('Ошибка создания заказа.'); } const yaMetrika = useYaMetrikaStore(); const pulse = usePulseStore(); await nextTick(() => { pulse.ingest(TC_PULSE_EVENTS.ORDER_CREATED, { order_id: this.order.id, revenue: this.order?.final_total_numeric, currency: this.order?.currency, }); yaMetrika.reachGoal(YA_METRIKA_GOAL.ORDER_CREATED_SUCCESS, { price: this.order?.final_total_numeric, currency: this.order?.currency, }); yaMetrika.dataLayerPush({ "ecommerce": { "currencyCode": useSettingsStore().currency_code, "purchase": { "actionField": { "id": this.order.id, 'revenue': this.order?.final_total_numeric, }, "products": this.order.products ? this.order.products.map((product, index) => { return { id: product.product_id, name: product.name, price: product.total_numeric, position: index, quantity: product.quantity, }; }) : [], } } }); }); const haptic = getHapticFeedback(); await haptic.notificationOccurred('success'); await useCartStore().getProducts(); } catch (error) { if (error.response?.status === 422) { this.validationErrors = error.response._data.data; } else { console.error('Server error', error); } const haptic = getHapticFeedback(); haptic.notificationOccurred('error'); this.errorMessage = 'Возникла ошибка при создании заказа.'; throw error; } finally { this.isLoading = false; } }, clearError(field) { this.validationErrors[field] = null; }, }, });