UNPKG

react-achievements-zustand

Version:

This package allows users to transpose a React achievements engine over their React apps using Zustand for state management

935 lines (892 loc) 59.3 kB
'use strict'; var React = require('react'); const createStoreImpl = (createState) => { let state; const listeners = /* @__PURE__ */ new Set(); const setState = (partial, replace) => { const nextState = typeof partial === "function" ? partial(state) : partial; if (!Object.is(nextState, state)) { const previousState = state; state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState); listeners.forEach((listener) => listener(state, previousState)); } }; const getState = () => state; const getInitialState = () => initialState; const subscribe = (listener) => { listeners.add(listener); return () => listeners.delete(listener); }; const destroy = () => { if ((undefined ? undefined.MODE : void 0) !== "production") { console.warn( "[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected." ); } listeners.clear(); }; const api = { setState, getState, getInitialState, subscribe, destroy }; const initialState = state = createState(setState, getState, api); return api; }; const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var withSelector = {exports: {}}; var withSelector_production = {}; var shim = {exports: {}}; var useSyncExternalStoreShim_production = {}; /** * @license React * use-sync-external-store-shim.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of undefined source tree. */ var hasRequiredUseSyncExternalStoreShim_production; function requireUseSyncExternalStoreShim_production () { if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production; hasRequiredUseSyncExternalStoreShim_production = 1; var React$1 = React; function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } var objectIs = "function" === typeof Object.is ? Object.is : is, useState = React$1.useState, useEffect = React$1.useEffect, useLayoutEffect = React$1.useLayoutEffect, useDebugValue = React$1.useDebugValue; function useSyncExternalStore$2(subscribe, getSnapshot) { var value = getSnapshot(), _useState = useState({ inst: { value: value, getSnapshot: getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1]; useLayoutEffect( function () { inst.value = value; inst.getSnapshot = getSnapshot; checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); }, [subscribe, value, getSnapshot] ); useEffect( function () { checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); return subscribe(function () { checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); }); }, [subscribe] ); useDebugValue(value); return value; } function checkIfSnapshotChanged(inst) { var latestGetSnapshot = inst.getSnapshot; inst = inst.value; try { var nextValue = latestGetSnapshot(); return !objectIs(inst, nextValue); } catch (error) { return true; } } function useSyncExternalStore$1(subscribe, getSnapshot) { return getSnapshot(); } var shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2; useSyncExternalStoreShim_production.useSyncExternalStore = void 0 !== React$1.useSyncExternalStore ? React$1.useSyncExternalStore : shim; return useSyncExternalStoreShim_production; } var useSyncExternalStoreShim_development = {}; /** * @license React * use-sync-external-store-shim.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of undefined source tree. */ var hasRequiredUseSyncExternalStoreShim_development; function requireUseSyncExternalStoreShim_development () { if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development; hasRequiredUseSyncExternalStoreShim_development = 1; "production" !== process.env.NODE_ENV && (function () { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } function useSyncExternalStore$2(subscribe, getSnapshot) { didWarnOld18Alpha || void 0 === React$1.startTransition || ((didWarnOld18Alpha = true), console.error( "You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release." )); var value = getSnapshot(); if (!didWarnUncachedGetSnapshot) { var cachedValue = getSnapshot(); objectIs(value, cachedValue) || (console.error( "The result of getSnapshot should be cached to avoid an infinite loop" ), (didWarnUncachedGetSnapshot = true)); } cachedValue = useState({ inst: { value: value, getSnapshot: getSnapshot } }); var inst = cachedValue[0].inst, forceUpdate = cachedValue[1]; useLayoutEffect( function () { inst.value = value; inst.getSnapshot = getSnapshot; checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); }, [subscribe, value, getSnapshot] ); useEffect( function () { checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); return subscribe(function () { checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst }); }); }, [subscribe] ); useDebugValue(value); return value; } function checkIfSnapshotChanged(inst) { var latestGetSnapshot = inst.getSnapshot; inst = inst.value; try { var nextValue = latestGetSnapshot(); return !objectIs(inst, nextValue); } catch (error) { return true; } } function useSyncExternalStore$1(subscribe, getSnapshot) { return getSnapshot(); } "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); var React$1 = React, objectIs = "function" === typeof Object.is ? Object.is : is, useState = React$1.useState, useEffect = React$1.useEffect, useLayoutEffect = React$1.useLayoutEffect, useDebugValue = React$1.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2; useSyncExternalStoreShim_development.useSyncExternalStore = void 0 !== React$1.useSyncExternalStore ? React$1.useSyncExternalStore : shim; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error()); })(); return useSyncExternalStoreShim_development; } var hasRequiredShim; function requireShim () { if (hasRequiredShim) return shim.exports; hasRequiredShim = 1; if (process.env.NODE_ENV === 'production') { shim.exports = requireUseSyncExternalStoreShim_production(); } else { shim.exports = requireUseSyncExternalStoreShim_development(); } return shim.exports; } /** * @license React * use-sync-external-store-shim/with-selector.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of undefined source tree. */ var hasRequiredWithSelector_production; function requireWithSelector_production () { if (hasRequiredWithSelector_production) return withSelector_production; hasRequiredWithSelector_production = 1; var React$1 = React, shim = requireShim(); function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } var objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim.useSyncExternalStore, useRef = React$1.useRef, useEffect = React$1.useEffect, useMemo = React$1.useMemo, useDebugValue = React$1.useDebugValue; withSelector_production.useSyncExternalStoreWithSelector = function ( subscribe, getSnapshot, getServerSnapshot, selector, isEqual ) { var instRef = useRef(null); if (null === instRef.current) { var inst = { hasValue: false, value: null }; instRef.current = inst; } else inst = instRef.current; instRef = useMemo( function () { function memoizedSelector(nextSnapshot) { if (!hasMemo) { hasMemo = true; memoizedSnapshot = nextSnapshot; nextSnapshot = selector(nextSnapshot); if (void 0 !== isEqual && inst.hasValue) { var currentSelection = inst.value; if (isEqual(currentSelection, nextSnapshot)) return (memoizedSelection = currentSelection); } return (memoizedSelection = nextSnapshot); } currentSelection = memoizedSelection; if (objectIs(memoizedSnapshot, nextSnapshot)) return currentSelection; var nextSelection = selector(nextSnapshot); if (void 0 !== isEqual && isEqual(currentSelection, nextSelection)) return (memoizedSnapshot = nextSnapshot), currentSelection; memoizedSnapshot = nextSnapshot; return (memoizedSelection = nextSelection); } var hasMemo = false, memoizedSnapshot, memoizedSelection, maybeGetServerSnapshot = void 0 === getServerSnapshot ? null : getServerSnapshot; return [ function () { return memoizedSelector(getSnapshot()); }, null === maybeGetServerSnapshot ? void 0 : function () { return memoizedSelector(maybeGetServerSnapshot()); } ]; }, [getSnapshot, getServerSnapshot, selector, isEqual] ); var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]); useEffect( function () { inst.hasValue = true; inst.value = value; }, [value] ); useDebugValue(value); return value; }; return withSelector_production; } var withSelector_development = {}; /** * @license React * use-sync-external-store-shim/with-selector.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of undefined source tree. */ var hasRequiredWithSelector_development; function requireWithSelector_development () { if (hasRequiredWithSelector_development) return withSelector_development; hasRequiredWithSelector_development = 1; "production" !== process.env.NODE_ENV && (function () { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error()); var React$1 = React, shim = requireShim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim.useSyncExternalStore, useRef = React$1.useRef, useEffect = React$1.useEffect, useMemo = React$1.useMemo, useDebugValue = React$1.useDebugValue; withSelector_development.useSyncExternalStoreWithSelector = function ( subscribe, getSnapshot, getServerSnapshot, selector, isEqual ) { var instRef = useRef(null); if (null === instRef.current) { var inst = { hasValue: false, value: null }; instRef.current = inst; } else inst = instRef.current; instRef = useMemo( function () { function memoizedSelector(nextSnapshot) { if (!hasMemo) { hasMemo = true; memoizedSnapshot = nextSnapshot; nextSnapshot = selector(nextSnapshot); if (void 0 !== isEqual && inst.hasValue) { var currentSelection = inst.value; if (isEqual(currentSelection, nextSnapshot)) return (memoizedSelection = currentSelection); } return (memoizedSelection = nextSnapshot); } currentSelection = memoizedSelection; if (objectIs(memoizedSnapshot, nextSnapshot)) return currentSelection; var nextSelection = selector(nextSnapshot); if (void 0 !== isEqual && isEqual(currentSelection, nextSelection)) return (memoizedSnapshot = nextSnapshot), currentSelection; memoizedSnapshot = nextSnapshot; return (memoizedSelection = nextSelection); } var hasMemo = false, memoizedSnapshot, memoizedSelection, maybeGetServerSnapshot = void 0 === getServerSnapshot ? null : getServerSnapshot; return [ function () { return memoizedSelector(getSnapshot()); }, null === maybeGetServerSnapshot ? void 0 : function () { return memoizedSelector(maybeGetServerSnapshot()); } ]; }, [getSnapshot, getServerSnapshot, selector, isEqual] ); var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]); useEffect( function () { inst.hasValue = true; inst.value = value; }, [value] ); useDebugValue(value); return value; }; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error()); })(); return withSelector_development; } if (process.env.NODE_ENV === 'production') { withSelector.exports = requireWithSelector_production(); } else { withSelector.exports = requireWithSelector_development(); } var withSelectorExports = withSelector.exports; var useSyncExternalStoreExports = /*@__PURE__*/getDefaultExportFromCjs(withSelectorExports); const { useDebugValue } = React; const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports; let didWarnAboutEqualityFn = false; const identity = (arg) => arg; function useStore(api, selector = identity, equalityFn) { if ((undefined ? undefined.MODE : void 0) !== "production" && equalityFn && !didWarnAboutEqualityFn) { console.warn( "[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937" ); didWarnAboutEqualityFn = true; } const slice = useSyncExternalStoreWithSelector( api.subscribe, api.getState, api.getServerState || api.getInitialState, selector, equalityFn ); useDebugValue(slice); return slice; } const createImpl = (createState) => { if ((undefined ? undefined.MODE : void 0) !== "production" && typeof createState !== "function") { console.warn( "[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`." ); } const api = typeof createState === "function" ? createStore(createState) : createState; const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn); Object.assign(useBoundStore, api); return useBoundStore; }; const create = (createState) => createState ? createImpl(createState) : createImpl; const useAchievementStore = create((set, get) => ({ isInitialized: false, config: {}, metrics: {}, unlockedAchievements: [], previouslyAwardedAchievements: [], storageKey: null, notifications: [], initialize: ({ config, initialState, storageKey }) => { var _a, _b, _c; const state = get(); if (state.isInitialized) return; const storedState = storageKey ? localStorage.getItem(storageKey) : null; const initialMetrics = initialState ? Object.keys(initialState) .filter(key => key !== 'previouslyAwardedAchievements') .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: Array.isArray(initialState[key]) ? initialState[key] : [initialState[key]] })), {}) : {}; const initialAwarded = (initialState === null || initialState === void 0 ? void 0 : initialState.previouslyAwardedAchievements) || []; if (storedState) { try { const parsedState = JSON.parse(storedState); set({ isInitialized: true, config, storageKey, metrics: ((_a = parsedState.achievements) === null || _a === void 0 ? void 0 : _a.metrics) || initialMetrics, unlockedAchievements: ((_b = parsedState.achievements) === null || _b === void 0 ? void 0 : _b.unlockedAchievements) || [], previouslyAwardedAchievements: ((_c = parsedState.achievements) === null || _c === void 0 ? void 0 : _c.previouslyAwardedAchievements) || initialAwarded, }); } catch (error) { console.error('Error parsing stored achievement state:', error); set({ isInitialized: true, config, storageKey, metrics: initialMetrics, unlockedAchievements: [], previouslyAwardedAchievements: initialAwarded, }); } } else { set({ isInitialized: true, config, storageKey, metrics: initialMetrics, unlockedAchievements: [], previouslyAwardedAchievements: initialAwarded, }); } }, setMetrics: (metrics) => { const state = get(); set({ metrics }); if (state.storageKey) { localStorage.setItem(state.storageKey, JSON.stringify({ achievements: { metrics, unlockedAchievements: state.unlockedAchievements, previouslyAwardedAchievements: state.previouslyAwardedAchievements } })); } }, unlockAchievement: (achievementId) => { const state = get(); if (!state.unlockedAchievements.includes(achievementId)) { const newUnlockedAchievements = [...state.unlockedAchievements, achievementId]; set({ unlockedAchievements: newUnlockedAchievements }); if (state.storageKey) { localStorage.setItem(state.storageKey, JSON.stringify({ achievements: { metrics: state.metrics, unlockedAchievements: newUnlockedAchievements, previouslyAwardedAchievements: state.previouslyAwardedAchievements } })); } } }, markAchievementAsAwarded: (achievementId) => { const state = get(); if (!state.previouslyAwardedAchievements.includes(achievementId)) { const newAwardedAchievements = [...state.previouslyAwardedAchievements, achievementId]; set({ previouslyAwardedAchievements: newAwardedAchievements }); if (state.storageKey) { localStorage.setItem(state.storageKey, JSON.stringify({ achievements: { metrics: state.metrics, unlockedAchievements: state.unlockedAchievements, previouslyAwardedAchievements: newAwardedAchievements } })); } } }, resetAchievements: () => { const state = get(); set({ metrics: {}, unlockedAchievements: [], previouslyAwardedAchievements: [], }); if (state.storageKey) { localStorage.removeItem(state.storageKey); } }, addNotification: (notification) => { const state = get(); set({ notifications: [...state.notifications, notification] }); }, clearNotifications: () => { set({ notifications: [] }); }, })); // src/defaultIcons.ts const defaultAchievementIcons = { // General Progress & Milestones levelUp: '🏆', questComplete: '📜', monsterDefeated: '⚔️', itemCollected: '📦', challengeCompleted: '🏁', milestoneReached: '🏅', firstStep: '👣', newBeginnings: '🌱', breakthrough: '💡', growth: '📈', // Social & Engagement shared: '🔗', liked: '❤️', commented: '💬', followed: '👥', invited: '🤝', communityMember: '🏘️', supporter: '🌟', connected: '🌐', participant: '🙋', influencer: '📣', // Time & Activity activeDay: '☀️', activeWeek: '📅', activeMonth: '🗓️', earlyBird: '⏰', nightOwl: '🌙', streak: '🔥', dedicated: '⏳', punctual: '⏱️', consistent: '🔄', marathon: '🏃', // Creativity & Skill artist: '🎨', writer: '✍️', innovator: '🔬', creator: '🛠️', expert: '🎓', master: '👑', pioneer: '🚀', performer: '🎭', thinker: '🧠', explorer: '🗺️', // Achievement Types bronze: '🥉', silver: '🥈', gold: '🥇', diamond: '💎', legendary: '✨', epic: '💥', rare: '🔮', common: '🔘', special: '🎁', hidden: '❓', // Numbers & Counters one: '1️⃣', ten: '🔟', hundred: '💯', thousand: '🔢', // Actions & Interactions clicked: '🖱️', used: '🔑', found: '🔍', built: '🧱', solved: '🧩', discovered: '🔭', unlocked: '🔓', upgraded: '⬆️', repaired: '🔧', defended: '🛡️', // Placeholders default: '⭐', // A fallback icon loading: '⏳', error: '⚠️', success: '✅', failure: '❌', // Miscellaneous trophy: '🏆', star: '⭐', flag: '🚩', puzzle: '🧩', gem: '💎', crown: '👑', medal: '🏅', ribbon: '🎗️', badge: '🎖️', shield: '🛡️', }; const AchievementModal = ({ isOpen, achievement, onClose, styles, icons = {} }) => { if (!isOpen || !achievement) return null; const mergedIcons = Object.assign(Object.assign({}, defaultAchievementIcons), icons); const iconToDisplay = (achievement === null || achievement === void 0 ? void 0 : achievement.achievementIconKey) ? (mergedIcons[achievement.achievementIconKey] || mergedIcons.default) : mergedIcons.default; return (React.createElement("div", { style: Object.assign(Object.assign({}, styles.overlay), { display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)' }) }, React.createElement("div", { style: Object.assign(Object.assign({}, styles.content), { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }) }, React.createElement("h2", { style: styles.title }, "Achievement Unlocked!"), iconToDisplay.startsWith('http') || iconToDisplay.startsWith('data:image') ? (React.createElement("img", { src: iconToDisplay, alt: achievement.achievementTitle, style: styles.icon })) : (React.createElement("p", { style: { fontSize: '3em' } }, iconToDisplay)), React.createElement("h3", { style: styles.title }, achievement.achievementTitle), React.createElement("p", { style: styles.description }, achievement.achievementDescription), React.createElement("button", { onClick: onClose, style: styles.button }, "Okay")))); }; var AchievementModal$1 = React.memo(AchievementModal); const BadgesButton = ({ onClick, position, styles, unlockedAchievements, icon, drawer = false, customStyles, }) => { const positionStyle = position ? { [position.split('-')[0]]: '20px', [position.split('-')[1]]: '20px', } : {}; const handleButtonClick = () => { onClick(); }; const achievementsText = 'View Achievements'; const buttonContent = icon ? icon : achievementsText; return (React.createElement("button", { onClick: handleButtonClick, style: Object.assign(Object.assign(Object.assign({}, styles), positionStyle), customStyles) }, buttonContent)); }; var BadgesButton$1 = React.memo(BadgesButton); const BadgesModal = ({ isOpen, achievements, onClose, styles, icons = {} }) => { if (!isOpen) return null; return (React.createElement("div", { style: styles.overlay }, React.createElement("div", { style: styles.content }, React.createElement("h2", { style: styles.title }, "Your Achievements"), React.createElement("div", { style: styles.badgeContainer }, achievements.map((achievement) => { const mergedIcons = Object.assign(Object.assign({}, defaultAchievementIcons), icons); let iconToDisplay = mergedIcons.default; if (achievement.achievementIconKey && mergedIcons[achievement.achievementIconKey]) { iconToDisplay = mergedIcons[achievement.achievementIconKey]; } return (React.createElement("div", { key: achievement.achievementId, style: styles.badge }, iconToDisplay.startsWith('http') || iconToDisplay.startsWith('data:image') ? (React.createElement("img", { src: iconToDisplay, alt: achievement.achievementTitle, style: styles.badgeIcon })) : (React.createElement("p", { style: { fontSize: '2em' } }, iconToDisplay) // Render Unicode as large text ), React.createElement("span", { style: styles.badgeTitle }, achievement.achievementTitle))); })), React.createElement("button", { onClick: onClose, style: styles.button }, "Close")))); }; var BadgesModal$1 = React.memo(BadgesModal); var reactConfetti_min = {exports: {}}; (function (module, exports) { !function(t,e){module.exports=e(React);}("undefined"!=typeof self?self:undefined,(function(t){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:false,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=true,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:true,get:r});},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:true});},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:true,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=2)}([function(e,n){e.exports=t;},function(t,e,n){var r={linear:function(t,e,n,r){return (n-e)*t/r+e},easeInQuad:function(t,e,n,r){return (n-e)*(t/=r)*t+e},easeOutQuad:function(t,e,n,r){return -(n-e)*(t/=r)*(t-2)+e},easeInOutQuad:function(t,e,n,r){var i=n-e;return (t/=r/2)<1?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,n,r){return (n-e)*(t/=r)*t*t+e},easeOutCubic:function(t,e,n,r){return (n-e)*((t=t/r-1)*t*t+1)+e},easeInOutCubic:function(t,e,n,r){var i=n-e;return (t/=r/2)<1?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e},easeInQuart:function(t,e,n,r){return (n-e)*(t/=r)*t*t*t+e},easeOutQuart:function(t,e,n,r){return -(n-e)*((t=t/r-1)*t*t*t-1)+e},easeInOutQuart:function(t,e,n,r){var i=n-e;return (t/=r/2)<1?i/2*t*t*t*t+e:-i/2*((t-=2)*t*t*t-2)+e},easeInQuint:function(t,e,n,r){return (n-e)*(t/=r)*t*t*t*t+e},easeOutQuint:function(t,e,n,r){return (n-e)*((t=t/r-1)*t*t*t*t+1)+e},easeInOutQuint:function(t,e,n,r){var i=n-e;return (t/=r/2)<1?i/2*t*t*t*t*t+e:i/2*((t-=2)*t*t*t*t+2)+e},easeInSine:function(t,e,n,r){var i=n-e;return -i*Math.cos(t/r*(Math.PI/2))+i+e},easeOutSine:function(t,e,n,r){return (n-e)*Math.sin(t/r*(Math.PI/2))+e},easeInOutSine:function(t,e,n,r){return -(n-e)/2*(Math.cos(Math.PI*t/r)-1)+e},easeInExpo:function(t,e,n,r){return 0==t?e:(n-e)*Math.pow(2,10*(t/r-1))+e},easeOutExpo:function(t,e,n,r){var i=n-e;return t==r?e+i:i*(1-Math.pow(2,-10*t/r))+e},easeInOutExpo:function(t,e,n,r){var i=n-e;return 0===t?e:t===r?e+i:(t/=r/2)<1?i/2*Math.pow(2,10*(t-1))+e:i/2*(2-Math.pow(2,-10*--t))+e},easeInCirc:function(t,e,n,r){return -(n-e)*(Math.sqrt(1-(t/=r)*t)-1)+e},easeOutCirc:function(t,e,n,r){return (n-e)*Math.sqrt(1-(t=t/r-1)*t)+e},easeInOutCirc:function(t,e,n,r){var i=n-e;return (t/=r/2)<1?-i/2*(Math.sqrt(1-t*t)-1)+e:i/2*(Math.sqrt(1-(t-=2)*t)+1)+e},easeInElastic:function(t,e,n,r){var i,o,a,c=n-e;return a=1.70158,0===t?e:1==(t/=r)?e+c:((o=0)||(o=.3*r),(i=c)<Math.abs(c)?(i=c,a=o/4):a=o/(2*Math.PI)*Math.asin(c/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t*r-a)*(2*Math.PI)/o)+e)},easeOutElastic:function(t,e,n,r){var i,o,a,c=n-e;return a=1.70158,0===t?e:1==(t/=r)?e+c:((o=0)||(o=.3*r),(i=c)<Math.abs(c)?(i=c,a=o/4):a=o/(2*Math.PI)*Math.asin(c/i),i*Math.pow(2,-10*t)*Math.sin((t*r-a)*(2*Math.PI)/o)+c+e)},easeInOutElastic:function(t,e,n,r){var i,o,a,c=n-e;return a=1.70158,0===t?e:2==(t/=r/2)?e+c:((o=0)||(o=r*(.3*1.5)),(i=c)<Math.abs(c)?(i=c,a=o/4):a=o/(2*Math.PI)*Math.asin(c/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t*r-a)*(2*Math.PI)/o)*-0.5+e:i*Math.pow(2,-10*(t-=1))*Math.sin((t*r-a)*(2*Math.PI)/o)*.5+c+e)},easeInBack:function(t,e,n,r,i){return void 0===i&&(i=1.70158),(n-e)*(t/=r)*t*((i+1)*t-i)+e},easeOutBack:function(t,e,n,r,i){return void 0===i&&(i=1.70158),(n-e)*((t=t/r-1)*t*((i+1)*t+i)+1)+e},easeInOutBack:function(t,e,n,r,i){var o=n-e;return void 0===i&&(i=1.70158),(t/=r/2)<1?o/2*(t*t*((1+(i*=1.525))*t-i))+e:o/2*((t-=2)*t*((1+(i*=1.525))*t+i)+2)+e},easeInBounce:function(t,e,n,i){var o=n-e;return o-r.easeOutBounce(i-t,0,o,i)+e},easeOutBounce:function(t,e,n,r){var i=n-e;return (t/=r)<1/2.75?i*(7.5625*t*t)+e:t<2/2.75?i*(7.5625*(t-=1.5/2.75)*t+.75)+e:t<2.5/2.75?i*(7.5625*(t-=2.25/2.75)*t+.9375)+e:i*(7.5625*(t-=2.625/2.75)*t+.984375)+e},easeInOutBounce:function(t,e,n,i){var o=n-e;return t<i/2?.5*r.easeInBounce(2*t,0,o,i)+e:.5*r.easeOutBounce(2*t-i,0,o,i)+.5*o+e}};t.exports=r;},function(t,e,n){t.exports=n(3);},function(t,e,n){n.r(e),n.d(e,"ReactConfetti",(function(){return Q}));var r,i,o=n(0),a=n.n(o),c=n(1),s=n.n(c);function u(t,e){return t+Math.random()*(e-t)}function f(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||false,r.configurable=true,"value"in r&&(r.writable=true),Object.defineProperty(t,r.key,r);}}function h(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:true,configurable:true,writable:true}):t[e]=n,t}!function(t){t[t.Circle=0]="Circle",t[t.Square=1]="Square",t[t.Strip=2]="Strip";}(r||(r={})),function(t){t[t.Positive=1]="Positive",t[t.Negative=-1]="Negative";}(i||(i={}));var l=function(){function t(e,n,r,o){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(undefined,t),h(undefined,"context",void 0),h(undefined,"radius",void 0),h(undefined,"x",void 0),h(undefined,"y",void 0),h(undefined,"w",void 0),h(undefined,"h",void 0),h(undefined,"vx",void 0),h(undefined,"vy",void 0),h(undefined,"shape",void 0),h(undefined,"angle",void 0),h(undefined,"angularSpin",void 0),h(undefined,"color",void 0),h(undefined,"rotateY",void 0),h(undefined,"rotationDirection",void 0),h(undefined,"getOptions",void 0),this.getOptions=n;var a,c,s=this.getOptions(),f=s.colors,l=s.initialVelocityX,p=s.initialVelocityY;this.context=e,this.x=r,this.y=o,this.w=u(5,20),this.h=u(5,20),this.radius=u(5,10),this.vx="number"==typeof l?u(-l,l):u(l.min,l.max),this.vy="number"==typeof p?u(-p,0):u(p.min,p.max),this.shape=(a=0,c=2,Math.floor(a+Math.random()*(c-a+1))),this.angle=u(0,360)*Math.PI/180,this.angularSpin=u(-0.2,.2),this.color=f[Math.floor(Math.random()*f.length)],this.rotateY=u(0,1),this.rotationDirection=u(0,1)?i.Positive:i.Negative;}var e,n;return e=t,(n=[{key:"update",value:function(){var t=this.getOptions(),e=t.gravity,n=t.wind,o=t.friction,a=t.opacity,c=t.drawShape;this.x+=this.vx,this.y+=this.vy,this.vy+=e,this.vx+=n,this.vx*=o,this.vy*=o,this.rotateY>=1&&this.rotationDirection===i.Positive?this.rotationDirection=i.Negative:this.rotateY<=-1&&this.rotationDirection===i.Negative&&(this.rotationDirection=i.Positive);var s=.1*this.rotationDirection;if(this.rotateY+=s,this.angle+=this.angularSpin,this.context.save(),this.context.translate(this.x,this.y),this.context.rotate(this.angle),this.context.scale(1,this.rotateY),this.context.rotate(this.angle),this.context.beginPath(),this.context.fillStyle=this.color,this.context.strokeStyle=this.color,this.context.globalAlpha=a,this.context.lineCap="round",this.context.lineWidth=2,c&&"function"==typeof c)c.call(undefined,this.context);else switch(this.shape){case r.Circle:this.context.beginPath(),this.context.arc(0,0,this.radius,0,2*Math.PI),this.context.fill();break;case r.Square:this.context.fillRect(-this.w/2,-this.h/2,this.w,this.h);break;case r.Strip:this.context.fillRect(-this.w/6,-this.h/2,this.w/3,this.h);}this.context.closePath(),this.context.restore();}}])&&f(e.prototype,n),t}();function p(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:true,configurable:true,writable:true}):t[e]=n,t}var v=function t(e,n){var r=undefined;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(undefined,t),p(undefined,"canvas",void 0),p(undefined,"context",void 0),p(undefined,"getOptions",void 0),p(undefined,"x",0),p(undefined,"y",0),p(undefined,"w",0),p(undefined,"h",0),p(undefined,"lastNumberOfPieces",0),p(undefined,"tweenInitTime",Date.now()),p(undefined,"particles",[]),p(undefined,"particlesGenerated",0),p(undefined,"removeParticleAt",(function(t){r.particles.splice(t,1);})),p(undefined,"getParticle",(function(){var t=u(r.x,r.w+r.x),e=u(r.y,r.h+r.y);return new l(r.context,r.getOptions,t,e)})),p(undefined,"animate",(function(){var t=r.canvas,e=r.context,n=r.particlesGenerated,i=r.lastNumberOfPieces,o=r.getOptions(),a=o.run,c=o.recycle,s=o.numberOfPieces,u=o.debug,f=o.tweenFunction,h=o.tweenDuration;if(!a)return false;var l=r.particles.length,p=c?l:n,v=Date.now();if(p<s){i!==s&&(r.tweenInitTime=v,r.lastNumberOfPieces=s);for(var y=r.tweenInitTime,d=f(v-y>h?h:Math.max(0,v-y),p,s,h),b=Math.round(d-p),g=0;g<b;g++)r.particles.push(r.getParticle());r.particlesGenerated+=b;}return u&&(e.font="12px sans-serif",e.fillStyle="#333",e.textAlign="right",e.fillText("Particles: ".concat(l),t.width-10,t.height-20)),r.particles.forEach((function(e,n){e.update(),(e.y>t.height||e.y<-100||e.x>t.width+100||e.x<-100)&&(c&&p<=s?r.particles[n]=r.getParticle():r.removeParticleAt(n));})),l>0||p<s})),this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.getOptions=n;};function y(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r);}return n}function d(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?y(Object(n),true).forEach((function(e){g(t,e,n[e]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):y(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e));}));}return t}function b(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||false,r.configurable=true,"value"in r&&(r.writable=true),Object.defineProperty(t,r.key,r);}}function g(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:true,configurable:true,writable:true}):t[e]=n,t}var O={width:"undefined"!=typeof window?window.innerWidth:300,height:"undefined"!=typeof window?window.innerHeight:200,numberOfPieces:200,friction:.99,wind:0,gravity:.1,initialVelocityX:4,initialVelocityY:10,colors:["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548"],opacity:1,debug:false,tweenFunction:s.a.easeInOutQuad,tweenDuration:5e3,recycle:true,run:true},w=function(){function t(e,n){var r=undefined;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(undefined,t),g(undefined,"canvas",void 0),g(undefined,"context",void 0),g(undefined,"_options",void 0),g(undefined,"generator",void 0),g(undefined,"rafId",void 0),g(undefined,"setOptionsWithDefaults",(function(t){var e={confettiSource:{x:0,y:0,w:r.canvas.width,h:0}};r._options=d(d(d({},e),O),t),Object.assign(r,t.confettiSource);})),g(undefined,"update",(function(){var t=r.options;t.run;t.onConfettiComplete;r.canvas;r.context;r.generator.animate()?r.rafId=requestAnimationFrame(r.update):(r._options.run=false);})),g(undefined,"reset",(function(){r.generator;})),g(undefined,"stop",(function(){r.options={run:false},r.rafId;})),this.canvas=e;var i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get canvas context");this.context=i,this.generator=new v(this.canvas,(function(){return r.options})),this.options=n,this.update();}var e,n;return e=t,(n=[{key:"options",get:function(){return this._options},set:function(t){var e=this._options&&this._options.run,n=this._options&&this._options.recycle;this.setOptionsWithDefaults(t),this.generator&&(Object.assign(this.generator,this.options.confettiSource),"boolean"==typeof t.recycle&&t.recycle&&false===n&&(this.generator.lastNumberOfPieces=this.generator.particles.length)),"boolean"==typeof t.run&&t.run&&false===e&&this.update();}}])&&b(e.prototype,n),t}();function m(t){return function(t){if(Array.isArray(t))return C(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||S(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function x(t){return (x="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function P(){return (P=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r]);}return t}).apply(undefined,arguments)}function j(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r);}return n}function M(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?j(Object(n),true).forEach((function(e){T(t,e,n[e]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):j(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e));}));}return t}function I(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var n=[],r=true,i=false,o=void 0;try{for(var a,c=t[Symbol.iterator]();!(r=(a=c.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=true,o=t;}finally{try{r||null==c.return||c.return();}finally{if(i)throw o}}return n}(t,e)||S(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function S(t,e){if(t){if("string"==typeof t)return C(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return "Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?C(t,e):void 0}}function C(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function D(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function E(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||false,r.configurable=true,"value"in r&&(r.writable=true),Object.defineProperty(t,r.key,r);}}function _(t,e){return (_=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function R(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if("function"==typeof Proxy)return true;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return false}}();return function(){var n,r=F(t);if(e){var i=F(undefined).constructor;n=Reflect.construct(r,arguments,i);}else n=r.apply(undefined,arguments);return k(undefined,n)}}function k(t,e){return !e||"object"!==x(e)&&"function"!=typeof e?A(t):e}function A(t){if(void 0===t)throw new ReferenceError("undefined hasn't been initialised - super() hasn't been called");return t}function F(t){return (F=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function T(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:true,configurable:true,writable:true}):t[e]=n,t}var B=a.a.createRef(),N=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:true,configurable:true}}),e&&_(t,e);}(o,t);var e,n,i=R(o);function o(t){var e;D(undefined,o);for(var n=arguments.length,r=new Array(n>1?n-1:0),c=1;c<n;c++)r[c-1]=arguments[c];return T(A(e=i.call.apply(i,[undefined,t].concat(r))),"canvas",a.a.createRef()),T(A(e),"confetti",void 0),e.canvas=t.canvasRef||B,e}return e=o,(n=[{key:"componentDidMount",value:function(){if(this.canvas.current){var t=q(this.props)[0];this.confetti=new w(this.canvas.current,t);}}},{key:"componentDidUpdate",value:function(){var t=q(this.props)[0];this.confetti&&(this.confetti.options=t);}},{key:"componentWillUnmount",value:function(){this.confetti&&this.confetti.stop(),this.confetti=void 0;}},{key:"render",value:function(){var t=I(q(this.props),2),e=t[0],n=t[1],r=M({zIndex:2,position:"absolute",pointerEvents:"none",top:0,left:0,bottom:0,right:0},n.style);return a.a.createElement("canvas",P({width:e.width,height:e.height,ref:this.canvas},n,{style:r}))}}])&&E(e.prototype,n),o}(o.Component);function q(t){var e={},n={},r=[].concat(m(Object.keys(O)),["confettiSource","drawShape","onConfettiComplete"]),i=["canvasRef"];for(var o in t){var a=t[o];r.includes(o)?e[o]=a:i.includes(o)?i[o]=a:n[o]=a;}return [e,n,{}]}T(N,"defaultProps",M({},O)),T(N,"displayName","ReactConfetti");var Q=a.a.forwardRef((function(t,e){return a.a.createElement(N,P({canvasRef:e},t))}));e.default=Q;}]).default})); } (reactConfetti_min)); var reactConfetti_minExports = reactConfetti_min.exports; var Confetti = /*@__PURE__*/getDefaultExportFromCjs(reactConfetti_minExports); function on(obj) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (obj && obj.addEventListener) { obj.addEventListener.apply(obj, args); } } function off(obj) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (obj && obj.removeEventListener) { obj.removeEventListener.apply(obj, args); } } var isBrowser = typeof window !== 'undefined'; var useEffectOnce = function (effect) { React.useEffect(effect, []); }; var useUnmount = function (fn) { var fnRef = React.useRef(fn); // update the ref each render so if it change the newest callback will be invoked fnRef.current = fn; useEffectOnce(function () { return function () { return fnRef.current(); }; }); }; var useRafState = function (initialState) { var frame = React.useRef(0); var _a = React.useState(initialState), state = _a[0], setState = _a[1]; var setRafState = React.useCallback(function (value) { cancelAnimationFrame(frame.current); frame.current = requestAnimationFrame(function () { setState(value); }); }, []); useUnmount(function () { cancelAnimationFrame(frame.current); }); return [state, setRafState]; }; var useWindowSize = function (initialWidth, initialHeight) { if (initialWidth === void 0) { initialWidth = Infinity; } if (initialHeight === void 0) { initialHeight = Infinity; } var _a = useRafState({ width: isBrowser ? window.innerWidth : initialWidth, height: isBrowser ? window.innerHeight : initialHeight, }), state = _a[0], setState = _a[1]; React.useEffect(function () { if (isBrowser) { var handler_1 = function () { setState({ width: window.innerWidth, height: window.innerHeight, }); }; on(window, 'resize', handler_1); return function () { off(window, 'resize', handler_1); }; } }, []); return state; }; const ConfettiWrapper = ({ show }) => { const { width, height } = useWindowSize(); if (!show) return null; return React.createElement(Confetti, { width: width, height: height, recycle: false }); }; const defaultStyles = { achievementModal: { overlay: { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', }, content: { backgroundColor: '#ffffff', borderRadius: '8px', padding: '20px', maxWidth: '400px', width: '100%', }, title: { fontSize: '24px', fontWeight: 'bold', marginBottom: '10px', }, icon: { width: '50px', height: '50px', marginBottom: '10px', }, description: { fontSize: '16px', marginBottom: '20px', }, button: { backgroundColor: '#007bff', color: '#ffffff', padding: '10px 20px', borderRadius: '4px', border: 'none', cursor: 'pointer', }, }, badgesModal: { overlay: { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', }, content: { backgroundColor: '#ffffff', borderRadius: '8px', padding: '20px', maxWidth: '600px', width: '100%', maxHeight: '80vh', overflowY: 'auto', }, title: { fontSize: '24px', fontWeight: 'bold', marginBottom: '20px', }, badgeContainer: { display: 'flex', flexWrap: 'wrap', justifyContent: 'center', }, badge: { display: 'flex', flexDirection: 'column', alignItems: 'center', margin: '10px', }, badgeIcon: { width: '50px', height: '50px', marginBottom: '5px', }, badgeTitle: { fontSize: '14px', textAlign: 'center', }, button: { backgroundColor: '#007bff', color: '#ffffff', padding: '10px 20px', borderRadius: '4px', border: 'none', cursor: 'pointer', marginTop: '20px', }, }, badgesButton: { position: 'fixed', padding: '10px 20px', backgroundColor: '#007bff', color: '#ffffff', border: 'none', borderRadius: '4px', cur