UNPKG

@bzbs/react-providers

Version:

A collection of React Context Provider for Buzzebees apps

1 lines 237 kB
{"version":3,"sources":["../src/providers/auth_provider.tsx","../src/providers/buzzebees_service_provider.tsx","../src/providers/locale_provider.tsx","../src/utils/locale.ts","../src/providers/analytics_provider.tsx","../src/providers/user_provider.tsx","../src/service/bzbs_service.ts","../src/providers/cart_provider.tsx","../src/providers/alert_provider.tsx","../src/providers/loading_indicator_provider.tsx","../src/providers/confirm_provider.tsx","../src/providers/popup_provider.tsx","../src/providers/address_provider.tsx","../src/providers/campaign_detail_provider.tsx","../src/constant.tsx","../src/providers/campaigns_provider.tsx","../src/providers/categories_provider.tsx","../src/providers/consent_provider.tsx","../src/providers/coupon_provider.tsx","../src/providers/dashboard_provider.tsx","../src/providers/default_main_app_provider.tsx","../src/utils/analytics.ts","../src/stores/analytics.store.ts","../src/utils/string_utils.ts","../src/utils/purchase_utils.tsx","../src/providers/maintenance_provider.tsx","../src/providers/notification_provider.tsx","../src/providers/point_log_provider.tsx","../src/providers/registration_provider.tsx","../src/providers/zipcode_provider.tsx","../src/providers/purchase_provider.tsx"],"sourcesContent":["import {\n ConfirmOtpResponse,\n ErrorResponse,\n ForgetPasswordResponse,\n LoginResponse,\n OtpResponse,\n ResumeResponse,\n ServiceResponse,\n StatusResponse,\n ValidateOtpResponse,\n Version,\n} from '@bzbs/react-api-client';\nimport React, { createContext, useContext, useRef, useState } from 'react';\nimport { LoginResponseHandler } from '../types';\nimport { useBuzzebeesServiceContext } from './buzzebees_service_provider';\nimport { useAppLocaleContext } from './locale_provider';\nimport { useAnalyticsContext } from './analytics_provider';\n\nexport type AuthContextType = {\n isInitialized: boolean;\n versionData?: Version | null;\n isLoading: boolean;\n token: string | null;\n isLoadingToken: boolean;\n isLoggedIn: boolean;\n error: ErrorResponse | null;\n actions: {\n init(uuid: string, appId: string, deviceToken: string): void;\n setUUID(value: string): void;\n setAppId(value: string): void;\n setDeviceToken(value: string): void;\n setClientVersion(value: string): void;\n setOs(value: string): void;\n setPlatform(value: string): void;\n setError(value: unknown): void;\n setLoginResponseHandler(fn: LoginResponseHandler): void;\n clearData: () => void;\n loginWithUsernamePassword: (username: string, password: string) => Promise<ServiceResponse<LoginResponse>>;\n loginWithGoogle: (token: string) => Promise<ServiceResponse<LoginResponse>>;\n loginWithFacebook: (token: string) => Promise<ServiceResponse<LoginResponse>>;\n loginWithApple: (token: string, refreshToken: string) => Promise<ServiceResponse<LoginResponse>>;\n loginWithUUID: () => Promise<ServiceResponse<LoginResponse>>;\n logout: () => Promise<ServiceResponse<unknown>>;\n forgetPassword: (\n contact: string,\n type: 'email' | 'contact_number'\n ) => Promise<ServiceResponse<ForgetPasswordResponse>>;\n resetPassword: (\n contact: string,\n otp: string,\n refCode: string,\n password: string\n ) => Promise<ServiceResponse<StatusResponse>>;\n sendOtp: (contact: string) => Promise<ServiceResponse<OtpResponse>>;\n validateOtp: (\n otp: string,\n refCode: string,\n contact: string,\n channel: string\n ) => Promise<ServiceResponse<ValidateOtpResponse>>;\n confirmOtp: (otp: string, refCode: string, contact: string) => Promise<ServiceResponse<ConfirmOtpResponse>>;\n resume: (clientVersion: string) => Promise<ServiceResponse<ResumeResponse>>;\n version: (clientVersion: string) => Promise<ServiceResponse<Version>>;\n };\n};\n\nexport const AuthContext = createContext({\n isInitialized: false,\n authData: null,\n versionData: null,\n isLoading: false,\n isLoggedIn: false,\n error: null,\n token: null,\n isLoadingToken: false,\n actions: {\n init: () => {},\n setUUID: () => {},\n setAppId: () => {},\n setDeviceToken: () => {},\n setClientVersion: () => {},\n setOs: () => {},\n setPlatform: () => {},\n setError: () => {},\n setLoginResponseHandler: () => {},\n clearData: () => {},\n loginWithUsernamePassword: async () => ({ type: 'client-error', message: 'Not implemented' }),\n loginWithGoogle: async () => ({ type: 'client-error', message: 'Not implemented' }),\n loginWithFacebook: async () => ({ type: 'client-error', message: 'Not implemented' }),\n loginWithApple: async () => ({ type: 'client-error', message: 'Not implemented' }),\n loginWithUUID: async () => ({ type: 'client-error', message: 'Not implemented' }),\n logout: async () => ({ type: 'client-error', message: 'Not implemented' }),\n forgetPassword: async () => ({ type: 'client-error', message: 'Not implemented' }),\n resetPassword: async () => ({ type: 'client-error', message: 'Not implemented' }),\n sendOtp: async () => ({ type: 'client-error', message: 'Not implemented' }),\n validateOtp: async () => ({ type: 'client-error', message: 'Not implemented' }),\n confirmOtp: async () => ({ type: 'client-error', message: 'Not implemented' }),\n resume: async () => ({ type: 'client-error', message: 'Not implemented' }),\n version: async () => ({ type: 'client-error', message: 'Not implemented' }),\n },\n} as AuthContextType);\n\nexport function useAuthContext() {\n return useContext(AuthContext);\n}\n\ntype getTokenFunction = () => Promise<string | null>;\ntype setTokenFunction = (token: string) => void;\ntype removeTokenFunction = () => void;\n\nexport type TokenFunctions = {\n getToken: getTokenFunction;\n setToken: setTokenFunction;\n removeToken: removeTokenFunction;\n};\n\nexport function AuthProvider({\n tokenFunctions,\n children,\n}: {\n tokenFunctions: TokenFunctions;\n children: React.ReactNode;\n}) {\n const [versionData, setVersionData] = useState<Version | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<ErrorResponse | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [isLoadingToken, setIsLoadingToken] = useState(false);\n const [token, setToken] = useState<string | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n\n const [loginResponseHandler, setLoginResponseHandler] = useState<LoginResponseHandler>(() => {});\n\n const { bzbsService } = useBuzzebeesServiceContext();\n const { localeId } = useAppLocaleContext();\n const { actions: analyticsActions } = useAnalyticsContext();\n const uuid = useRef<string>('');\n const appId = useRef<string>('');\n const deviceToken = useRef<string>('');\n const clientVersion = useRef<string>('');\n const os = useRef<string>('');\n const platform = useRef<string>('');\n\n const setUUID = (value: string) => {\n uuid.current = value;\n };\n\n const setAppId = (value: string) => {\n appId.current = value;\n };\n\n const setDeviceToken = (value: string) => {\n deviceToken.current = value;\n };\n\n const setClientVersion = (value: string) => {\n clientVersion.current = value;\n };\n\n const setOs = (value: string) => {\n os.current = value;\n };\n\n const setPlatform = (value: string) => {\n platform.current = value;\n };\n\n const init = (uuid: string, appId: string, deviceToken: string) => {\n setUUID(uuid);\n setAppId(appId);\n setDeviceToken(deviceToken);\n checkLoggedIn();\n };\n\n const checkLoggedIn = async () => {\n try {\n setIsLoadingToken(true);\n const savedToken = await tokenFunctions.getToken();\n setIsLoadingToken(false);\n if (savedToken) {\n setIsLoggedIn(true);\n } else {\n setIsLoggedIn(false);\n }\n setToken(savedToken);\n } catch (error) {\n setIsLoggedIn(false);\n }\n\n setIsInitialized(true);\n };\n\n const clearData = () => {\n setVersionData(null);\n setError(null);\n setIsLoading(false);\n setIsLoggedIn(false);\n setToken(null);\n };\n\n const login = async (\n loginFn: () => Promise<ServiceResponse<LoginResponse>>\n ): Promise<ServiceResponse<LoginResponse>> => {\n setIsLoading(true);\n const response = await loginFn();\n setIsLoading(false);\n\n if (response.type === 'success') {\n tokenFunctions.setToken(response.model.token);\n setToken(response.model.token);\n setIsLoggedIn(true);\n setError(null);\n loginResponseHandler(response.model);\n analyticsActions.trackEvent({\n action: 'on_click',\n name: 'login_success',\n category: 'login',\n });\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const loginWithUsernamePassword = async (\n username: string,\n password: string\n ): Promise<ServiceResponse<LoginResponse>> => {\n const response = await login(() =>\n bzbsService.authApi.usernamePasswordLogin({\n username: username,\n password: password,\n appId: appId.current,\n uuid: uuid.current,\n deviceToken: deviceToken.current,\n clientVersion: clientVersion.current,\n os: os.current,\n platform: platform.current,\n deviceLocale: localeId.toString(),\n deviceNotificationEnabled: true,\n })\n );\n\n return response;\n };\n\n const loginWithGoogle = async (token: string): Promise<ServiceResponse<LoginResponse>> => {\n const response = await login(() =>\n bzbsService.authApi.googleLogin({\n idToken: token,\n appId: appId.current,\n uuid: uuid.current,\n deviceToken: deviceToken.current,\n clientVersion: clientVersion.current,\n os: os.current,\n platform: platform.current,\n deviceLocale: localeId.toString(),\n deviceNotificationEnabled: true,\n })\n );\n\n return response;\n };\n\n const loginWithFacebook = async (token: string): Promise<ServiceResponse<LoginResponse>> => {\n const response = await login(() =>\n bzbsService.authApi.facebookLogin({\n accessToken: token,\n appId: appId.current,\n uuid: uuid.current,\n deviceToken: deviceToken.current,\n clientVersion: clientVersion.current,\n os: os.current,\n platform: platform.current,\n deviceLocale: localeId.toString(),\n deviceNotificationEnabled: true,\n })\n );\n\n return response;\n };\n\n const loginWithApple = async (token: string, refreshToken: string): Promise<ServiceResponse<LoginResponse>> => {\n const response = await login(() =>\n bzbsService.authApi.appleLogin({\n idToken: token,\n refreshToken: refreshToken,\n appId: appId.current,\n uuid: uuid.current,\n deviceToken: deviceToken.current,\n clientVersion: clientVersion.current,\n os: os.current,\n platform: platform.current,\n deviceLocale: localeId.toString(),\n deviceNotificationEnabled: true,\n })\n );\n\n return response;\n };\n\n const loginWithUUID = async (): Promise<ServiceResponse<LoginResponse>> => {\n const response = await login(() =>\n bzbsService.authApi.deviceLogin({\n appId: appId.current,\n uuid: uuid.current,\n deviceToken: deviceToken.current,\n clientVersion: clientVersion.current,\n os: os.current,\n platform: platform.current,\n deviceLocale: localeId.toString(),\n deviceNotificationEnabled: true,\n })\n );\n\n return response;\n };\n\n const logout = async (): Promise<ServiceResponse<unknown>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.logout({ uuid: uuid.current });\n setIsLoading(false);\n tokenFunctions.removeToken();\n setToken(null);\n setIsLoggedIn(false);\n setError(null);\n return response;\n };\n\n const forgetPassword = async (\n contact: string,\n type: 'email' | 'contact_number'\n ): Promise<ServiceResponse<ForgetPasswordResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.forgetPassword({ contact: contact, type: type });\n setIsLoading(false);\n return response;\n };\n\n const resetPassword = async (\n contact: string,\n otp: string,\n refCode: string,\n newPassword: string\n ): Promise<ServiceResponse<StatusResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.resetPassword({\n contact: contact,\n refCode: refCode,\n otp: otp,\n newPassword: newPassword,\n });\n setIsLoading(false);\n return response;\n };\n\n const sendOtp = async (contact: string): Promise<ServiceResponse<OtpResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.otp({\n uuid: uuid.current,\n appId: appId.current,\n contactNumber: contact,\n });\n setIsLoading(false);\n return response;\n };\n\n const validateOtp = async (\n contact: string,\n otp: string,\n refCode: string,\n channel: string\n ): Promise<ServiceResponse<ValidateOtpResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.validateOtp({\n appId: appId.current,\n otp: otp,\n refCode: refCode,\n contactNumber: contact,\n use: false,\n channel: channel,\n });\n setIsLoading(false);\n return response;\n };\n\n const confirmOtp = async (\n contact: string,\n otp: string,\n refCode: string\n ): Promise<ServiceResponse<ConfirmOtpResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.confirmOtp({ otp: otp, refCode: refCode, contactNumber: contact });\n setIsLoading(false);\n return response;\n };\n\n const resume = async (clientVersion: string): Promise<ServiceResponse<ResumeResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.resume({\n uuid: uuid.current,\n appId: appId.current,\n clientVersion: clientVersion,\n deviceToken: deviceToken.current,\n });\n setIsLoading(false);\n return response;\n };\n\n const version = async (clientVersion: string): Promise<ServiceResponse<Version>> => {\n setIsLoading(true);\n const response = await bzbsService.authApi.version(clientVersion);\n if (response.type === 'success') {\n setVersionData(response.model);\n }\n setIsLoading(false);\n return response;\n };\n\n return (\n <AuthContext.Provider\n value={{\n isInitialized,\n versionData,\n isLoading,\n isLoggedIn,\n token,\n isLoadingToken,\n error,\n actions: {\n init,\n setUUID,\n setAppId,\n setDeviceToken,\n setClientVersion,\n setOs,\n setPlatform,\n setError,\n setLoginResponseHandler,\n clearData,\n loginWithUsernamePassword,\n loginWithGoogle,\n loginWithFacebook,\n loginWithApple,\n loginWithUUID,\n logout,\n forgetPassword,\n resetPassword,\n sendOtp,\n validateOtp,\n confirmOtp,\n resume,\n version,\n },\n }}\n >\n {children}\n </AuthContext.Provider>\n );\n}\n","import { BzbsService } from '@bzbs/react-api-client';\nimport React, { createContext, useContext } from 'react';\n\nexport type BuzzebeesServiceContextType = {\n appId: string;\n appName: string;\n bzbsService: BzbsService;\n urls: {\n webCallback: string;\n cart: string;\n };\n};\n\nexport const BuzzebeesServiceContext = createContext<BuzzebeesServiceContextType>({\n appId: '',\n appName: '',\n bzbsService: {} as BzbsService,\n urls: {\n webCallback: '',\n cart: '',\n },\n});\n\nexport function useBuzzebeesServiceContext() {\n return useContext(BuzzebeesServiceContext);\n}\n\nexport type BuzzebeesServiceProviderProps = {\n appId: string;\n appName: string;\n bzbsService: BzbsService;\n urls: {\n webCallback: string;\n cart: string;\n };\n children: React.ReactNode;\n};\n\nexport function BuzzebeesServiceProvider({\n appId,\n appName,\n bzbsService,\n urls,\n children,\n}: BuzzebeesServiceProviderProps) {\n return (\n <BuzzebeesServiceContext.Provider\n value={{\n appId,\n appName,\n urls,\n bzbsService,\n }}\n >\n {children}\n </BuzzebeesServiceContext.Provider>\n );\n}\n","import React, { createContext, ReactNode, useContext, useState } from 'react';\nimport { findBestLocaleFromString } from '../utils/locale';\n\nexport type AppLocale = {\n locale: string;\n localeId: number;\n};\n\nexport const EN = { locale: 'en', localeId: 1033 };\nexport const TH = { locale: 'th', localeId: 1054 };\n\nexport type LocaleContextType = {\n appLocale: AppLocale;\n locale: string;\n localeId: number;\n setAppLocale: (locale: AppLocale | string) => void;\n};\n\nexport const LocaleContext = createContext({\n appLocale: EN,\n locale: 'en',\n localeId: 1033,\n setAppLocale: () => {},\n} as LocaleContextType);\n\nexport const useAppLocaleContext = () => {\n return useContext(LocaleContext);\n};\n\nexport const AppLocaleProvider = ({ initLocale, children }: { initLocale: AppLocale; children: ReactNode }) => {\n const [locale, setLocale] = useState<AppLocale>(initLocale);\n\n const setAppLocale = (locale: AppLocale | string) => {\n if (typeof locale === 'string') {\n setLocale(findBestLocaleFromString(locale));\n } else {\n setLocale(locale);\n }\n };\n\n return (\n <LocaleContext.Provider\n value={{\n appLocale: locale,\n locale: locale.locale,\n localeId: locale.localeId,\n setAppLocale: setAppLocale,\n }}\n >\n {children}\n </LocaleContext.Provider>\n );\n};\n","export const localeToLCIDMap: { [key: string]: number } = {\n 'ar-SA': 1025,\n 'bg-BG': 1026,\n 'ca-ES': 1027,\n 'zh-TW': 1028,\n 'cs-CZ': 1029,\n 'da-DK': 1030,\n 'de-DE': 1031,\n 'el-GR': 1032,\n 'en-US': 1033,\n 'es-ES': 1034,\n 'fi-FI': 1035,\n 'fr-FR': 1036,\n 'he-IL': 1037,\n 'hu-HU': 1038,\n 'is-IS': 1039,\n 'it-IT': 1040,\n 'ja-JP': 1041,\n 'ko-KR': 1042,\n 'nl-NL': 1043,\n 'nb-NO': 1044,\n 'pl-PL': 1045,\n 'pt-BR': 1046,\n 'rm-CH': 1047,\n 'ro-RO': 1048,\n 'ru-RU': 1049,\n 'hr-HR': 1050,\n 'sk-SK': 1051,\n 'sq-AL': 1052,\n 'sv-SE': 1053,\n 'th-TH': 1054,\n 'tr-TR': 1055,\n 'ur-PK': 1056,\n 'id-ID': 1057,\n 'uk-UA': 1058,\n 'be-BY': 1059,\n 'sl-SI': 1060,\n 'et-EE': 1061,\n 'lv-LV': 1062,\n 'lt-LT': 1063,\n 'tg-Cyrl-TJ': 1064,\n 'fa-IR': 1065,\n 'vi-VN': 1066,\n 'hy-AM': 1067,\n 'az-Latn-AZ': 1068,\n 'eu-ES': 1069,\n 'wen-DE': 1070,\n 'mk-MK': 1071,\n 'st-ZA': 1072,\n 'ts-ZA': 1073,\n 'tn-ZA': 1074,\n 'ven-ZA': 1075,\n 'xh-ZA': 1076,\n 'zu-ZA': 1077,\n 'af-ZA': 1078,\n 'ka-GE': 1079,\n 'fo-FO': 1080,\n 'hi-IN': 1081,\n 'mt-MT': 1082,\n 'se-NO': 1083,\n 'gd-GB': 1084,\n yi: 1085,\n 'ms-MY': 1086,\n 'kk-KZ': 1087,\n 'ky-KG': 1088,\n 'sw-KE': 1089,\n 'tk-TM': 1090,\n 'uz-Latn-UZ': 1091,\n 'tt-RU': 1092,\n 'bn-IN': 1093,\n 'pa-IN': 1094,\n 'gu-IN': 1095,\n 'or-IN': 1096,\n 'ta-IN': 1097,\n 'te-IN': 1098,\n 'kn-IN': 1099,\n 'ml-IN': 1100,\n 'as-IN': 1101,\n 'mr-IN': 1102,\n 'sa-IN': 1103,\n 'mn-MN': 1104,\n 'bo-CN': 1105,\n 'cy-GB': 1106,\n 'km-KH': 1107,\n 'lo-LA': 1108,\n 'my-MM': 1109,\n 'gl-ES': 1110,\n 'kok-IN': 1111,\n mni: 1112,\n 'sd-IN': 1113,\n 'syr-SY': 1114,\n 'si-LK': 1115,\n 'chr-US': 1116,\n 'iu-Cans-CA': 1117,\n 'am-ET': 1118,\n tmz: 1119,\n 'ks-Arab-IN': 1120,\n 'ne-NP': 1121,\n 'fy-NL': 1122,\n 'ps-AF': 1123,\n 'fil-PH': 1124,\n 'dv-MV': 1125,\n 'bin-NG': 1126,\n 'fuv-NG': 1127,\n 'ha-Latn-NG': 1128,\n 'ibb-NG': 1129,\n 'yo-NG': 1130,\n 'quz-BO': 1131,\n 'nso-ZA': 1132,\n 'ig-NG': 1136,\n 'kr-NG': 1137,\n 'gaz-ET': 1138,\n 'ti-ER': 1139,\n 'gn-PY': 1140,\n 'haw-US': 1141,\n la: 1142,\n 'so-SO': 1143,\n 'ii-CN': 1144,\n 'pap-AN': 1145,\n 'ug-Arab-CN': 1152,\n 'mi-NZ': 1153,\n 'ar-IQ': 2049,\n 'zh-CN': 2052,\n 'de-CH': 2055,\n 'en-GB': 2057,\n 'es-MX': 2058,\n 'fr-BE': 2060,\n 'it-CH': 2064,\n 'nl-BE': 2067,\n 'nn-NO': 2068,\n 'pt-PT': 2070,\n 'ro-MD': 2072,\n 'ru-MD': 2073,\n 'sr-Latn-CS': 2074,\n 'sv-FI': 2077,\n 'ur-IN': 2080,\n 'az-Cyrl-AZ': 2092,\n 'ga-IE': 2108,\n 'ms-BN': 2110,\n 'uz-Cyrl-UZ': 2115,\n 'bn-BD': 2117,\n 'pa-PK': 2118,\n 'mn-Mong-CN': 2128,\n 'bo-BT': 2129,\n 'sd-PK': 2137,\n 'tzm-Latn-DZ': 2143,\n 'ks-Deva-IN': 2144,\n 'ne-IN': 2145,\n 'quz-EC': 2155,\n 'ti-ET': 2163,\n 'ar-EG': 3073,\n 'zh-HK': 3076,\n 'de-AT': 3079,\n 'en-AU': 3081,\n 'fr-CA': 3084,\n 'sr-Cyrl-CS': 3098,\n 'ar-LY': 4097,\n 'zh-SG': 4100,\n 'de-LU': 4103,\n 'en-CA': 4105,\n 'fr-CH': 4108,\n 'hr-BA': 4122,\n 'ar-DZ': 5121,\n 'zh-MO': 5124,\n 'de-LI': 5127,\n 'en-NZ': 5129,\n 'fr-LU': 5132,\n 'bs-Latn-BA': 5146,\n 'ar-MO': 6145,\n 'fr-MC': 6156,\n 'ar-TN': 7169,\n 'ar-OM': 8193,\n 'ar-YE': 9217,\n 'en-BZ': 10249,\n 'es-PE': 10250,\n 'fr-SN': 10252,\n 'ar-JO': 11265,\n 'fr-CM': 11276,\n 'en-ID': 14345,\n 'es-CL': 13322,\n 'en-HK': 15369,\n 'fr-MA': 14348,\n 'en-MY': 17417,\n 'es-SV': 17418,\n 'es-NI': 19466,\n 'es-PR': 20490,\n 'es-US': 21514,\n 'fr-015': 58380,\n};\n\nexport function findBestLocaleFromString(value: string): { locale: string; localeId: number } {\n // Attempt to find an exact match in the map\n if (localeToLCIDMap[value]) {\n return {\n locale: value,\n localeId: localeToLCIDMap[value],\n };\n }\n\n // Fallback: Check for a partial match (e.g., \"en\" in \"en-US\")\n const partialMatch = Object.keys(localeToLCIDMap).find((key) => key.startsWith(value.split('-')[0]));\n\n if (partialMatch) {\n return {\n locale: partialMatch,\n localeId: localeToLCIDMap[partialMatch],\n };\n }\n\n // Default result if no match is found\n throw new Error(`Locale '${value}' is not supported.`);\n}\n","import type { UserInfo } from 'matomo-tracker-react-native';\nimport MatomoTracker, { MatomoProvider, useMatomo } from 'matomo-tracker-react-native';\nimport React, { createContext, useContext, useState } from 'react';\n\nexport type AnalyticsEventParams = {\n action: string;\n name?: string;\n category?: string;\n value?: number;\n campaign?: string;\n userInfo?: UserInfo;\n};\n\nexport type AnalyticsPageViewParams = {\n name: string;\n url?: string;\n userInfo?: UserInfo;\n};\n\nexport type AnalyticsContextType = {\n isInitialized: boolean;\n isEnabled: boolean;\n userId?: string;\n presetUserInfo?: UserInfo;\n actions: {\n setEnabled: (enabled: boolean) => void;\n setPresetUserInfo: (userInfo: UserInfo) => void;\n clearPresetUserInfo: () => void;\n trackAppStart: (userInfo?: UserInfo) => Promise<void>;\n trackEvent: (params: AnalyticsEventParams) => Promise<void>;\n trackScreenView: (params: AnalyticsPageViewParams) => Promise<void>;\n trackAction: (params: AnalyticsPageViewParams) => Promise<void>;\n trackSiteSearch: (params: {\n keyword: string;\n category?: string;\n count?: number;\n userInfo?: UserInfo;\n }) => Promise<void>;\n trackLink: (params: { link: string; userInfo?: UserInfo }) => Promise<void>;\n trackDownload: (params: { download: string; userInfo?: UserInfo }) => Promise<void>;\n setUserId: (userId: string | null) => void;\n setCustomDimension: (id: number, value: string) => void;\n reset: () => void;\n };\n};\n\nexport const AnalyticsContext = createContext<AnalyticsContextType>({\n isInitialized: false,\n isEnabled: true,\n actions: {\n setEnabled: () => {},\n setPresetUserInfo: () => {},\n clearPresetUserInfo: () => {},\n trackAppStart: async () => {},\n trackEvent: async () => {},\n trackScreenView: async () => {},\n trackAction: async () => {},\n trackSiteSearch: async () => {},\n trackLink: async () => {},\n trackDownload: async () => {},\n setUserId: () => {},\n setCustomDimension: () => {},\n reset: () => {},\n },\n});\n\nexport function useAnalyticsContext() {\n return useContext(AnalyticsContext);\n}\n\n// Inner component that has access to Matomo\nfunction AnalyticsInner({\n children,\n userId,\n enableLogging,\n}: {\n children: React.ReactNode;\n userId?: string;\n enableLogging?: boolean;\n}) {\n const { trackEvent, trackScreenView, trackAppStart, trackAction, trackSiteSearch, trackLink, trackDownload } =\n useMatomo();\n const [isEnabled, setIsEnabled] = useState(true);\n const [userIdState, setUserIdState] = useState<string | undefined>(userId);\n const [presetUserInfo, setPresetUserInfoState] = useState<UserInfo | undefined>(undefined);\n const [log] = useState(enableLogging || false);\n\n const handleSetEnabled = (enabled: boolean) => {\n setIsEnabled(enabled);\n };\n\n const handleSetPresetUserInfo = (userInfo: UserInfo) => {\n setPresetUserInfoState(userInfo);\n };\n\n const handleClearPresetUserInfo = () => {\n setPresetUserInfoState(undefined);\n };\n\n const handleTrackAppStart = async (userInfo?: UserInfo) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track App Start skipped - not initialized or disabled');\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...userInfo };\n\n await trackAppStart({\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: App start tracked successfully', { userInfo: mergedUserInfo });\n }\n } catch (error) {\n console.error('Analytics: Failed to track app start', error);\n }\n };\n\n const handleTrackEvent = async (params: AnalyticsEventParams) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Event skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackEvent({\n category: params.category || 'User Action',\n action: params.action,\n name: params.name,\n value: params.value,\n campaign: params.campaign,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Event tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track event', error, params);\n }\n };\n\n const handleTrackScreenView = async (params: AnalyticsPageViewParams) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Screen View skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackScreenView({\n name: params.name,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Screen view tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track screen view', error, params);\n }\n };\n\n const handleTrackAction = async (params: AnalyticsPageViewParams) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Action skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackAction({\n name: params.name,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Action tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track action', error, params);\n }\n };\n\n const handleTrackSiteSearch = async (params: {\n keyword: string;\n category?: string;\n count?: number;\n userInfo?: UserInfo;\n }) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Site Search skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackSiteSearch({\n keyword: params.keyword,\n category: params.category,\n count: params.count,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Site search tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track site search', error, params);\n }\n };\n\n const handleTrackLink = async (params: { link: string; userInfo?: UserInfo }) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Link skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackLink({\n link: params.link,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Link tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track link', error, params);\n }\n };\n\n const handleTrackDownload = async (params: { download: string; userInfo?: UserInfo }) => {\n if (!userIdState || !isEnabled) {\n if (log) {\n console.debug('Analytics: Track Download skipped - not initialized or disabled', params);\n }\n return;\n }\n\n try {\n // Merge preset userInfo with provided userInfo\n const mergedUserInfo = { ...presetUserInfo, ...params.userInfo };\n\n await trackDownload({\n download: params.download,\n userInfo: Object.keys(mergedUserInfo).length > 0 ? mergedUserInfo : undefined,\n });\n\n if (log) {\n console.debug('Analytics: Download tracked successfully', params);\n }\n } catch (error) {\n console.error('Analytics: Failed to track download', error, params);\n }\n };\n\n const handleSetUserId = (userId: string | null) => {\n setUserIdState(userId || undefined);\n\n // Update preset userInfo with the new userId\n if (userId) {\n setPresetUserInfoState((prev) => ({\n ...prev,\n uid: userId,\n }));\n } else {\n // Remove uid from preset userInfo if userId is null\n setPresetUserInfoState((prev) => {\n if (prev?.uid) {\n const updatedUserInfo = { ...prev };\n delete updatedUserInfo.uid;\n return Object.keys(updatedUserInfo).length > 0 ? updatedUserInfo : undefined;\n }\n return prev;\n });\n }\n\n if (log) {\n console.debug('Analytics: User ID updated in preset userInfo', userId);\n }\n };\n\n const handleSetCustomDimension = (id: number, value: string) => {\n if (!presetUserInfo) {\n setPresetUserInfoState({ [`dimension${id}`]: value });\n } else {\n setPresetUserInfoState({\n ...presetUserInfo,\n [`dimension${id}`]: value,\n });\n }\n\n if (log) {\n console.debug('Analytics: Custom dimension set in preset userInfo', { id, value });\n }\n };\n\n const reset = () => {\n setUserIdState(undefined);\n setPresetUserInfoState(undefined);\n setIsEnabled(true);\n\n console.debug('Analytics: Provider reset successfully');\n };\n\n const contextValue: AnalyticsContextType = {\n isInitialized: true, // Always true since initialization is handled by MatomoProvider\n isEnabled,\n userId: userIdState,\n presetUserInfo,\n actions: {\n setEnabled: handleSetEnabled,\n setPresetUserInfo: handleSetPresetUserInfo,\n clearPresetUserInfo: handleClearPresetUserInfo,\n trackAppStart: handleTrackAppStart,\n trackEvent: handleTrackEvent,\n trackScreenView: handleTrackScreenView,\n trackAction: handleTrackAction,\n trackSiteSearch: handleTrackSiteSearch,\n trackLink: handleTrackLink,\n trackDownload: handleTrackDownload,\n setUserId: handleSetUserId,\n setCustomDimension: handleSetCustomDimension,\n reset,\n },\n };\n\n return <AnalyticsContext.Provider value={contextValue}>{children}</AnalyticsContext.Provider>;\n}\n\nexport type AnalyticsProviderProps = {\n children: React.ReactNode;\n disabled?: boolean;\n instance?: MatomoTracker;\n userId?: string;\n enableLogging?: boolean;\n};\n\nexport function AnalyticsProvider({\n children,\n disabled = false,\n instance,\n userId,\n enableLogging = false,\n}: AnalyticsProviderProps) {\n // If analytics is disabled, provide a no-op context\n if (disabled) {\n const noOpContextValue: AnalyticsContextType = {\n isInitialized: false,\n isEnabled: false,\n actions: {\n setEnabled: () => {},\n setPresetUserInfo: () => {},\n clearPresetUserInfo: () => {},\n trackAppStart: async () => {},\n trackEvent: async () => {},\n trackScreenView: async () => {},\n trackAction: async () => {},\n trackSiteSearch: async () => {},\n trackLink: async () => {},\n trackDownload: async () => {},\n setUserId: () => {},\n setCustomDimension: () => {},\n reset: () => {},\n },\n };\n\n return <AnalyticsContext.Provider value={noOpContextValue}>{children}</AnalyticsContext.Provider>;\n }\n\n // Use provided instance or create a default placeholder\n const matomoInstance =\n instance ||\n new MatomoTracker({\n urlBase: 'https://placeholder.com',\n siteId: 1,\n disabled: true, // Disabled until properly initialized\n });\n\n return (\n <MatomoProvider instance={matomoInstance}>\n <AnalyticsInner userId={userId} enableLogging={enableLogging}>\n {children}\n </AnalyticsInner>\n </MatomoProvider>\n );\n}\n","import {\n Badge,\n Buzzebees,\n CartCountResponse,\n ConfirmOtpResponse,\n ErrorResponse,\n ExpiringPoints,\n ProfileResponse,\n ServiceResponse,\n StatusResponse,\n Trace,\n UpdatedPoints,\n} from '@bzbs/react-api-client';\nimport React, { ReactNode, createContext, useContext, useEffect, useState } from 'react';\nimport { eventEmitter } from '../service';\nimport { useAuthContext } from './auth_provider';\nimport { useBuzzebeesServiceContext } from './buzzebees_service_provider';\n\ntype UserContextType = {\n user: ProfileResponse | null;\n points: number;\n recentPoints: number;\n expiringPoints: UpdatedPoints[];\n recentBadge: Badge | null;\n recentTrace: Trace | null;\n cartCount: number;\n isLoading: boolean;\n error: ErrorResponse | null;\n actions: {\n fetchUser: () => Promise<ServiceResponse<ProfileResponse>>;\n fetchPoint: () => Promise<ServiceResponse<UpdatedPoints>>;\n fetchExpiringPoints: () => Promise<ServiceResponse<ExpiringPoints>>;\n fetchCartCount: () => Promise<ServiceResponse<CartCountResponse>>;\n editUser: (data: UpdateProfileParams) => Promise<ServiceResponse<ProfileResponse>>;\n changePassword: (oldPassword: string, newPassword: string) => Promise<ServiceResponse<StatusResponse>>;\n changeContactNumber: (\n contactNumber: string,\n otp: string,\n refCode: string\n ) => Promise<ServiceResponse<ConfirmOtpResponse>>;\n changeAvatar: (avatar: File) => Promise<ServiceResponse<ProfileResponse>>;\n consumeRecentPoints: () => void;\n consumeRecentBadge: () => void;\n consumeRecentTrace: () => void;\n deleteUser: () => Promise<ServiceResponse<any>>;\n setError: (error: ErrorResponse | null) => void;\n clearData: () => void;\n };\n};\n\nexport type UpdateProfileParams = {\n profileImage?: File | { uri: string; name: string; type: string };\n firstName?: string;\n lastName?: string;\n contactNumber?: string;\n email?: string;\n notification?: boolean;\n locale?: number;\n title?: string;\n gender?: string;\n birthDate?: number;\n address?: string;\n subdistrictCode?: number;\n subdistrictName?: string;\n districtCode?: number;\n districtName?: string;\n provinceCode?: number;\n provinceName?: string;\n countryCode?: string;\n countryName?: string;\n zipCode?: string;\n idCard?: string;\n passport?: string;\n maritalStatus?: string;\n village?: string;\n building?: string;\n number?: string;\n moo?: string;\n room?: string;\n floor?: string;\n soi?: string;\n city?: string;\n road?: string;\n landmark?: string;\n alternateContactNumber?: string;\n homeContactNumber?: string;\n nationality?: string;\n religion?: string;\n location?: string;\n latitude?: number;\n longitude?: number;\n income?: string;\n interests?: string;\n region?: string;\n phonepurchase?: number;\n highestEducation?: string;\n occupation?: string;\n remark?: string;\n displayName?: string;\n options?: { [key: string]: any };\n};\n\nexport const UserContext = createContext<UserContextType>({\n user: null,\n points: 0,\n expiringPoints: [] as UpdatedPoints[],\n recentPoints: 0,\n recentBadge: null,\n recentTrace: null,\n cartCount: 0,\n isLoading: false,\n error: null,\n actions: {\n fetchUser: async () => ({ type: 'client-error', message: 'Not implemented' }),\n fetchPoint: async () => ({ type: 'client-error', message: 'Not implemented' }),\n fetchExpiringPoints: async () => ({ type: 'client-error', message: 'Not implemented' }),\n fetchCartCount: async () => ({ type: 'client-error', message: 'Not implemented' }),\n editUser: async () => ({ type: 'client-error', message: 'Not implemented' }),\n changePassword: async () => ({ type: 'client-error', message: 'Not implemented' }),\n changeContactNumber: async () => ({ type: 'client-error', message: 'Not implemented' }),\n changeAvatar: async () => ({ type: 'client-error', message: 'Not implemented' }),\n consumeRecentPoints: () => {},\n consumeRecentBadge: () => {},\n consumeRecentTrace: () => {},\n deleteUser: async () => ({ type: 'client-error', message: 'Not implemented' }),\n setError: () => {},\n clearData: () => {},\n } as UserContextType['actions'],\n});\n\nexport function useUserContext() {\n return useContext(UserContext);\n}\n\nexport function UserProvider({ children }: { children: ReactNode }) {\n const [user, setUser] = useState<ProfileResponse | null>(null);\n const [points, setPoints] = useState<number>(0);\n const [expiringPoints, setExpiringPoints] = useState<UpdatedPoints[]>([]);\n const [cartCount, setCartCount] = useState<number>(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<ErrorResponse | null>(null);\n\n const [recentPoints, setRecentPoints] = useState<number>(0);\n const [recentBadge, setRecentBadge] = useState<Badge | null>(null);\n const [badgeList, setBadgeList] = useState<Badge[]>([]);\n const [recentTrace, setRecentTrace] = useState<Trace | null>(null);\n const [traceList, setTraceList] = useState<Trace[]>([]);\n\n const { bzbsService } = useBuzzebeesServiceContext();\n const auth = useAuthContext();\n\n useEffect(() => {\n eventEmitter.on('get_points', (buzzebees: Buzzebees) => {\n console.log('get_points', buzzebees);\n const points = buzzebees.points;\n if (points) {\n setRecentPoints(points);\n }\n\n const traces = buzzebees.traces;\n if (traces) {\n if (traces.length > 0) {\n const first = traces.shift();\n if (first) {\n setRecentTrace(first);\n }\n setTraceList(traces);\n }\n }\n });\n\n eventEmitter.on('get_badges', (badges: Badge[]) => {\n if (badges.length > 0) {\n const first = badges.shift();\n if (first) {\n setRecentBadge(first);\n }\n setBadgeList(badges);\n }\n });\n\n eventEmitter.on('session_expired', () => {\n auth.actions.logout();\n });\n\n return () => {\n console.log('UserProvider cleanup');\n eventEmitter.clearListeners(['get_points', 'get_badges', 'session_expired']);\n };\n }, []);\n\n const fetchUser = async (): Promise<ServiceResponse<ProfileResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.profile();\n setIsLoading(false);\n\n if (response.type === 'success') {\n setUser(response.model);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const fetchPoint = async (): Promise<ServiceResponse<UpdatedPoints>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.points();\n setIsLoading(false);\n\n if (response.type === 'success') {\n setPoints(response.model.points);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const fetchExpiringPoints = async (): Promise<ServiceResponse<ExpiringPoints>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.expiringPoints();\n setIsLoading(false);\n\n if (response.type === 'success') {\n setExpiringPoints(response.model.expiring_points ?? []);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const fetchCartCount = async (): Promise<ServiceResponse<CartCountResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.cartApi.cartCount();\n setIsLoading(false);\n if (response.type === 'success') {\n setCartCount(response.model.cart_count ?? 0);\n } else {\n setError(response);\n setCartCount(0);\n }\n\n return response;\n };\n\n const editUser = async (data: UpdateProfileParams): Promise<ServiceResponse<ProfileResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.updateProfile(data);\n setIsLoading(false);\n\n if (response.type === 'success') {\n setUser(response.model);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const changePassword = async (oldPassword: string, newPassword: string): Promise<ServiceResponse<StatusResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.changePassword({ current: oldPassword, change: newPassword });\n setIsLoading(false);\n\n if (response.type === 'success') {\n setIsLoading(false);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const changeContactNumber = async (\n contactNumber: string,\n otp: string,\n refCode: string\n ): Promise<ServiceResponse<ConfirmOtpResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.changeContactNumber({ contactNumber, otp: otp, refCode });\n setIsLoading(false);\n\n if (response.type === 'success') {\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const changeAvatar = async (avatar: File): Promise<ServiceResponse<ProfileResponse>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.updateProfile({ profileImage: avatar });\n setIsLoading(false);\n\n if (response.type === 'success') {\n setUser(response.model);\n setError(null);\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const consumeRecentPoints = () => {\n setRecentPoints(0);\n };\n\n const consumeRecentBadge = () => {\n setRecentBadge(null);\n const next = badgeList.shift();\n if (next) {\n setRecentBadge(next);\n setBadgeList(badgeList);\n }\n };\n\n const consumeRecentTrace = () => {\n setRecentTrace(null);\n const next = traceList.shift();\n if (next) {\n setRecentTrace(next);\n setTraceList(traceList);\n }\n };\n\n const deleteUser = async (): Promise<ServiceResponse<any>> => {\n setIsLoading(true);\n const response = await bzbsService.profileApi.deactivate();\n setIsLoading(false);\n\n if (response.type === 'success') {\n clearData();\n } else {\n setError(response);\n }\n\n return response;\n };\n\n const clearData = () => {\n setUser(null);\n setPoints(0);\n setExpiringPoints([]);\n setError(null);\n };\n\n return (\n <UserContext.Provider\n value={{\n user,\n points,\n expiringPoints,\n recentPoints,\n recentBadge,\n recentTrace,\n cartCount,\n isLoading,\n error,\n actions: {\n fetchUser,\n fetchPoint,\n fetchExpiringPoints,\n fetchCartCount,\n editUser,\n changePassword,\n changeContactNumber,\n changeAvatar,\n consumeRecentPoints,\n consumeRecentBadge,\n consumeRecentTrace,\n deleteUser,\n setError,\n clearData,\n },\n }}\n >\n {children}\n </UserContext.Provider>\n );\n}\n","import { AxiosInstance } from 'axios';\nimport * as blake from 'blakejs';\nimport Emittery from 'emittery';\nimport { v7 as uuidv7 } from 'uuid';\nimport { TokenFunctions } from '../providers';\n\nconst eventEmitter = new Emittery();\n\nfunction defaultCorelationIdGenerator(): string {\n return uuidv7();\n}\n\nfunction isJWT(token: string): boolean {\n return typeof token === 'string' && token.split('.').length === 3;\n}\n\nfunction addDefaultHeaderInterceptor(\n axiosInstance: AxiosInstance,\n appId: string,\n subscriptionKey: string,\n tokenFunctions: TokenFunctions,\n apiVersion: string,\n corelationIdGenerator: () => string = defaultCorelationIdGenerator\n) {\n axiosInstance.interceptors.request.use(\n async (config) => {\n config.headers.set('App-Id', appId);\n\n if (subscriptionKey) {\n config.headers.set('Ocp-Apim-Subscription-Key', subscriptionKey);\n }\n\n if (apiVersion) {\n config.headers.set('api-version', apiVersion);\n }\n\n config.headers.set('X-Corelation-Id', corelationIdGenerator());\n const token = await tokenFunctions.getToken();\n\n if (token) {\n if (isJWT(token)) {\n config.headers.set('Authorization', `Bearer ${token}`);\n } else {\n config.headers.set('Authorization', `token ${token}`);\n }\n }\n\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n axiosInstance.interceptors.response.use(\n (response) => {\n const responseData = response.data;\n const buzzebeesObj = responseData.buzzebees;\n if (buzzebeesObj) {\n const points = buzzebeesObj.points;\n const badges = buzzebeesObj.badges;\n\n if (typeof points === 'number') {\n eventEmitter.emit('get_points', buzzebeesObj);\n }\n\n if (badges) {\n eventEmitter.emit('get_badges', badges);\n }\n }\n\n if (responseData.error) {\n const id = responseData.error.id;\n const code = responseData.error.code;\n\n if (code === 409 && (id === 1905 || id === 2076)) {\n eventEmitter.emit('session_expired', responseData.error);\n }\n }\n\n return response;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n}\n\nfunction generateShortLivedId(): string {\n return Math.random().toString(36).substring(2, 15);\n}\n\nfunction avatarUrl(baseUrl: string, appId: string, userId: string, token: string | null) {\n const url =\n `${baseUrl}/profile/${userId}/picture?timestamp=${Date.now()}&type=large` +\n `${token === null ? '' : `&token=${token}&device_app_id=${appId}`}`;\n console.log(url);\n return url;\n}\n\nfunction largeImage(url: string) {\n if (!url) return '';\n const result = url.replace('?', '-large?');\n return result;\n}\n\nasync function fetchImage(axiosClient: AxiosInstance, imageUrl: string) {\n try {\n const response = await axiosClient.get(imageUrl, { responseType: 'blob' });\n return response.data;\n } catch (error) {\n console.error('Error fetching image:', error);\n }\n}\n\nfunction createInterfaceWebsiteUrl(\n url: string,\n token?: string,\n returnUrl: string = '',\n params?: { [key: string]: any }\n): string {\n if (token) {\n params = {\n token: createInterfaceToken(token),\n return_url: returnUrl,\n ...params,\n };\n }\n const searchParams = new URLSearchParams(params).toString();\n const result = url.includes('?') ? `${url}&${searchParams}` : `${url}?${searchParams}`;\n return result;\n}\n\nfunction createInterfaceToken(token: string): string {\n if (token.length <= 5) {\n return token;\n }\n\n const firstChar = token.substring(0, 1);\n const last5Chars = token.substring(token.length - 5);\n const remainingChars = token.substring(1, token.length - 5);\n\n return firstChar === '.' ? `${last5Chars}${rem