UNPKG

@bzbs/react-providers

Version:

A collection of React Context Provider for Buzzebees apps

1,584 lines (1,565 loc) 113 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // zustand.ts var zustand_exports = {}; __export(zustand_exports, { EN: () => EN, TH: () => TH, addBlake2OtpSignatureInterceptor: () => addBlake2OtpSignatureInterceptor, addDefaultHeaderInterceptor: () => addDefaultHeaderInterceptor, analytics: () => analytics, avatarUrl: () => avatarUrl, campaignInterfaceType: () => campaignInterfaceType, campaignPointType: () => campaignPointType, campaignType: () => campaignType, createCampaignDetailStore: () => createCampaignDetailStore, createCampaignsStore: () => createCampaignsStore, createCartUrl: () => createCartUrl, createCategoriesStore: () => createCategoriesStore, createDashboardStore: () => createDashboardStore, createInterfaceToken: () => createInterfaceToken, createPointLogStore: () => createPointLogStore, createPurchaseStore: () => createPurchaseStore, eventEmitter: () => eventEmitter, fetchImage: () => fetchImage, findBestLocaleFromString: () => findBestLocaleFromString, generateBlake2bSignatureHex: () => generateBlake2bSignatureHex, generateShortLivedId: () => generateShortLivedId, getOtpSignatureHeaders: () => getOtpSignatureHeaders, getPurchaseItemStatus: () => getPurchaseItemStatus, initializeAnalytics: () => initializeAnalytics, interfaceWebsite: () => createInterfaceWebsiteUrl, isValidEmail: () => isValidEmail, largeImage: () => largeImage, localeToLCIDMap: () => localeToLCIDMap, trackCommonEvents: () => trackCommonEvents, useAddressStore: () => useAddressStore, useAlertStore: () => useAlertStore, useAnalytics: () => useAnalytics, useAnalyticsState: () => useAnalyticsState, useAnalyticsStore: () => useAnalyticsStore, useAuthStore: () => useAuthStore, useBuzzebeesAppStore: () => useBuzzebeesAppStore, useCartStore: () => useCartStore, useConfirmStore: () => useConfirmStore, useConsentStore: () => useConsentStore, useCouponStore: () => useCouponStore, useLoading: () => useLoading, useLoadingIndicatorStore: () => useLoadingIndicatorStore, useLocaleStore: () => useLocaleStore, useMaintenanceStore: () => useMaintenanceStore, useNotificationStore: () => useNotificationStore, usePageTracking: () => usePageTracking, usePopupStore: () => usePopupStore, useRegistrationStore: () => useRegistrationStore, useUserStore: () => useUserStore, useZipcodeStore: () => useZipcodeStore, withPageTracking: () => withPageTracking }); module.exports = __toCommonJS(zustand_exports); // src/stores/address.store.ts var import_zustand2 = require("zustand"); // src/stores/buzzebeess-app.store.ts var import_zustand = require("zustand"); var useBuzzebeesAppStore = (0, import_zustand.create)((set) => ({ appId: "", appName: "", bzbsService: null, uuid: "", macAddress: "", clientVersion: "", os: "", platform: "", fcmToken: "", deviceNotificationEnabled: false, urls: { webCallback: "", cart: "" }, tokenFunctions: null, tokenType: "auth_token", config: { defaultDashboardConfig: "", defaultDashboardMode: "main", defaultMenuConfig: "", defaultCampaignConfig: "" }, setAppId: (appId) => set({ appId }), setAppName: (appName) => set({ appName }), setBzbsService: (service) => set({ bzbsService: service }), setUuid: (uuid) => set({ uuid }), setMacAddress: (macAddress) => set({ macAddress }), setClientVersion: (clientVersion) => set({ clientVersion }), setOs: (os) => set({ os }), setPlatform: (platform) => set({ platform }), setFcmToken: (fcmToken) => set({ fcmToken }), setDeviceNotificationEnabled: (deviceNotificationEnabled) => set({ deviceNotificationEnabled }), setUrls: (urls) => set({ urls }), setTokenFunctions: (tokenFunctions) => set({ tokenFunctions }), setTokenType: (tokenType) => set({ tokenType }), configure: (config) => { set({ appId: config.appId, appName: config.appName, bzbsService: config.bzbsService, uuid: config.uuid, clientVersion: config.clientVersion, os: config.os, platform: config.platform, fcmToken: config.fcmToken, deviceNotificationEnabled: config.deviceNotificationEnabled, urls: config.urls, tokenFunctions: config.tokenFunctions, tokenType: config.tokenType, config: { defaultDashboardConfig: config.defaultDashboardConfig, defaultDashboardMode: config.defaultDashboardMode, defaultMenuConfig: config.defaultMenuConfig, defaultCampaignConfig: config.defaultCampaignConfig } }); } })); // src/stores/address.store.ts var useAddressStore = (0, import_zustand2.create)((set, get) => ({ // Initial state data: [], selectedAddress: null, isLoading: false, error: null, setSelectedAddress: (address) => set({ selectedAddress: address }), fetchData: () => __async(null, null, function* () { const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { return { type: "client-error", message: "Service not configured" }; } set({ isLoading: true }); const response = yield bzbsService.addressApi.userAddresses(); set({ isLoading: false }); if (response.type === "success") { set({ data: response.model, error: null }); } else { set({ error: response }); } return response; }), createAddress: (address) => __async(null, null, function* () { const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { return { type: "client-error", message: "Service not configured" }; } set({ isLoading: true }); const response = yield bzbsService.addressApi.updateAddress(__spreadProps(__spreadValues({}, address), { rowKey: "" })); set({ isLoading: false }); if (response.type === "success") { get().fetchData(); set({ error: null }); } else { set({ error: response }); } return response; }), updateAddress: (address) => __async(null, null, function* () { const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { return { type: "client-error", message: "Service not configured" }; } set({ isLoading: true }); const response = yield bzbsService.addressApi.updateAddress(__spreadProps(__spreadValues({}, address), { rowKey: address.rowKey || "" })); set({ isLoading: false }); if (response.type === "success") { get().fetchData(); set({ error: null }); } else { set({ error: response }); } return response; }), deleteAddress: (rowKey) => __async(null, null, function* () { const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { return { type: "client-error", message: "Service not configured" }; } set({ isLoading: true }); const response = yield bzbsService.addressApi.deleteAddress({ rowKey }); set({ isLoading: false }); if (response.type === "success") { get().fetchData(); set({ error: null }); } else { set({ error: response }); } return response; }), clear: () => { set({ data: [], selectedAddress: null, isLoading: false, error: null }); } })); // src/stores/alert.store.ts var import_zustand3 = require("zustand"); var useAlertStore = (0, import_zustand3.create)((set, get) => ({ isOpen: false, alertRequest: { title: "", content: "", onClose: () => { } }, openAlert: (request) => { set({ alertRequest: request, isOpen: true }); }, closeAlert: () => { const { alertRequest } = get(); alertRequest.onClose(); set({ isOpen: false }); } })); // src/stores/analytics.store.ts var import_matomo_tracker_react_native = __toESM(require("matomo-tracker-react-native")); var import_zustand4 = require("zustand"); var useAnalyticsStore = (0, import_zustand4.create)((set, get) => ({ isInitialized: false, isEnabled: true, siteId: void 0, urlBase: void 0, trackerUrl: void 0, userId: void 0, disabled: false, log: false, matomoInstance: void 0, presetUserInfo: void 0, initialize: (config) => { try { const matomoInstance = new import_matomo_tracker_react_native.default({ urlBase: config.urlBase, siteId: config.siteId, trackerUrl: config.trackerUrl, userId: config.userId, disabled: config.disabled || false, log: config.log || false }); set({ siteId: config.siteId, urlBase: config.urlBase, trackerUrl: config.trackerUrl, userId: config.userId, disabled: config.disabled || false, log: config.log || false, matomoInstance, isInitialized: true }); console.log("Analytics: Matomo tracker initialized", config); } catch (error) { console.error("Analytics: Failed to initialize Matomo tracker", error); set({ siteId: config.siteId, urlBase: config.urlBase, trackerUrl: config.trackerUrl, userId: config.userId, disabled: config.disabled || false, log: config.log || false, isInitialized: false }); } }, setEnabled: (enabled) => { set({ isEnabled: enabled }); }, setPresetUserInfo: (userInfo) => { set({ presetUserInfo: userInfo }); }, clearPresetUserInfo: () => { set({ presetUserInfo: void 0 }); }, trackAppStart: (userInfo) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track App Start skipped - not initialized, disabled, or tracking disabled"); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), userInfo); yield state.matomoInstance.trackAppStart({ userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: App start tracked successfully", { userInfo: mergedUserInfo }); } } catch (error) { console.error("Analytics: Failed to track app start", error); } }), trackEvent: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Event skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackEvent({ category: params.category || "User Action", action: params.action, name: params.name, value: params.value, campaign: params.campaign, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Event tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track event", error, params); } }), trackScreenView: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Screen View skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackScreenView({ name: params.name, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Screen view tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track screen view", error, params); } }), trackAction: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Action skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackAction({ name: params.name, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Action tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track action", error, params); } }), trackSiteSearch: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Site Search skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackSiteSearch({ keyword: params.keyword, category: params.category, count: params.count, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Site search tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track site search", error, params); } }), trackLink: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Link skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackLink({ link: params.link, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Link tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track link", error, params); } }), trackDownload: (params) => __async(null, null, function* () { const state = get(); if (!state.isInitialized || !state.isEnabled || !state.matomoInstance || state.disabled) { console.debug("Analytics: Track Download skipped - not initialized, disabled, or tracking disabled", params); return; } try { const mergedUserInfo = __spreadValues(__spreadValues({}, state.presetUserInfo), params.userInfo); yield state.matomoInstance.trackDownload({ download: params.download, userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : void 0 }); if (state.log) { console.debug("Analytics: Download tracked successfully", params); } } catch (error) { console.error("Analytics: Failed to track download", error, params); } }), setUserId: (userId) => { const state = get(); if (userId) { const updatedUserInfo = __spreadProps(__spreadValues({}, state.presetUserInfo), { uid: userId }); set({ userId, presetUserInfo: updatedUserInfo }); } else { const currentUserInfo = state.presetUserInfo || {}; if (currentUserInfo.uid) { const updatedUserInfo = __spreadValues({}, currentUserInfo); delete updatedUserInfo.uid; set({ userId: void 0, presetUserInfo: Object.keys(updatedUserInfo).length > 0 ? updatedUserInfo : void 0 }); } else { set({ userId: void 0 }); } } if (state.log) { console.debug("Analytics: User ID updated in preset userInfo", userId); } }, setCustomDimension: (id, value) => { const state = get(); if (!state.presetUserInfo) { set({ presetUserInfo: { [`dimension${id}`]: value } }); } else { set({ presetUserInfo: __spreadProps(__spreadValues({}, state.presetUserInfo), { [`dimension${id}`]: value }) }); } if (state.log) { console.debug("Analytics: Custom dimension set in preset userInfo", { id, value }); } }, reset: () => { set({ isInitialized: false, isEnabled: true, siteId: void 0, urlBase: void 0, trackerUrl: void 0, userId: void 0, disabled: false, log: false, matomoInstance: void 0, presetUserInfo: void 0 }); console.debug("Analytics: Store reset successfully"); } })); // src/stores/auth.store.ts var import_zustand7 = require("zustand"); // src/stores/locale.store.ts var import_zustand5 = require("zustand"); // src/utils/locale.ts var localeToLCIDMap = { "ar-SA": 1025, "bg-BG": 1026, "ca-ES": 1027, "zh-TW": 1028, "cs-CZ": 1029, "da-DK": 1030, "de-DE": 1031, "el-GR": 1032, "en-US": 1033, "es-ES": 1034, "fi-FI": 1035, "fr-FR": 1036, "he-IL": 1037, "hu-HU": 1038, "is-IS": 1039, "it-IT": 1040, "ja-JP": 1041, "ko-KR": 1042, "nl-NL": 1043, "nb-NO": 1044, "pl-PL": 1045, "pt-BR": 1046, "rm-CH": 1047, "ro-RO": 1048, "ru-RU": 1049, "hr-HR": 1050, "sk-SK": 1051, "sq-AL": 1052, "sv-SE": 1053, "th-TH": 1054, "tr-TR": 1055, "ur-PK": 1056, "id-ID": 1057, "uk-UA": 1058, "be-BY": 1059, "sl-SI": 1060, "et-EE": 1061, "lv-LV": 1062, "lt-LT": 1063, "tg-Cyrl-TJ": 1064, "fa-IR": 1065, "vi-VN": 1066, "hy-AM": 1067, "az-Latn-AZ": 1068, "eu-ES": 1069, "wen-DE": 1070, "mk-MK": 1071, "st-ZA": 1072, "ts-ZA": 1073, "tn-ZA": 1074, "ven-ZA": 1075, "xh-ZA": 1076, "zu-ZA": 1077, "af-ZA": 1078, "ka-GE": 1079, "fo-FO": 1080, "hi-IN": 1081, "mt-MT": 1082, "se-NO": 1083, "gd-GB": 1084, yi: 1085, "ms-MY": 1086, "kk-KZ": 1087, "ky-KG": 1088, "sw-KE": 1089, "tk-TM": 1090, "uz-Latn-UZ": 1091, "tt-RU": 1092, "bn-IN": 1093, "pa-IN": 1094, "gu-IN": 1095, "or-IN": 1096, "ta-IN": 1097, "te-IN": 1098, "kn-IN": 1099, "ml-IN": 1100, "as-IN": 1101, "mr-IN": 1102, "sa-IN": 1103, "mn-MN": 1104, "bo-CN": 1105, "cy-GB": 1106, "km-KH": 1107, "lo-LA": 1108, "my-MM": 1109, "gl-ES": 1110, "kok-IN": 1111, mni: 1112, "sd-IN": 1113, "syr-SY": 1114, "si-LK": 1115, "chr-US": 1116, "iu-Cans-CA": 1117, "am-ET": 1118, tmz: 1119, "ks-Arab-IN": 1120, "ne-NP": 1121, "fy-NL": 1122, "ps-AF": 1123, "fil-PH": 1124, "dv-MV": 1125, "bin-NG": 1126, "fuv-NG": 1127, "ha-Latn-NG": 1128, "ibb-NG": 1129, "yo-NG": 1130, "quz-BO": 1131, "nso-ZA": 1132, "ig-NG": 1136, "kr-NG": 1137, "gaz-ET": 1138, "ti-ER": 1139, "gn-PY": 1140, "haw-US": 1141, la: 1142, "so-SO": 1143, "ii-CN": 1144, "pap-AN": 1145, "ug-Arab-CN": 1152, "mi-NZ": 1153, "ar-IQ": 2049, "zh-CN": 2052, "de-CH": 2055, "en-GB": 2057, "es-MX": 2058, "fr-BE": 2060, "it-CH": 2064, "nl-BE": 2067, "nn-NO": 2068, "pt-PT": 2070, "ro-MD": 2072, "ru-MD": 2073, "sr-Latn-CS": 2074, "sv-FI": 2077, "ur-IN": 2080, "az-Cyrl-AZ": 2092, "ga-IE": 2108, "ms-BN": 2110, "uz-Cyrl-UZ": 2115, "bn-BD": 2117, "pa-PK": 2118, "mn-Mong-CN": 2128, "bo-BT": 2129, "sd-PK": 2137, "tzm-Latn-DZ": 2143, "ks-Deva-IN": 2144, "ne-IN": 2145, "quz-EC": 2155, "ti-ET": 2163, "ar-EG": 3073, "zh-HK": 3076, "de-AT": 3079, "en-AU": 3081, "fr-CA": 3084, "sr-Cyrl-CS": 3098, "ar-LY": 4097, "zh-SG": 4100, "de-LU": 4103, "en-CA": 4105, "fr-CH": 4108, "hr-BA": 4122, "ar-DZ": 5121, "zh-MO": 5124, "de-LI": 5127, "en-NZ": 5129, "fr-LU": 5132, "bs-Latn-BA": 5146, "ar-MO": 6145, "fr-MC": 6156, "ar-TN": 7169, "ar-OM": 8193, "ar-YE": 9217, "en-BZ": 10249, "es-PE": 10250, "fr-SN": 10252, "ar-JO": 11265, "fr-CM": 11276, "en-ID": 14345, "es-CL": 13322, "en-HK": 15369, "fr-MA": 14348, "en-MY": 17417, "es-SV": 17418, "es-NI": 19466, "es-PR": 20490, "es-US": 21514, "fr-015": 58380 }; function findBestLocaleFromString(value) { if (localeToLCIDMap[value]) { return { locale: value, localeId: localeToLCIDMap[value] }; } const partialMatch = Object.keys(localeToLCIDMap).find((key) => key.startsWith(value.split("-")[0])); if (partialMatch) { return { locale: partialMatch, localeId: localeToLCIDMap[partialMatch] }; } throw new Error(`Locale '${value}' is not supported.`); } // src/stores/locale.store.ts var EN = { locale: "en", localeId: 1033 }; var TH = { locale: "th", localeId: 1054 }; var useLocaleStore = (0, import_zustand5.create)((set) => ({ appLocale: EN, locale: "en", localeId: 1033, setAppLocale: (locale) => { const newLocale = typeof locale === "string" ? findBestLocaleFromString(locale) : locale; set({ appLocale: newLocale, locale: newLocale.locale, localeId: newLocale.localeId }); } })); // src/utils/analytics.ts var import_react2 = __toESM(require("react")); // src/providers/analytics_provider.tsx var import_matomo_tracker_react_native2 = __toESM(require("matomo-tracker-react-native")); var import_react = __toESM(require("react")); var AnalyticsContext = (0, import_react.createContext)({ isInitialized: false, isEnabled: true, actions: { setEnabled: () => { }, setPresetUserInfo: () => { }, clearPresetUserInfo: () => { }, trackAppStart: () => __async(null, null, function* () { }), trackEvent: () => __async(null, null, function* () { }), trackScreenView: () => __async(null, null, function* () { }), trackAction: () => __async(null, null, function* () { }), trackSiteSearch: () => __async(null, null, function* () { }), trackLink: () => __async(null, null, function* () { }), trackDownload: () => __async(null, null, function* () { }), setUserId: () => { }, setCustomDimension: () => { }, reset: () => { } } }); function useAnalyticsContext() { return (0, import_react.useContext)(AnalyticsContext); } // src/utils/analytics.ts var usePageTracking = (pageName, dependencies = [], customUserInfo) => { const { actions, isInitialized, isEnabled } = useAnalyticsContext(); (0, import_react2.useEffect)(() => { if (isInitialized && isEnabled) { actions.trackScreenView({ name: pageName || (typeof window !== "undefined" ? window.location.pathname : "/"), userInfo: customUserInfo }); } }, [isInitialized, isEnabled, pageName, customUserInfo, ...dependencies]); }; var useAnalytics = () => { const { actions, isInitialized, isEnabled } = useAnalyticsContext(); return { isInitialized, isEnabled, trackEvent: actions.trackEvent, trackScreenView: actions.trackScreenView, trackAction: actions.trackAction, trackAppStart: actions.trackAppStart, trackSiteSearch: actions.trackSiteSearch, trackLink: actions.trackLink, trackDownload: actions.trackDownload, setUserId: actions.setUserId, setCustomDimension: actions.setCustomDimension, setEnabled: actions.setEnabled, setPresetUserInfo: actions.setPresetUserInfo, clearPresetUserInfo: actions.clearPresetUserInfo }; }; var useAnalyticsState = () => { return useAnalyticsStore(); }; var trackCommonEvents = { /** * Track register success event * Screen: register, Category: register, Event: register_success */ registerSuccess: (userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category: "register", name: "register_success", userInfo }); } }), /** * Track login success event * Screen: login, Category: login, Event: login_success */ loginSuccess: (userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category: "login", name: "login_success", userInfo }); } }), /** * Track view campaign event * Screen: campaign, Category: campaign_list, Event: view_campaign */ viewCampaign: (userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category: "campaign_list", name: "view_campaign", userInfo }); } }), /** * Track redeem success event * Screen: campaign, Category: campaign_redeem, Event: redeem_success */ redeemSuccess: (campaignId, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category: "campaign_redeem", name: "redeem_success", // Use campaign_id as label - can be passed in userInfo or as a separate dimension userInfo: __spreadProps(__spreadValues({}, userInfo), { dimension3: campaignId // Store campaign_id in dimension3 }) }); } }), /** * Track unconsent success event * Screen: marketing, Category: marketing_unconsent, Event: unconsent_success */ unconsentSuccess: (userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category: "marketing_unconsent", name: "unconsent_success", userInfo }); } }), /** * Track button click event */ buttonClick: (buttonName, category = "UI", userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "on click", category, name: buttonName, userInfo }); } }), /** * Track form submit event */ formSubmit: (formName, success = true, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "submit", category: "Form", name: formName, userInfo: __spreadProps(__spreadValues({}, userInfo), { dimension1: success ? "success" : "failure" }) }); } }), /** * Track search event */ search: (keyword, resultCount, category = "Search", userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackSiteSearch({ keyword, category, count: resultCount, userInfo }); } }), /** * Track purchase event */ purchase: (amount, currency = "THB", productName, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "purchase", category: "Commerce", name: productName || "Purchase", value: amount, userInfo: __spreadProps(__spreadValues({}, userInfo), { dimension1: currency }) }); } }), /** * Track user registration event */ userRegistration: (method = "email", userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "register", category: "User", name: `registration_${method}`, userInfo }); } }), /** * Track user login event */ userLogin: (method = "email", userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "login", category: "User", name: `login_${method}`, userInfo }); } }), /** * Track error event */ error: (errorType, errorMessage, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "error", category: "Error", name: errorType, userInfo: __spreadProps(__spreadValues({}, userInfo), { dimension2: errorMessage }) }); } }), /** * Track custom event */ custom: (name, category, label, value, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent({ action: "custom", category, name, value, userInfo: __spreadProps(__spreadValues({}, userInfo), { dimension1: label }) }); } }) }; var withPageTracking = (Component, pageName, customUserInfo) => { const WrappedComponent = (props) => { usePageTracking(pageName, [], customUserInfo); return import_react2.default.createElement(Component, props); }; WrappedComponent.displayName = `withPageTracking(${Component.displayName || Component.name || "Component"})`; return WrappedComponent; }; var initializeAnalytics = (config) => { const store = useAnalyticsStore.getState(); store.initialize(config); }; var analytics = { /** * Initialize analytics (can be called outside React components) */ init: (config) => { const store = useAnalyticsStore.getState(); store.initialize(config); }, /** * Track event (can be called outside React components) */ trackEvent: (params) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackEvent(params); } }), /** * Track screen view (can be called outside React components) */ trackScreenView: (name, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackScreenView({ name, userInfo }); } }), /** * Track app start (can be called outside React components) */ trackAppStart: (userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackAppStart(userInfo); } }), /** * Track site search (can be called outside React components) */ trackSiteSearch: (keyword, category, count, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackSiteSearch({ keyword, category, count, userInfo }); } }), /** * Track link click (can be called outside React components) */ trackLink: (link, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackLink({ link, userInfo }); } }), /** * Track download (can be called outside React components) */ trackDownload: (download, userInfo) => __async(null, null, function* () { const store = useAnalyticsStore.getState(); if (store.isInitialized && store.isEnabled) { yield store.trackDownload({ download, userInfo }); } }), /** * Set user ID and update preset userInfo (can be called outside React components) */ setUserId: (userId) => { const store = useAnalyticsStore.getState(); store.setUserId(userId); }, /** * Set custom dimension (can be called outside React components) */ setCustomDimension: (id, value) => { const store = useAnalyticsStore.getState(); store.setCustomDimension(id, value); }, /** * Set preset user info (can be called outside React components) */ setPresetUserInfo: (userInfo) => { const store = useAnalyticsStore.getState(); store.setPresetUserInfo(userInfo); }, /** * Clear preset user info (can be called outside React components) */ clearPresetUserInfo: () => { const store = useAnalyticsStore.getState(); store.clearPresetUserInfo(); }, /** * Enable/disable analytics (can be called outside React components) */ setEnabled: (enabled) => { const store = useAnalyticsStore.getState(); store.setEnabled(enabled); }, /** * Reset analytics (can be called outside React components) */ reset: () => { const store = useAnalyticsStore.getState(); store.reset(); } }; // src/utils/string_utils.ts function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } // src/constant.tsx var campaignType = { draw: 0, free: 1, deal: 2, buy: 3, bid: 4, ads: 5, install: 6, booking: 7, interface: 8, event: 9, media: 10, ewalletTopUp: 11, ewalletRedeem: 12, ewalletTransfer: 13, ewalletBanking: 14, autofeed: 15, news: 16, reservation: 17, ewalletBuy: 18, pointRedemption: 19, donate: 20, pointFree: 21, voucher: 22, encrypt: 23, encryptRedeem: 24, giftCard: 25, verifyCode: 26, subscription: 27, fillCode: 28, subscriptionFood: 29, buyEVoucher: 30, uploadReceipt: 31, payWithPoints: 32, marketPlacePrivilege: 33, topup2C2P: 34, directTopup2C2P: 35 }; var campaignPointType = { use: "use", get: "get" }; var campaignInterfaceType = { web: "web", survey: "survey", surveyApprove: "surveyapprove" }; // src/utils/purchase_utils.tsx function getPurchaseItemStatus(item) { var _a, _b, _c, _d, _e; const title = (_a = item.Name) != null ? _a : ""; const pointPerUnit = (_b = item.PointPerUnit) != null ? _b : 0; const image = (_c = item.FullImageUrl) != null ? _c : ""; const showTracking = (_d = item.Delivered) != null ? _d : false; const expireDate = new Date(((_e = item.VoucherExpireDate) != null ? _e : 0) * 1e3); let showCode = false; let status = "used"; if (item.ArrangedDate) { return { title, pointPerUnit, expireDate, image, showTracking, showCode: false, expired: false, status: "used" }; } if (item.IsExpired || item.ExpireIn && item.ExpireIn <= 0) { return { title, pointPerUnit, expireDate, image, showTracking, showCode: false, expired: true, status: "expired" }; } if (item.VoucherExpireDate && item.VoucherExpireDate <= Date.now() / 1e3) { return { title, pointPerUnit, expireDate, image, showTracking, showCode: false, expired: true, status: "expired" }; } switch (item.Type) { case campaignType.free: case campaignType.deal: status = "redeemed"; showCode = true; break; case campaignType.draw: if (item.HasWinner) { status = item.IsWinner ? "draw_win" : "draw_lose"; } else { status = "draw_waiting"; } break; } if (item.Delivered) { showCode = false; status = item.IsShipped ? "shipped" : "prepared_for_shipping"; } return { title, pointPerUnit, expireDate, image, showTracking, showCode, expired: false, status }; } // src/stores/user.store.ts var import_zustand6 = require("zustand"); // src/service/bzbs_service.ts var blake = __toESM(require("blakejs")); var import_emittery = __toESM(require("emittery")); var import_uuid = require("uuid"); var eventEmitter = new import_emittery.default(); function defaultCorelationIdGenerator() { return (0, import_uuid.v7)(); } function isJWT(token) { return typeof token === "string" && token.split(".").length === 3; } function addDefaultHeaderInterceptor(axiosInstance, appId, subscriptionKey, tokenFunctions, apiVersion, corelationIdGenerator = defaultCorelationIdGenerator) { axiosInstance.interceptors.request.use( (config) => __async(null, null, function* () { config.headers.set("App-Id", appId); if (subscriptionKey) { config.headers.set("Ocp-Apim-Subscription-Key", subscriptionKey); } if (apiVersion) { config.headers.set("api-version", apiVersion); } config.headers.set("X-Corelation-Id", corelationIdGenerator()); const token = yield tokenFunctions.getToken(); if (token) { if (isJWT(token)) { config.headers.set("Authorization", `Bearer ${token}`); } else { config.headers.set("Authorization", `token ${token}`); } } return config; }), (error) => { return Promise.reject(error); } ); axiosInstance.interceptors.response.use( (response) => { const responseData = response.data; const buzzebeesObj = responseData.buzzebees; if (buzzebeesObj) { const points = buzzebeesObj.points; const badges = buzzebeesObj.badges; if (typeof points === "number") { eventEmitter.emit("get_points", buzzebeesObj); } if (badges) { eventEmitter.emit("get_badges", badges); } } if (responseData.error) { const id = responseData.error.id; const code = responseData.error.code; if (code === 409 && (id === 1905 || id === 2076)) { eventEmitter.emit("session_expired", responseData.error); } } return response; }, (error) => { return Promise.reject(error); } ); } function generateShortLivedId() { return Math.random().toString(36).substring(2, 15); } function avatarUrl(baseUrl, appId, userId, token) { const url = `${baseUrl}/profile/${userId}/picture?timestamp=${Date.now()}&type=large${token === null ? "" : `&token=${token}&device_app_id=${appId}`}`; console.log(url); return url; } function largeImage(url) { if (!url) return ""; const result = url.replace("?", "-large?"); return result; } function fetchImage(axiosClient, imageUrl) { return __async(this, null, function* () { try { const response = yield axiosClient.get(imageUrl, { responseType: "blob" }); return response.data; } catch (error) { console.error("Error fetching image:", error); } }); } function createInterfaceWebsiteUrl(url, token, returnUrl = "", params) { if (token) { params = __spreadValues({ token: createInterfaceToken(token), return_url: returnUrl }, params); } const searchParams = new URLSearchParams(params).toString(); const result = url.includes("?") ? `${url}&${searchParams}` : `${url}?${searchParams}`; return result; } function createInterfaceToken(token) { if (token.length <= 5) { return token; } const firstChar = token.substring(0, 1); const last5Chars = token.substring(token.length - 5); const remainingChars = token.substring(1, token.length - 5); return firstChar === "." ? `${last5Chars}${remainingChars}` : token; } function createCartUrl(cartUrl, appName, accessKey, params) { const newUrl = cartUrl.endsWith("/") ? `${cartUrl}landing/${appName}` : `${cartUrl}/landing/${appName}`; const newParams = __spreadValues({ access_key: accessKey, appname_config: appName }, params); const searchParams = new URLSearchParams(newParams).toString(); return searchParams ? `${newUrl}?${searchParams}` : newUrl; } function generateBlake2bSignatureHex(data, key, encoder) { const keyBytes = encoder.encode(key); return blake.blake2bHex(data, keyBytes, 32); } function getOtpSignatureHeaders({ appId, contactNumber, channel, encoder, now = /* @__PURE__ */ new Date() }) { const dateTime = now.toISOString().split(".")[0] + "Z"; const timeStamp = Math.floor(now.getTime() / 1e3); const data = `${appId}|${contactNumber}|${channel}|${dateTime}`; const signature = generateBlake2bSignatureHex(data, appId, encoder); return { "OTP-Signature": signature, Timestamp: timeStamp }; } function addBlake2OtpSignatureInterceptor(axiosInstance, paths, encoder, getCurrentDateTime = () => /* @__PURE__ */ new Date()) { axiosInstance.interceptors.request.use((config) => { if (paths.some((path) => config.url && config.url.includes(path))) { const getParam = (key) => { if (config.params && config.params[key]) return config.params[key]; if (config.data && typeof config.data === "object" && config.data[key]) return config.data[key]; return void 0; }; const appId = getParam("app_id"); const contactNumber = getParam("contact_number"); const channel = getParam("channel"); if (appId && contactNumber && channel) { const now = getCurrentDateTime(); const headers = getOtpSignatureHeaders({ appId, contactNumber, channel, now, encoder }); config.headers.set("OTP-Signature", headers["OTP-Signature"]); config.headers.set("Timestamp", headers["Timestamp"]); } } return config; }); } // src/stores/user.store.ts var useUserStore = (0, import_zustand6.create)((set, get) => { return { user: null, points: 0, recentPoints: 0, expiringPoints: [], recentBadge: null, recentTrace: null, cartCount: 0, isLoading: false, error: null, badgeList: [], traceList: [], fetchUser: () => __async(null, null, function* () { set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.profile(); set({ isLoading: false }); if (response.type === "success") { set({ user: response.model, error: null }); } else { set({ error: response }); } return response; }), fetchPoint: () => __async(null, null, function* () { var _a; set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.points(); set({ isLoading: false }); if (response.type === "success") { set({ points: (_a = response.model.points) != null ? _a : 0, error: null }); } else { set({ error: response }); } return response; }), fetchExpiringPoints: () => __async(null, null, function* () { var _a; set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.expiringPoints(); set({ isLoading: false }); if (response.type === "success") { set({ expiringPoints: (_a = response.model.expiring_points) != null ? _a : [], error: null }); } else { set({ error: response }); } return response; }), fetchCartCount: () => __async(null, null, function* () { var _a; set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.cartApi.cartCount(); set({ isLoading: false }); if (response.type === "success") { set({ cartCount: (_a = response.model.cart_count) != null ? _a : 0, error: null }); } else { set({ error: response, cartCount: 0 }); } return response; }), editUser: (data) => __async(null, null, function* () { set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.updateProfile(data); set({ isLoading: false }); if (response.type === "success") { set({ user: response.model, error: null }); const { tokenFunctions, tokenType } = useBuzzebeesAppStore.getState(); const token = tokenType === "jwt" ? response.model.Jwt : response.model.Token; if (token && tokenFunctions) { tokenFunctions.setToken(token); } } else { set({ error: response }); } return response; }), changePassword: (oldPassword, newPassword) => __async(null, null, function* () { set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.changePassword({ current: oldPassword, change: newPassword }); set({ isLoading: false }); if (response.type === "success") { set({ error: null }); } else { set({ error: response }); } return response; }), changeContactNumber: (contactNumber, otp, refCode) => __async(null, null, function* () { set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } const response = yield bzbsService.profileApi.changeContactNumber({ contactNumber, otp, refCode }); set({ isLoading: false }); if (response.type === "success") { set({ error: null }); } else { set({ error: response }); } return response; }), changeAvatar: (avatar) => __async(null, null, function* () { set({ isLoading: true }); const bzbsService = useBuzzebeesAppStore.getState().bzbsService; if (!bzbsService) { set({ isLoading: false, error: { type: "client-error", message: "Service not configured" } }); return { type: "client-error", message: "Service not configured" }; } c