Squashed commit message
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
This commit is contained in:
157
frontend/spa/src/stores/CheckoutStore.js
Normal file
157
frontend/spa/src/stores/CheckoutStore.js
Normal file
@@ -0,0 +1,157 @@
|
||||
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;
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user