@dashadmin/dash-admin 1.3.16 → 1.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/dist/AppAsyncWrapper.js +1 -0
  2. package/dist/AppWrapper.js +1 -0
  3. package/dist/DASHAdmin.js +1 -0
  4. package/dist/DASHAdmin.tsx.old +456 -0
  5. package/dist/RoutingWrapper.js +1 -0
  6. package/dist/classes/DASHStorageClass.js +1 -0
  7. package/dist/components/Input/RichTextField.js +1 -0
  8. package/dist/components/Redirect.js +1 -0
  9. package/dist/components/avatar/Avatar.js +1 -0
  10. package/dist/components/avatar/SingleImageUploader.js +1 -0
  11. package/dist/components/currency/Format.js +1 -0
  12. package/dist/components/custom/Redirect.js +1 -0
  13. package/dist/components/error/Error.js +1 -0
  14. package/dist/components/geocoding/GeocodingField.js +1 -0
  15. package/dist/components/i18n/BridgedLocalesMenuButton.js +1 -0
  16. package/dist/components/i18n/LangSwitcher.js +1 -0
  17. package/dist/components/loader/GlobalLoader.js +1 -0
  18. package/dist/components/logs/LogFile.js +1 -0
  19. package/dist/components/logs/LogFileById.js +1 -0
  20. package/dist/components/logs/LogViewer.js +1 -0
  21. package/dist/components/menu/AppMenu.js +1 -0
  22. package/dist/components/menu/CustomMenuItemLink.js +1 -0
  23. package/dist/components/menu/DarkToggleMode.js +1 -0
  24. package/dist/components/menu/LanguageToggleMode.js +1 -0
  25. package/dist/components/misc/CustomImageInput.js +1 -0
  26. package/dist/components/misc/DASHGlobalErrorHandler.js +1 -0
  27. package/dist/components/misc/DarkModeSwitcher.js +1 -0
  28. package/dist/components/misc/LanguageSwitcher.js +1 -0
  29. package/dist/components/misc/MUIHtmlToolTip.js +1 -0
  30. package/dist/components/misc/MuiSimpleJsonTable.js +1 -0
  31. package/dist/components/misc/MultiLevelTable.js +1 -0
  32. package/dist/components/misc/NoResults.js +1 -0
  33. package/dist/components/misc/PDFViewer.js +1 -0
  34. package/dist/components/navigation/Breadcrumbs.js +1 -0
  35. package/dist/components/navigation/BreadcrumbsManager.js +1 -0
  36. package/dist/components/navigation/index.js +1 -0
  37. package/dist/components/panel/Error.js +1 -0
  38. package/dist/components/permission/AvailablePermissionsContext.js +1 -0
  39. package/dist/components/permission/PermissionsSelector.js +1 -0
  40. package/dist/components/permission/PermissionsSelectorList.js +1 -0
  41. package/dist/components/permission/tsx +0 -0
  42. package/dist/components/racustombuttons/CustomRAButton.js +1 -0
  43. package/dist/components/racustombuttons/QuickButton.js +1 -0
  44. package/dist/components/racustombuttons/QuickEditButton.js +1 -0
  45. package/dist/components/racustombuttons/QuickIconButton.js +1 -0
  46. package/dist/components/scrollbar/Scrollbar.js +1 -0
  47. package/dist/components/selects/MultiSelect.js +1 -0
  48. package/dist/components/selects/RASearchableSelect.js +1 -0
  49. package/dist/components/selects/RASearchableSelectChips.js +1 -0
  50. package/dist/components/selects/SearchableSelect.js +1 -0
  51. package/dist/components/subscription/BillingCycleSelectInput.js +1 -0
  52. package/dist/components/subscription/PlanAddonsSettings.js +1 -0
  53. package/dist/components/subscription/PlanAuditLog.js +1 -0
  54. package/dist/components/subscription/PlanFeaturesSettings.js +1 -0
  55. package/dist/components/subscription/PlanLimitsSettings.js +1 -0
  56. package/dist/components/subscription/PlanMetadataSettings.js +1 -0
  57. package/dist/components/subscription/PlanPricesSettings.js +1 -0
  58. package/dist/components/subscription/index.js +1 -0
  59. package/dist/components/svgelements/SvgLoading.js +1 -0
  60. package/dist/components/svgelements/SvgLogo.js +1 -0
  61. package/dist/components/svgelements/SvgLogoMin.js +1 -0
  62. package/dist/components/svgelements/SvgShipping.js +1 -0
  63. package/dist/components/tenant/AvailablePermissionsContext.js +0 -0
  64. package/dist/components/tenant/TenantAttributes.js +1 -0
  65. package/dist/components/tenant/TenantAttributesContext.js +1 -0
  66. package/dist/components/tenant/TenantSelector.js +1 -0
  67. package/dist/components/tenant/TenantSettings.js +1 -0
  68. package/dist/components/tenant/TenantSettingsContext.js +1 -0
  69. package/dist/components/tenant/TenantTheme.js +1 -0
  70. package/dist/components/user/AvatarComponent.js +1 -0
  71. package/dist/components/user/TenantAvatarComponent.js +1 -0
  72. package/dist/components/user/UserPreferences.js +1 -0
  73. package/dist/config/ACTIONS.js +1 -0
  74. package/dist/config/ConstantsService.js +1 -0
  75. package/dist/config/DASHAdminSystemConstants.js +1 -0
  76. package/dist/config/PARSERS.js +1 -0
  77. package/dist/contexts/DashQueryClientContext.js +1 -0
  78. package/dist/contexts/DashResourceContext.js +1 -0
  79. package/dist/contexts/I18nBridgeContext.js +1 -0
  80. package/dist/contexts/I18nBridgeSetter.js +1 -0
  81. package/dist/contexts/I18nReduxSync.js +1 -0
  82. package/dist/contexts/SubscriptionPlanFormatsProvider.js +1 -0
  83. package/dist/contexts/SystemRequestsCache.js +1 -0
  84. package/dist/contexts/auth/AuthContext.js +1 -0
  85. package/dist/contexts/auth/AuthContextLocalStorage.js +1 -0
  86. package/dist/contexts/auth/DASHAuthenticationService.js +1 -0
  87. package/dist/contexts/auth/WindowContext.js +1 -0
  88. package/dist/contexts/auth/index.js +1 -0
  89. package/dist/contexts/com/FCMContext.js +1 -0
  90. package/dist/contexts/com/LaravelEchoContext.js +1 -0
  91. package/dist/contexts/com/LaravelEchoMgr.js +1 -0
  92. package/dist/contexts/com/components/DefaultNotificationComponent.js +1 -0
  93. package/dist/contexts/com/components/NotificationAttributesTable.js +1 -0
  94. package/dist/contexts/com/components/NotificationRenderer.js +1 -0
  95. package/dist/contexts/com/components/NotificationsWidget.js +1 -0
  96. package/dist/contexts/com/components/notificationFormats.js +1 -0
  97. package/dist/contexts/com/useLaravelEcho.js +1 -0
  98. package/dist/contexts/dictionary/DictionaryContext.js +1 -0
  99. package/dist/declarations.d.ts +17 -0
  100. package/dist/default-theme/DASHAppProviders.js +1 -0
  101. package/dist/default-theme/DashThemeContext.js +1 -0
  102. package/dist/default-theme/DashThemeContext.tsx.fast +143 -0
  103. package/dist/default-theme/DashThemeContext.tsx.old +306 -0
  104. package/dist/default-theme/DashThemeHelperProvider.js +1 -0
  105. package/dist/default-theme/DomainAppLayout.js +1 -0
  106. package/dist/default-theme/DomainHeader.js +1 -0
  107. package/dist/default-theme/DomainTheme.js +1 -0
  108. package/dist/default-theme/FullLayoutMarkup.js +1 -0
  109. package/dist/default-theme/StaticLayout.js +1 -0
  110. package/dist/default-theme/index.js +1 -0
  111. package/dist/default-theme/menu/AppMaterialMenu.js +1 -0
  112. package/dist/default-theme/menu/AppMenuComponents/SubmenuPortal.js +1 -0
  113. package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItem.js +1 -0
  114. package/dist/default-theme/menu/AppMenuComponents/collapsed/CollapsedSidebarItems.js +1 -0
  115. package/dist/default-theme/menu/AppMenuComponents/expanded/CollapsableSidebarMenu.js +1 -0
  116. package/dist/default-theme/menu/AppMenuComponents/expanded/SidebarItem.js +1 -0
  117. package/dist/default-theme/menu/AppMenuComponents/getItem.js +1 -0
  118. package/dist/default-theme/menu/AppMenuComponents/interfaces.js +0 -0
  119. package/dist/default-theme/menu/AppMenuComponents/submenuConstants.js +1 -0
  120. package/dist/default-theme/menu/AppSidebarMaterial.js +1 -0
  121. package/dist/default-theme/menu/SidebarActions.js +1 -0
  122. package/dist/default-theme/updateDomCssVariables.js +1 -0
  123. package/dist/helpers/checkRole.js +1 -0
  124. package/dist/helpers/parseAxiosError.js +2 -0
  125. package/dist/hooks/audio/useAudio.js +1 -0
  126. package/dist/hooks/axios.js +1 -0
  127. package/dist/hooks/data/useDashboardStats.js +1 -0
  128. package/dist/hooks/data/usePackageByClientsStats.js +1 -0
  129. package/dist/hooks/data/usePackageByCommunesStats.js +1 -0
  130. package/dist/hooks/data/usePackageStats.js +1 -0
  131. package/dist/hooks/data/usePackageWithdrawDetails.js +1 -0
  132. package/dist/hooks/data/useStats.js +1 -0
  133. package/dist/hooks/isCurrentPath.js +1 -0
  134. package/dist/hooks/notifications/WSMessagesManager.js +1 -0
  135. package/dist/hooks/notifications/WSPusherManager.js +1 -0
  136. package/dist/hooks/useBreadcrumbs.js +1 -0
  137. package/dist/hooks/useClickOutside.js +1 -0
  138. package/dist/hooks/useFormPersistance.js +1 -0
  139. package/dist/hooks/useGlobalErrorMediator.js +1 -0
  140. package/dist/hooks/useGlobalLoaderMgr.js +1 -0
  141. package/dist/hooks/useHash.js +1 -0
  142. package/dist/hooks/useLocalStorage.js +1 -0
  143. package/dist/hooks/usePolyglotTranslation.js +1 -0
  144. package/dist/hooks/usePrevious.js +1 -0
  145. package/dist/hooks/usePrintSelected.js +1 -0
  146. package/dist/hooks/useVirtualHash.js +1 -0
  147. package/dist/hooks/window/useWindowSize.js +1 -0
  148. package/dist/interfaces/IAppResourceConfig.js +0 -0
  149. package/dist/interfaces/Log.js +0 -0
  150. package/dist/interfaces/Tenant.js +0 -0
  151. package/dist/interfaces/communication/IActions.js +0 -0
  152. package/dist/interfaces/communication/INotification.js +0 -0
  153. package/dist/interfaces/communication/IPayload.js +0 -0
  154. package/dist/interfaces/communication/IRequestAction.js +0 -0
  155. package/dist/interfaces/communication/IRequestPayload.js +0 -0
  156. package/dist/interfaces/communication/IResponseAction.js +0 -0
  157. package/dist/interfaces/misc/IAny.js +0 -0
  158. package/dist/interfaces/misc/IFlashMessage.js +0 -0
  159. package/dist/interfaces/navigation/IAppMenu.js +0 -0
  160. package/dist/interfaces/navigation/ICollapsableSidebarMenu.js +0 -0
  161. package/dist/interfaces/navigation/IMenuItem.js +0 -0
  162. package/dist/interfaces/notifications/IModel.js +0 -0
  163. package/dist/interfaces/notifications/IModelField.js +0 -0
  164. package/dist/interfaces/notifications/IUserNotification.js +0 -0
  165. package/dist/interfaces/notifications/IUserNotificationData.js +0 -0
  166. package/dist/interfaces/notifications/IUserNotificationPayload.js +0 -0
  167. package/dist/interfaces/user/IGetAuth.js +0 -0
  168. package/dist/interfaces/user/ITenantSettings.js +0 -0
  169. package/dist/interfaces/user/IUser.js +0 -0
  170. package/dist/interfaces/user/IUserSettings.js +0 -0
  171. package/dist/interfaces.js +1 -0
  172. package/dist/layout/AppLayout.js +1 -0
  173. package/dist/layout/ApplicationLayout.js +1 -0
  174. package/dist/layout/MotionWrapper.js +1 -0
  175. package/dist/layout/MotionWrapper.original.js +1 -0
  176. package/dist/layout/ResourceMenu.js +1 -0
  177. package/dist/layout/ResoureLayout.js +1 -0
  178. package/dist/layout/TransitionWrapper.js +24 -0
  179. package/dist/pages/ChangePassword.js +1 -0
  180. package/dist/pages/DASHLanding.js +1 -0
  181. package/dist/pages/DASHLightWeightLogin.js +1 -0
  182. package/dist/pages/DASHSimpleLogin.js +1 -0
  183. package/dist/pages/Login.js +1 -0
  184. package/dist/pages/Profile.js +1 -0
  185. package/dist/pages/RecoverPassword.js +1 -0
  186. package/dist/pages/SingleImageUploader.js +1 -0
  187. package/dist/pages/VerifyAccount.js +1 -0
  188. package/dist/providers/authProvider.js +1 -0
  189. package/dist/providers/dataProvider.js +1 -0
  190. package/dist/providers/i18n/en.js +1 -0
  191. package/dist/providers/i18n/es.js +1 -0
  192. package/dist/providers/i18n/languages.js +1 -0
  193. package/dist/providers/i18nProvider.js +1 -0
  194. package/dist/react-admin-dash/RADashComponent.js +1 -0
  195. package/dist/react-admin-dash/Resource.js +1 -0
  196. package/dist/resources/Brand/BrandResource.js +1 -0
  197. package/dist/resources/DASHResourceLoader.js +1 -0
  198. package/dist/resources/Log/LogResource.js +1 -0
  199. package/dist/resources/Tenant/ImpersonateTenantResource.js +1 -0
  200. package/dist/resources/Trash/TrashTemplate.js +1 -0
  201. package/dist/resources.js +1 -0
  202. package/dist/schemas/log.js +1 -0
  203. package/dist/schemas/notification.js +1 -0
  204. package/dist/schemas/permissions.js +1 -0
  205. package/dist/schemas/roles.js +1 -0
  206. package/dist/schemas/rolesDataGrid.js +1 -0
  207. package/dist/schemas/subscription/components/SubscriptionActions.js +1 -0
  208. package/dist/schemas/subscription/components/SubscriptionPaymentHistory.js +1 -0
  209. package/dist/schemas/subscription/components/SubscriptionPlanFeatures.js +1 -0
  210. package/dist/schemas/subscription/components/SubscriptionPlanPreview.js +1 -0
  211. package/dist/schemas/subscription/components/SubscriptionPlanStats.js +1 -0
  212. package/dist/schemas/subscription/components/SubscriptionStatusIndicator.js +1 -0
  213. package/dist/schemas/subscription/subscriptionPlanSchema.js +1 -0
  214. package/dist/schemas/subscription/subscriptionSchema.js +1 -0
  215. package/dist/schemas/subscriptionPlan.js +1 -0
  216. package/dist/schemas/tenant.js +1 -0
  217. package/dist/schemas/tenantUser.js +1 -0
  218. package/dist/schemas/tenant_superadmin.js +1 -0
  219. package/dist/schemas/user.js +1 -0
  220. package/dist/systemResources.js +1 -0
  221. package/dist/systemResources.old.js +1 -0
  222. package/dist/templates/ResourceTemplate.js +1 -0
  223. package/dist/templates/ResourceTemplate.tsx.memoized_experiment +350 -0
  224. package/dist/templates/ResourceTemplate.tsx.original +396 -0
  225. package/dist/templates/ResourceTemplateCreate.js +1 -0
  226. package/dist/templates/ResourceTemplateEdit.js +1 -0
  227. package/dist/templates/ResourceTemplateFull.js +1 -0
  228. package/dist/templates/ResourceTemplateList.js +1 -0
  229. package/dist/templates/ResourceTemplateOld.tsx.bkup +567 -0
  230. package/dist/templates/ResourceTemplateShow.js +1 -0
  231. package/dist/templates/TrashTemplate.js +1 -0
  232. package/dist/tenantResources.js +1 -0
  233. package/dist/test_portal_bubbles.js +1 -0
  234. package/dist/theme/AppHeader.js +1 -0
  235. package/dist/theme/AppLayoutSetting.js +1 -0
  236. package/dist/theme/AppLogo.js +1 -0
  237. package/dist/theme/AppSidebar.js +1 -0
  238. package/dist/theme/AppSidebarContent.js +1 -0
  239. package/dist/theme/AppSidebarLogo.js +1 -0
  240. package/dist/theme/components/PageTitle.js +1 -0
  241. package/dist/utils/cache/CacheInvalidatorContext.js +1 -0
  242. package/dist/utils/cache/CacheInvalidatorListenerComponent.js +1 -0
  243. package/dist/utils/cache/useCacheInvalidatorListener.js +1 -0
  244. package/dist/utils/convertFileToBase64.js +1 -0
  245. package/dist/utils/convertToFile.js +1 -0
  246. package/dist/utils/cookies.js +1 -0
  247. package/dist/utils/dashDefaultQueryClient.js +1 -0
  248. package/dist/utils/dataUrlToBlob.js +1 -0
  249. package/dist/utils/deepReplace.js +1 -0
  250. package/dist/utils/getProfileMenu.js +1 -0
  251. package/dist/utils/getTenantSettings.js +1 -0
  252. package/dist/utils/getType.js +1 -0
  253. package/dist/utils/getUserSettings.js +1 -0
  254. package/dist/utils/hasCode.js +1 -0
  255. package/dist/utils/index.js +1 -0
  256. package/dist/utils/injectTenantStyles.js +1 -0
  257. package/dist/utils/isComponent.js +1 -0
  258. package/dist/utils/navEvents.js +1 -0
  259. package/dist/utils/prototypes.js +1 -0
  260. package/dist/utils/regexp.js +1 -0
  261. package/dist/utils/resolveObjectPath.js +1 -0
  262. package/dist/utils/setNativeValue.js +1 -0
  263. package/dist/utils/slugify.js +1 -0
  264. package/dist/utils/validators/emailValidator.js +1 -0
  265. package/dist/utils/validators/requiredValidator.js +1 -0
  266. package/dist/utils/validators/rutValidator.js +1 -0
  267. package/dist/utils/validators.js +1 -0
  268. package/package.json +13 -2
@@ -0,0 +1 @@
1
+ var z=Object.defineProperty;var D=(r,i,e)=>i in r?z(r,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[i]=e;var b=(r,i,e)=>D(r,typeof i!="symbol"?i+"":i,e);import{jsx as Q}from"react/jsx-runtime";import{useDispatch as J,useSelector as M}from"react-redux";import g,{useCallback as l,useContext as K,useRef as m}from"react";import{DASH_REDUX_ACTIONS as h}from"@dashadmin/dash-admin-state";import{ACTION_UPDATE_AUTH as A}from"@dashadmin/dash-admin-state/src/redux/reducers/Auth";import q from"../../hooks/axios";import{getEnv as G}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";import{useDashThemeContext as $}from"../../../src/default-theme/DashThemeContext";import f from"../../theme/AppLayoutSetting";import B from"./DASHAuthenticationService";import{AuthPersistenceService as o,clearDeviceStoreAuth as W}from"@dashadmin/dash-auth";import{dashStorage as I}from"@dashadmin/dash-utils";class X{}b(X,"values");const S=g.createContext(null),vt=r=>{const{children:i}=r,e=M(t=>t.auth),u=J(),{axios:C}=q(),{recreateTheme:F}=$(),v=m(!1),T=m(""),V=m(""),E=m(""),k=m(""),Z=m(!1),[n,p]=g.useState(()=>{const t=o.getUser(),s=o.getToken(),a=o.getSystemValues(),c=JSON.parse(I.getItem("authenticated")||"false");return{authenticated:e.authenticated||c,user:e.user||t,auth:e.auth,token:e.user?.token||s,roles:e.user?.roles,systemValues:a}}),d=l(async()=>{console.log("Making GET request to:",G("APP_GETAUTH_ENDPOINT"));try{const{data:t}=await C.get(G("APP_GETAUTH_ENDPOINT"));return console.log("Received complete auth data:",t),o.saveAuth({auth:t.auth,systemValues:t.systemValues}),u(h.updateAuth(A,{user:t.user,authenticated:!0,auth:t.auth})),p(s=>({...s,systemValues:t.systemValues})),t}catch(t){throw console.error("Error fetching complete auth data:",t),o.markAsLoggedOut(),t}},[C,u]),tt=l(async()=>{const t=o.getToken(),s=o.getUser(),a=JSON.parse(I.getItem("authenticated")||"false");if(console.log("Initializing auth from token:",{hasToken:!!t,hasStoredUser:!!s,isAuthenticated:a,reduxAuthenticated:e.authenticated}),t&&!e.authenticated)try{console.log("Token found but not fully authenticated, fetching complete auth data..."),await d()}catch(c){console.error("Failed to initialize auth from token:",c),o.markAsLoggedOut()}else if(a&&s&&t&&!e.authenticated){console.log("Restoring auth session from localStorage");const c=o.getAuth();u(h.updateAuth(A,{user:s,authenticated:!0,auth:c?.auth||null}))}},[e.authenticated,u,d]),_=l(async t=>{if(!t||e.authenticated||v.current)return;const s=JSON.stringify(t);if(T.current!==s){v.current=!0,T.current=s,console.log("Handling react-admin identity:",t);try{u(h.updateAuth(A,{user:t.user||t,authenticated:t?.user?!0:!!t?.id,auth:t.auth})),await d()}catch{console.error("Failed to fetch complete auth data after identity load")}finally{v.current=!1}}},[e.authenticated,u,d]),U=async t=>{o.markAsLoggedOut(),await W(),B.setPendingRedirect(window.location.pathname),p({authenticated:!1,user:null,auth:null,token:null,roles:null,systemValues:null}),u(h.updateAuth(A,{user:null,authenticated:!1,auth:null})),j({authenticated:!1,user:null,auth:null,token:null,roles:null,systemValues:null}),document.body.classList.remove(f.LAYOUT_TYPE_FULL,f.LAYOUT_TYPE_BOXED,f.LAYOUT_TYPE_FRAMED,f.THEME_TYPE_DARK,f.THEME_TYPE_LIGHT),t&&t()},O=l(t=>{if(t&&(console.log("\u{1F504} AuthContext: Updating auth context with:",t),p(s=>{const a={...s,...t};return console.log("\u2705 AuthContext: Local context updated:",a),a}),(t.authenticated!==void 0||t.user||t.auth)&&t.authenticated!==!1)){console.log("\u{1F504} AuthContext: Dispatching to Redux state...");const s={user:t.user||e.user,authenticated:t.authenticated??e.authenticated,auth:t.auth||e.auth};console.log("\u{1F504} AuthContext: Redux payload:",s),u(h.updateAuth(A,s)),console.log("\u2705 AuthContext: Redux dispatch completed")}},[u,e.user,e.authenticated,e.auth]),R=l(t=>{console.log("Manual update values called with:",t),p(s=>({...s,...t}))},[]),w=l(()=>{try{if(n.roles==="guest")return Promise.resolve("guest");if(n.roles&&Array.isArray(n.roles)){const t={roles:n.roles.map(s=>typeof s=="string"?s:s.name)};return Promise.resolve(t)}if(e.user?.roles&&Array.isArray(e.user.roles)){const t={roles:e.user.roles.map(s=>typeof s=="string"?s:s.name)};return Promise.resolve(t)}return o.getPermissions()}catch(t){return console.error("Failed to get permissions from context:",t),Promise.resolve("null")}},[n.roles,e.user?.roles]),y=l(()=>n.systemValues||o.getSystemValues(),[n.systemValues]),P=l(t=>{const s=y();return s?s[t]:null},[y]),L=l(()=>P("point_of_sales"),[P]);g.useEffect(()=>{const t=s=>{console.log("Auth event received:",s.detail),O(s.detail)};return window.addEventListener("authEvent",t),()=>{window.removeEventListener("authEvent",t)}},[O]),g.useEffect(()=>{if(console.log("Redux auth state changed:",{authenticated:e.authenticated,user:!!e.user,auth:!!e.auth}),e.authenticated){let t=e?.auth?.tenantImages,s=e?.auth?.tenantSettings,a=n.systemValues;t||(t=o.getTenantImages()),s||(s=o.getTenantSettings()),a||(a=o.getSystemValues());const c=JSON.stringify(t);if(t&&V.current!==c){console.log("Updating panel settings with tenant images from auth context or persisted data"),V.current=c;const x={...t.horizontal_logo.original&&{horizontalLogo:t.horizontal_logo.original},...t.squared_logo.original&&{squaredLogo:t.squared_logo.original},...t.banner.original&&{loginBackground:t.banner.original}};u(h.setPanelSettings(x))}const H=JSON.stringify(s);s&&E.current!==H&&(console.log("Recreating MUI theme with tenant settings from auth context"),E.current=H,F(s),u(h.updateThemeSettings(s)));const N=JSON.stringify(a);if(a&&k.current!==N&&(console.log("Processing system values from auth context or persisted data"),k.current=N,console.log("Available system values:",Object.keys(a)),console.log("Point of Sales:",a.point_of_sales)),JSON.parse(I.getItem("authenticated")||"false")&&e.user?.tenant_id){const{DashIPCService:x}=window;x&&x.action("start-bg-service",{token:I.getItem("token"),channel:`private-tenant.${e.user.tenant_id}.system`})}}},[e.authenticated,n.systemValues]),g.useEffect(()=>{console.log("Auth context values changed:",{authenticated:n.authenticated,user:n.user?`${n.user.name} (${n.user.id})`:null,auth:n.auth,token:n.token?"present":"missing",systemValues:n.systemValues?Object.keys(n.systemValues):null})},[n]);const Y=g.useMemo(()=>{const t=n.user||e.user||o.getUser(),s=n.authenticated??e.authenticated??!1,a=n.token||e.user?.token||o.getToken();return{user:t,authenticated:s,auth:n.auth||e.auth,token:a,roles:n.roles||e.user?.roles,systemValues:n.systemValues||o.getSystemValues(),updateValues:R,logout:U,handleReactAdminIdentity:_,getPermissions:w,fetchAuth:d,getSystemValues:y,getSystemValue:P,getPointOfSales:L}},[n,e,R,U,_,w,d,y,P,L]);return Q(S.Provider,{value:Y,children:i})},Ct=S.Consumer,Tt=()=>K(S),j=r=>(console.log("Setting auth event:",r),window.dispatchEvent(new CustomEvent("authEvent",{detail:r})),r),Vt=()=>o.getPermissions();var Et=S;export{S as AuthContext,X as AuthContextClass,Ct as AuthContextConsumer,vt as AuthContextProvider,Et as default,Vt as getAuthPermissions,j as setAuthEvent,Tt as useAuthContext};
@@ -0,0 +1 @@
1
+ var d=Object.defineProperty;var A=(t,e,r)=>e in t?d(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var h=(t,e,r)=>A(t,typeof e!="symbol"?e+"":e,r);import{jsx as V}from"react/jsx-runtime";import P from"../../hooks/useLocalStorage";import I,{useContext as S,useState as f,useEffect as g}from"react";import{dashStorage as o}from"@dashadmin/dash-utils";class m{}h(m,"values");const n={authenticated:!1,user:null,auth:null,token:null,roles:null},a=I.createContext(null),U=t=>{const{children:e,values:r}=t,[x,u]=f(r||n),[i,c]=P("SerializedAuthContext",JSON.stringify(r||n));g(()=>{try{const s=typeof i=="string"?JSON.parse(i):i;u(s||n)}catch(s){console.error("Error parsing auth context from localStorage:",s),u(n)}},[]);const p=s=>{u(C=>{const l={...C,...s};return c(JSON.stringify(l)),l})};return V(a.Provider,{value:{...x,updateValues:p},children:e})},W=a.Consumer,b=()=>S(a),y=()=>{try{const t=o.getItem("SerializedAuthContext");return t?JSON.parse(t):n}catch(t){return console.error("Error getting auth context:",t),n}},R=t=>{try{const r={...y(),...t};return o.setItem("SerializedAuthContext",JSON.stringify(r)),r}catch(e){return console.error("Error updating auth context:",e),t}},q=t=>{try{return o.setItem("SerializedAuthContext",JSON.stringify(t)),o.setItem("roles",JSON.stringify(t.user.roles)),o.setItem("authenticated","true"),o.setItem("user",JSON.stringify(t.user)),t}catch(e){return console.error("Error setting auth context:",e),t}};var w=a;export{m as AuthContextClass,W as AuthContextConsumer,a as AuthContextLocalStorage,U as AuthContextProvider,w as default,y as getAuthContext,q as setAuthContext,R as updateAuthContext,b as useAuthContext};
@@ -0,0 +1 @@
1
+ var y=Object.defineProperty;var N=(m,t,e)=>t in m?y(m,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):m[t]=e;var p=(m,t,e)=>N(m,typeof t!="symbol"?t+"":t,e);import{createAxiosInstance as E}from"@dashadmin/dash-axios-hook";import{setCookie as _}from"../../utils/cookies";import{getEnv as g}from"../../config/DASHAdminSystemConstants";import{AuthPersistenceService as h,syncLocalStorageToDeviceStore as u,clearDeviceStoreAuth as v}from"@dashadmin/dash-auth";import{DASHAppConstants as T}from"@dashadmin/dash-constants";import{DASHAdminSystemConstants as R}from"@dashadmin/dash-constants";import{dashStorage as r}from"@dashadmin/dash-utils";import{DASH_REDUX_ACTIONS as S,dispatchToRedux as k}from"@dashadmin/dash-admin-state";import{ACTION_UPDATE_AUTH as I}from"@dashadmin/dash-admin-state/src/redux/reducers/Auth";class w{constructor(){p(this,"axiosInstance");p(this,"REDIRECT_STORAGE_KEY","redirectAfterLogin");p(this,"logoutFromStorage",async t=>{console.log("logoutFromStorage",t),h.markAsLoggedOut(),await v();const{DashIPCService:e}=window;e&&e.action("stop-bg-service")});p(this,"getInitialAuthState",()=>{try{const t=h.getAuth(),e=h.getUser(),s=h.getToken(),n=JSON.parse(r.getItem("authenticated")||"false");if(console.log("\u{1F50D} DASHLightApp: Initializing auth state with persisted data:",{hasPersistedAuth:!!t,hasStoredUser:!!e,hasStoredToken:!!s,isAuthenticated:n,storedUser:e?`${e.name||e.email} (${e.id})`:null,persistedAuthStructure:t?Object.keys(t):null}),n&&e&&s&&t){console.log("\u2705 DASHLightApp: Using persisted auth state");const a={authenticated:!0,user:e,auth:t.auth||null};return console.log("\u{1F50D} DASHLightApp: Constructed auth state:",{authenticated:a.authenticated,user:a.user?`${a.user.name||a.user.email} (${a.user.id})`:null,auth:a.auth?"present":null}),a}return s&&!n?(console.log("\u{1F504} DASHLightApp: Token found but not authenticated, will initialize later"),{authenticated:!1,user:null,auth:null}):(console.log("\u2139\uFE0F DASHLightApp: No valid persisted auth found, using default auth state"),{authenticated:!1,user:null,auth:null})}catch(t){return console.error("\u274C DASHLightApp: Error getting initial auth state:",t),{authenticated:!1,user:null,auth:null}}});this.axiosInstance=E()}reinitializeAxios(t){this.axiosInstance=E(t)}sanitizeRedirectUrl(t){if(!t)return"/";const e=/^\/[A-Za-z]:\/|^[A-Za-z]:\/|^file:\/\//i.test(t),s=window.location.protocol==="file:"||g("IS_ELECTRON")==="true"||g("IS_ELECTRON")===!0;if((e||t.includes("index.html"))&&t.includes("#")){const n=t.split("#");if(n.length>1&&n[1]){const a=n[1];return console.log("Detected file/electron path with hash, extracting route:",a),"#"+a}}return e?(console.log("Detected Windows file path in redirect, resetting to #/"),"#/"):t.includes("/resources/app/")||t.includes("/dist/index.html")||t.includes("Program Files")?(console.log("Detected Electron app path in redirect, resetting to #/"),"#/"):s&&t.startsWith("/")&&!t.startsWith("#")?(console.log("Detected Electron environment with standard path, adding hash prefix:",t),"#"+t):t}setPendingRedirect(t){if(!t||t==="/"||t==="#/"||t==="#"){console.log("Skipping pending redirect for root path:",t);return}const e=this.sanitizeRedirectUrl(t);if(e==="/"||e==="#/"||e==="#"){console.log("Skipping pending redirect for sanitized root path:",e);return}console.log("Setting pending redirect:",t,"\u2192",e),r.setItem(this.REDIRECT_STORAGE_KEY,e)}getPendingRedirect(){return r.getItem(this.REDIRECT_STORAGE_KEY)}clearPendingRedirect(){console.log("Clearing pending redirect"),r.removeItem(this.REDIRECT_STORAGE_KEY)}getRoleRedirect(t){const e=t?.roles;if(Array.isArray(e)&&e.length>0){for(const s of e)if(s.redirect)return console.log("Found role redirect:",s.name,"->",s.redirect),s.redirect}return null}determineRedirectUrl(t,e=!0){let s=null;if(t)return console.log("Using backend redirect:",t,"(persist:",e,")"),s=t,e?(this.setPendingRedirect(s),this.getPendingRedirect()):this.sanitizeRedirectUrl(s);const n=this.getPendingRedirect();return n?(console.log("Using localStorage redirect:",n),n):(s=g("APP_DEFAULT_REDIRECT"),e?(this.setPendingRedirect(s),this.getPendingRedirect()):this.sanitizeRedirectUrl(s))}async login(t){if(console.log("=== DASH AUTH SERVICE LOGIN START ==="),console.log("Credentials:",{username:t.username,password:"***",redirect:t.redirect,meta:t.meta}),!(t.username&&t.password))return console.log("\u274C Missing credentials"),Promise.resolve({success:!1,error:"Username and password are required"});try{console.log("Making login request to /login");const e=await this.axiosInstance.post("/login",{email:t.username,password:t.password,redirect:t.redirect,meta:t.meta});if(console.log("Login response status:",e.status),console.log("Login response data:",e.data),e.status>=200&&e.status<=299){console.log("\u2705 Login response successful");const s=e.data.redirectTo;console.log("\u{1F3AF} Backend redirectTo:",s);const n=new Date;if(new Date().setDate(n.getDate()+2),e.data&&e.data.token){console.log("Setting token in storage"),r.setItem("token",e.data.token);const c=e.data?.refresh_token||e.data?.refreshToken;c&&(console.log("Setting refresh token in storage"),r.setItem("refreshToken",c)),e.data?.meta&&(console.log("Setting app"),r.setItem("app",e.data.meta.app)),await u()}else console.warn("\u26A0\uFE0F No token in login response");try{console.log("Getting auth data from:",g("APP_GETAUTH_ENDPOINT"));const c=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));console.log("Auth response status:",c.status),console.log("Auth response data:",c.data);const i=c.data;let o=s;if(!o){const A=this.getRoleRedirect(i.user),f=i.redirect||i.user?.redirect||A||null;console.log("Auth response redirect:",f,"(role redirect:",A,")"),f?o=f:t.redirect&&t.redirect!=="/login"?o=t.redirect:o=g("APP_DEFAULT_REDIRECT")||"/"}console.log("\u{1F3AF} Final redirect determined:",o),h.saveAuth(i);const l=i.auth?.tenantSettings?.primary_language_code||i.user?.preferences?.locale;l&&(localStorage.setItem("dash-user-locale",l),window.dispatchEvent(new CustomEvent("dash:locale-change",{detail:{locale:l}})),console.log("\u{1F310} DASHAuthService: Dispatched locale change event:",l)),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(i.user)),r.setItem("roles",i.user?.roles?JSON.stringify(i.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&i.user?.tenant_id&&(r.setItem("tenant_id",i.user?.tenant_id),r.setItem("user_id",i.user?.id));const d={authenticated:!0,user:i.user,auth:i.auth,token:e.data.token||r.getItem("token"),roles:i.user?.roles};return console.log("\u{1F504} DASHAuthenticationService: Dispatching to Redux:",d),k(S.updateAuth(I,{user:d.user,authenticated:d.authenticated,auth:d.auth})),await u(),console.log("\u2705 Login completed successfully"),Promise.resolve({success:!0,token:d.token,user:d.user,auth:d.auth,redirectAfterLogin:o})}catch(c){return await u(),console.error("\u274C Error getting auth data:",c),this.logoutFromStorage("login get auth error"),Promise.resolve({success:!1,error:"Failed to get user authentication data"})}}else return await u(),console.log("\u274C Login response status not successful:",e.status),this.logoutFromStorage("login status error logout"),Promise.reject({success:!1,error:`Login failed with status: ${e.status}`})}catch(e){return await u(),console.error("\u274C Login error:",e),console.error("Error details:",{message:e?.message,response:e?.response?.data,status:e?.response?.status}),this.logoutFromStorage("login error logout"),await u(),Promise.reject({success:!1,error:e?.response?.data?.message||e?.message||"Login failed"})}}async initializeFromToken(){const t=r.getItem("token");if(!t)return{success:!1,error:"No token found"};try{console.log("Initializing auth from existing token...");const{data:e}=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT")),s=this.getRoleRedirect(e.user),n=e.redirect||e.user?.redirect||s||null;console.log("Backend redirect found during token initialization:",n,"(role redirect:",s,")"),h.saveAuth(e),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(e.user)),r.setItem("roles",e.user?.roles?JSON.stringify(e.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&e.user?.tenant_id&&(r.setItem("tenant_id",e.user?.tenant_id),_("tenant_id",e.user?.tenant_id),r.setItem("user_id",e.user?.id),_("user_id",e.user?.id));const a={authenticated:!0,user:e.user,auth:e.auth,token:t,roles:e.user?.roles};console.log("\u{1F504} DASHAuthenticationService: Dispatching token init to Redux:",a),k(S.updateAuth(I,{user:a.user,authenticated:a.authenticated,auth:a.auth})),console.log("Auth initialized successfully from existing token"),await u();const c=this.determineRedirectUrl(n,!1);return{success:!0,token:t,user:e.user,auth:e.auth,redirectAfterLogin:c}}catch(e){return console.error("Error initializing auth from token:",e),this.logoutFromStorage("initialize from token error"),await u(),{success:!1,error:"Failed to initialize authentication from token"}}}async refreshToken(t){try{console.log("[DASHAuthService] Attempting to refresh token...");const e=await this.axiosInstance.post("/auth/refresh",{refresh_token:t});if(e.status>=200&&e.status<=299){const s=e.data;return s.token&&(r.setItem("token",s.token),console.log("[DASHAuthService] Access token updated")),s.refresh_token&&(r.setItem("refreshToken",s.refresh_token),console.log("[DASHAuthService] Refresh token rotated")),await u(),console.log("[DASHAuthService] Token refresh successful"),{success:!0,token:s.token,refreshToken:s.refresh_token,user:s.user}}else return console.warn("[DASHAuthService] Token refresh returned non-success status:",e.status),{success:!1,error:"Token refresh failed"}}catch(e){return console.error("[DASHAuthService] Token refresh error:",e),e?.response?.status===401&&(console.log("[DASHAuthService] Refresh token is invalid or expired"),this.logoutFromStorage("refresh_token_expired")),{success:!1,error:e?.response?.data?.message||e?.message||"Network error occurred"}}}async checkAuth(){const t=JSON.parse(r.getItem("authenticated")||"false"),e=JSON.parse(r.getItem("user")||"null");return!!(t&&e?.id&&h.getAuth())}async getIdentity(){if(!r.getItem("token"))throw new Error("No token present");try{const{data:e}=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));return r.setItem("roles",e.user?.roles?JSON.stringify(e.user.roles):JSON.stringify(T.system.GUEST_ROLE)),r.setItem("authenticated","true"),r.setItem("user",JSON.stringify(e.user)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&e.user?.tenant_id&&(r.setItem("tenant_id",e.user?.tenant_id),r.setItem("user_id",e.user?.id)),await u(),e}catch(e){throw this.logoutFromStorage("get identity error logout"),e}}async shouldRefreshToken(){return r.getItem("token")?!!r.getItem("refreshToken"):!1}async handleTokenRefresh(){const t=r.getItem("refreshToken");if(!t)return!1;try{const e=await this.refreshToken(t);if(e.success)return r.setItem("token",e.token),e.refreshToken&&r.setItem("refreshToken",e.refreshToken),await u(),!0}catch(e){console.error("Token refresh failed:",e),this.logoutFromStorage("token refresh failed")}return!1}async shouldInitializeFromToken(t){if(t)return!0;const e=r.getItem("token"),s=JSON.parse(r.getItem("authenticated")||"false"),n=r.getItem("user");return!!(e&&(!s||!n))}async initializeApp(t){console.log("Initializing DASH app authentication...");const e=!0;if(await this.shouldInitializeFromToken(t))return console.log("Token found but not fully authenticated, initializing..."),await this.initializeFromToken();{const n=r.getItem("token"),a=JSON.parse(r.getItem("authenticated")||"false"),c=r.getItem("user");if(n&&a&&c)if(console.log("Already authenticated, checking if auth refresh needed"),e)try{console.log("Refreshing auth data for latest tenant/user information...");const i=await this.axiosInstance.get(g("APP_GETAUTH_ENDPOINT"));console.log("Fresh auth response:",i.data);const o=i.data,l=this.getRoleRedirect(o.user),d=o.redirect||o.user?.redirect||l||null;console.log("Backend redirect found during app initialization:",d,"(role redirect:",l,")"),h.saveAuth(o);const A=o.auth?.tenantSettings?.primary_language_code||o.user?.preferences?.locale;A&&(localStorage.setItem("dash-user-locale",A),window.dispatchEvent(new CustomEvent("dash:locale-change",{detail:{locale:A}})),console.log("\u{1F310} DASHAuthService: Dispatched locale change event (app init):",A)),r.setItem("user",JSON.stringify(o.user)),r.setItem("roles",o.user?.roles?JSON.stringify(o.user.roles):JSON.stringify(T.system.GUEST_ROLE)),JSON.parse(R.system.ENABLE_TENANT_IMPERSONATION.toString())&&o.user?.tenant_id&&(r.setItem("tenant_id",o.user?.tenant_id),r.setItem("user_id",o.user?.id));const f={authenticated:!0,user:o.user,auth:o.auth,token:n,roles:o.user?.roles};console.log("\u{1F504} DASHAuthenticationService: Dispatching fresh auth to Redux:",f),k(S.updateAuth(I,{user:f.user,authenticated:f.authenticated,auth:f.auth}));const D=this.determineRedirectUrl(d,!1);return console.log("Auth data refreshed successfully"),await u(),{success:!0,token:n,user:o.user,auth:o.auth,redirectAfterLogin:D}}catch(i){console.error("Error refreshing auth data:",i),console.log("Falling back to existing auth data");const o=JSON.parse(c),l=h.getAuth();console.log("\u{1F504} DASHAuthenticationService: Dispatching existing auth to Redux"),k(S.updateAuth(I,{user:o,authenticated:!0,auth:l?.auth||null}));const d=this.determineRedirectUrl(void 0,!1);return await u(),{success:!0,token:n,user:o,auth:l?.auth||null,redirectAfterLogin:d}}else{console.log("No auth refresh needed, using existing data");const i=JSON.parse(c),o=h.getAuth();console.log("\u{1F504} DASHAuthenticationService: Dispatching existing auth to Redux"),k(S.updateAuth(I,{user:i,authenticated:!0,auth:o?.auth||null}));const l=this.determineRedirectUrl(void 0,!1);return await u(),{success:!0,token:n,user:i,auth:o?.auth||null,redirectAfterLogin:l}}else return console.log("No valid authentication found"),await u(),{success:!1,error:"No valid authentication found"}}}async loginWithReactAdmin(t,e){debugger;return await(e||this.login)(t)}}var j=new w;export{j as default};
@@ -0,0 +1 @@
1
+ import t from"react";const o=t.createContext({isMobile:!1,width:0,height:0,mq:"all"});export{o as WindowContext};
@@ -0,0 +1 @@
1
+ export*from"./AuthContext";export*from"./WindowContext";
@@ -0,0 +1 @@
1
+ var M=Object.defineProperty;var k=(s,i,t)=>i in s?M(s,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[i]=t;var a=(s,i,t)=>k(s,typeof i!="symbol"?i+"":i,t);import{jsx as D}from"react/jsx-runtime";import F,{useEffect as O,useMemo as v,useRef as w}from"react";import{createAxiosInstance as L}from"@dashadmin/dash-axios-hook";import{useSelector as b}from"react-redux";import{getEnv as o}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";const _=()=>!!window?.Capacitor?.Plugins?.PushNotifications,p=()=>window?.Capacitor?.Plugins?.PushNotifications,f=()=>window?.Capacitor;class E{constructor(){a(this,"notifications",[]);a(this,"lastNotification",null);a(this,"axiosInstance",L());a(this,"permissionStatus","unknown");this.isSupported()||(this.permissionStatus="not_supported")}isSupported(){const i=f(),t=_(),d=i?.isNativePlatform?.()||!1;return console.log("\u{1F50D} FCM Support check:",{hasCapacitor:!!i,hasPlugin:t,isNativePlatform:d,platform:i?.getPlatform?.()||"web"}),t&&d}getPlatform(){return f()?.getPlatform?.()||"web"}async checkPermissions(){if(!this.isSupported())return console.log("\u{1F4F1} Push notifications not supported on this platform"),this.permissionStatus="not_supported",!1;try{const i=p();console.log("\u{1F50D} Checking push notification permissions...");const t=await i.checkPermissions();return console.log("\u{1F510} Permission status:",t),t.receive==="granted"?(this.permissionStatus="granted",!0):t.receive==="denied"?(this.permissionStatus="denied",!1):(this.permissionStatus="unknown",!1)}catch(i){return console.error("\u274C Error checking permissions:",i),this.permissionStatus="denied",!1}}async requestPermissions(){if(!this.isSupported())return console.log("\u{1F4F1} Push notifications not supported, skipping permission request"),!1;try{const i=p();console.log("\u{1F510} Requesting push notification permissions...");const t=await i.requestPermissions();return console.log("\u{1F510} Permission request result:",t),t.receive==="granted"?(this.permissionStatus="granted",console.log("\u2705 Push notification permissions granted"),!0):(this.permissionStatus="denied",console.log("\u274C Push notification permissions denied"),!1)}catch(i){return console.error("\u274C Error requesting permissions:",i),this.permissionStatus="denied",!1}}async initializePushNotifications(){if(console.log("\u{1F680} Initializing push notifications..."),!this.isSupported()){console.log("\u{1F4F1} Push notifications not supported on this platform, skipping initialization");return}try{if(!await this.checkPermissions()&&!await this.requestPermissions()){console.log("\u274C Cannot initialize push notifications without permissions");return}await this.registerNotifications(),await this.addListeners(),console.log("\u2705 Push notifications initialized successfully")}catch(i){throw console.error("\u274C Failed to initialize push notifications:",i),i}}async registerNotifications(){if(!this.isSupported())throw new Error("Push notifications not supported on this platform");try{const i=p();console.log("\u{1F4DD} Registering for push notifications..."),await i.register(),console.log("\u2705 Successfully registered for push notifications")}catch(i){throw console.error("\u274C Error registering for push notifications:",i),new Error(`Registration failed: ${i.message}`)}}async addListeners(){if(this.isSupported())try{const i=p();console.log("\u{1F442} Adding push notification listeners..."),await i.addListener("registration",t=>{console.log("\u{1F4DD} Registration token received:",t.value),this.sendTokenToBackend(t.value)}),await i.addListener("registrationError",t=>{console.error("\u274C Registration error:",t.error)}),await i.addListener("pushNotificationReceived",t=>{console.log("\u{1F4E8} Push notification received:",t),this.notifications.push(t),this.lastNotification=t}),await i.addListener("pushNotificationActionPerformed",t=>{console.log("\u{1F446} Push notification action performed:",t.actionId,t.inputValue)}),console.log("\u2705 Push notification listeners added successfully")}catch(i){throw console.error("\u274C Error adding listeners:",i),new Error(`Failed to add listeners: ${i.message}`)}}async sendTokenToBackend(i){try{console.log("\u{1F4E4} Sending FCM token to backend..."),await this.axiosInstance.post("/system/fcm/token",{fcm_token:i}),console.log("\u2705 FCM token sent to backend successfully")}catch(t){console.error("\u274C Error sending token to backend:",t)}}clear(){console.log("\u{1F9F9} Clearing notifications..."),this.notifications=[],this.lastNotification=null}cleanup(){console.log("\u{1F9F9} Cleaning up FCM service..."),this.clear()}getState(){return{notifications:this.notifications,lastNotification:this.lastNotification,clear:this.clear.bind(this),initializePushNotifications:this.initializePushNotifications.bind(this),permissionStatus:this.permissionStatus,isSupported:this.isSupported(),platform:this.getPlatform()}}getDebugInfo(){const i=f(),t=_();return{windowCapacitor:!!i,hasPushNotificationsPlugin:t,availablePlugins:i?.Plugins?Object.keys(i.Plugins):[],platform:this.getPlatform(),isNativePlatform:i?.isNativePlatform?.()||!1,isSupported:this.isSupported(),permissionStatus:this.permissionStatus,notificationsCount:this.notifications.length,hasLastNotification:!!this.lastNotification}}}const y=F.createContext({notifications:[],lastNotification:null,clear:()=>{},initializePushNotifications:async()=>{},permissionStatus:"unknown",isSupported:!1,platform:"web"}),T=({manager:s,children:i,...t})=>{const h=w(new E).current,{notifications:m,lastNotification:P,clear:S,initializePushNotifications:c,permissionStatus:I,isSupported:n,platform:l}=s?s():h.getState(),g=b(e=>e.auth),N=w(!1),r=v(()=>({APP_VERSION:o("APP_VERSION")||"1.0.0",BUILD_TIME:o("BUILD_TIME")||new Date().toISOString(),IS_ELECTRON:JSON.parse(o("IS_ELECTRON")||"false"),PLATFORM:o("PLATFORM")||"unknown",IS_WINDOWS:JSON.parse(o("IS_WINDOWS")||"false"),IS_MAC:JSON.parse(o("IS_MAC")||"false"),IS_LINUX:JSON.parse(o("IS_LINUX")||"false"),PLATFORM_TYPE:o("PLATFORM_TYPE")||"desktop",IS_ANDROID:JSON.parse(o("IS_ANDROID")||"false"),IS_IOS:JSON.parse(o("IS_IOS")||"false"),IS_CAPACITOR:JSON.parse(o("IS_CAPACITOR")||"false"),IS_MOBILE:JSON.parse(o("IS_MOBILE")||"false"),CAPACITOR_PLATFORM:o("CAPACITOR_PLATFORM")||"web",ANDROID_AVAILABLE:JSON.parse(o("ANDROID_AVAILABLE")||"false"),IOS_AVAILABLE:JSON.parse(o("IOS_AVAILABLE")||"false")}),[]),C=f();O(()=>{if(g.authenticated&&!N.current){const e=C?.getPlatform?.()||"web",u=C?.isNativePlatform?.()||!1;console.log("\u{1F510} User authenticated, checking if should initialize FCM...",{debug:!1,isSupported:n,platform:l,capacitorPlatform:e,isNativePlatform:u,envVars:{IS_ANDROID:r.IS_ANDROID,IS_IOS:r.IS_IOS,IS_CAPACITOR:r.IS_CAPACITOR,CAPACITOR_PLATFORM:r.CAPACITOR_PLATFORM}}),n?u||e==="android"||e==="ios"?(console.log("\u{1F4F1} Native platform detected: initializing FCM",{capacitorPlatform:e,isNativePlatform:u}),c().catch(A=>{console.error("\u274C FCM initialization failed:",A)})):console.log("\u{1F310} Web platform or unsupported: skipping FCM initialization",{capacitorPlatform:e,isNativePlatform:u}):console.log("\u274C FCM not supported on this platform")}N.current=g.authenticated},[g,!1,n,l,r,c]),O(()=>()=>{h.cleanup()},[h]);const R=v(()=>({notifications:m,lastNotification:P,clear:S,initializePushNotifications:c,permissionStatus:I,isSupported:n,platform:l}),[m,P,S,c,I,n,l]);return D(y.Provider,{value:R,children:i})};export{y as FCMContext,T as FCMProvider,E as FCMService,y as default};
@@ -0,0 +1 @@
1
+ import{jsx as v}from"react/jsx-runtime";import c from"./LaravelEchoMgr";import n from"react";const a=n.createContext({events:[],lastEvent:null,clear:null}),i=({manager:e,children:t,...s})=>{const{events:o,lastEvent:r,clear:l}=e?e():c();return v(a.Provider,{value:{events:o,lastEvent:r,clear:l},children:t})};export{a as LaravelEchoContext,i as LaravelEchoProvider,a as default};
@@ -0,0 +1 @@
1
+ import{jsx as v,jsxs as d}from"react/jsx-runtime";import{useContext as E,useEffect as l,useState as c}from"react";import{toast as p}from"react-toastify";import{NotificationComponent as u}from"./components/NotificationRenderer";import{AuthContext as m}from"../auth/AuthContext";import{NotificationWrapper as h}from"./components/NotificationsWidget";import f from"./useLaravelEcho";const I=e=>{p(d(h,{notification:e,children:[" ",v(u,{notification:e})," "]},0),{position:"top-right",autoClose:8e3,hideProgressBar:!1,closeOnClick:!0,pauseOnHover:!0,draggable:!0,progress:void 0})},N=e=>{p(d(h,{notification:e,children:[" ",v(u,{notification:e})," "]},0),{position:"top-right",autoClose:!1,hideProgressBar:!1,closeOnClick:!0,pauseOnHover:!0,draggable:!0,progress:void 0})},P=()=>{const[e,s]=c([]),[g,o]=c(null),t=E(m);console.log("\u{1F50D} LaravelEchoMgr: Initializing with authContext:",{hasUser:!!t?.user,userId:t?.user?.id,authenticated:t?.authenticated});const y=()=>{o(null)};l(()=>{console.log("Echo manager listener for private and public messages initialized")},[]),console.log("\u{1F50D} LaravelEchoMgr: Setting up public channel listener...");const i=f({type:"public",channel:"public",events:{public:a=>{console.log("\u{1F4E1} LaravelEchoMgr: Received public notification:",a),s([...e,a]),o(a),N(a)}},userId:null,enabled:!0});console.log("\u{1F50D} LaravelEchoMgr: Setting up private channel listener...");const n=f({type:"private",channel:`user.${t.user?.id}`,events:{notification:a=>{console.log("\u{1F4E1} LaravelEchoMgr: Received private notification:",a),I(a)}},userId:t.user?.id,enabled:!!t?.user?.id});return l(()=>{if(n?.lastEvent){console.log("\u{1F4E1} LaravelEchoMgr: Global event captured from private channel:",n.lastEvent);const a=n.lastEvent.data;a&&(o(a),s(r=>[...r,a]))}},[n?.lastEvent]),l(()=>{if(i?.lastEvent){console.log("\u{1F4E1} LaravelEchoMgr: Global event captured from public channel:",i.lastEvent);const a=i.lastEvent.data;a&&(o(a),s(r=>[...r,a]))}},[i?.lastEvent]),{events:e,lastEvent:g,clear:y}};var x=P;export{x as default};
@@ -0,0 +1 @@
1
+ import{Fragment as n,jsx as o}from"react/jsx-runtime";import i from"../../../components/misc/MuiSimpleJsonTable";const a=({notification:t,...e})=>o(n,{children:o(i,{tableData:t.notificationPayload,vertical:!0})});var p=a;export{p as default};
@@ -0,0 +1 @@
1
+ import{Fragment as d,jsx as n,jsxs as m}from"react/jsx-runtime";import c from"react";import f from"../../dictionary/DictionaryContext";const s=({tableData:o,ignore:i,include:l})=>{const r=c.useContext(f);i||(i=[]),l||(l=[]);let e=o?Object.keys(o):[];return l.length&&(e=e.filter(t=>l.includes(t))),i.length&&(e=e.filter(t=>!i.includes(t))),n("table",{className:"table",children:n("tbody",{children:n(()=>e&&e.length>0?e.map(t=>m("tr",{children:[n("td",{children:r.get(t)}),n("td",{children:typeof o[t]!="object"?r.get(o[t]):o[t]})]})):n(d,{}),{})})})};var g=s;export{g as default};
@@ -0,0 +1 @@
1
+ import{Fragment as f,jsx as a}from"react/jsx-runtime";import{useRecordContext as e}from"react-admin";import{formatNotification as n}from"./notificationFormats";const r=({notification:t})=>{let o=t;const i=n(o);return a(i.content,{notification:o})},c=({method:t,attribute:o})=>{const i=e();return a(r,{notification:i})},s=({method:t,attribute:o,resourceConfig:i})=>{switch(t){case"edit":case"create":return a(f,{children:"Not implemented"});case"view":case"list":return a(c,{attribute:o,method:t,resourceConfig:i})}};var A=s;export{r as NotificationComponent,A as default};
@@ -0,0 +1 @@
1
+ import{Fragment as F,jsx as t,jsxs as e}from"react/jsx-runtime";import m,{useContext as u,useEffect as v}from"react";import{useGetList as g}from"react-admin";import{NotificationComponent as y}from"./NotificationRenderer";import{Badge as I,Button as C,Popover as E}from"@mui/material";import{useNavigate as P}from"react-router";import{Link as b}from"react-router-dom";import{useStore as B}from"react-admin";import T from"@mui/icons-material/NotificationsActive";import x from"../LaravelEchoContext";import L from"../../dictionary/DictionaryContext";import k from"../../../components/scrollbar/Scrollbar";import{formatNotification as O}from"./notificationFormats";import{dashStorage as S}from"@dashadmin/dash-utils";const A=({notification:a,key:r,children:i})=>{const n=O(a);return e("li",{className:"dash-media",children:[e("div",{className:"dash-user-thumb dash-mr-3",children:[t(n.content,{notification:a}),t("span",{className:"dash-badge dash-badge-danger dash-text-white dash-rounded-circle"})]}),e("div",{className:"dash-media-body",children:[t("h5",{children:t(n.title,{notification:a})}),t("span",{children:t(n.content,{notification:a})}),i]})]},r)},D=()=>{const[a,r]=B("activeNotifications"),i=u(x);v(()=>{if(i.lastEvent&&S.getItem("lastEvent")!==JSON.stringify(i.lastEvent)){if(["ProductImportProgressNotification"].includes(i.lastEvent.notificationPayload.class))return;r((a||0)+1)}},[i.lastEvent]);const n=P(),{data:s}=g("notification",{pagination:{page:1,perPage:5},sort:null}),c=m.useContext(L),f=()=>t("ul",{className:"dash-sub-popover",children:t("li",{children:c.get("NO_AVAILABLE_NOTIFICATIONS")})}),p=()=>e(F,{children:[e("div",{className:"dash-popover-header",children:[t("h3",{className:"dash-mb-0",children:c.get("NOTIFICATIONS_WIDGET_TITLE")}),t(C,{onClick:()=>n("notification"),children:"Ver todas"})]}),t(k,{className:"dash-popover-scroll",children:t("ul",{className:"dash-sub-popover",children:s&&s.length?s.map((o,h)=>{const N={...o,notificationPayload:{...o.notificationPayload,notificationPayload:{...o.notificationPayload.notificationPayload,name:t(b,{target:"_blank",to:`/log/${o?.notificationPayload?.notificationPayload?.id}/show`,children:o?.notificationPayload?.notificationPayload?.name})}}};return t(A,{notification:o,children:t(y,{notification:N})},h)}):t(f,{})})})]}),[l,d]=m.useState(null);return e("div",{className:"dash-notify dash-header-entry",children:[t(E,{id:void 0,open:!!l,anchorEl:l,onClose:()=>{d(null)},anchorOrigin:{vertical:"bottom",horizontal:"left"},children:t(p,{})}),t(I,{onClick:o=>{d(o.currentTarget)},badgeContent:a,color:"primary",children:t(T,{color:"action"})})]})};var it=D;export{A as NotificationWrapper,D as NotificationsWidget,it as default};
@@ -0,0 +1 @@
1
+ import{Fragment as o,jsx as n}from"react/jsx-runtime";import f from"./DefaultNotificationComponent";function s(c,i,t,a){return{class:c.class,title:i||(e=>n(o,{children:"notification.title"})),icon:t||(e=>n(o,{children:"\u{1F514}"})),content:a||f}}var F=s;export{F as default,s as formatNotification};
@@ -0,0 +1 @@
1
+ var G=Object.defineProperty;var J=(r,e,g)=>e in r?G(r,e,{enumerable:!0,configurable:!0,writable:!0,value:g}):r[e]=g;var _=(r,e,g)=>J(r,typeof e!="symbol"?e+"":e,g);import{useState as C,useEffect as $,useContext as Y,useCallback as w,useRef as Q}from"react";import Z from"@rooks/use-previous";import ee from"laravel-echo";import ne from"pusher-js";import{ConstantsContext as te}from"../../config/ConstantsService";import{getEnv as p}from"@dashadmin/dash-constants/src/DASHAdminSystemConstants";import{useSelector as oe}from"react-redux";import{dashStorage as N}from"@dashadmin/dash-utils";window.Pusher=ne;const f=class f{constructor(){_(this,"clients");this.clients=new Map}static getInstance(){return f.instance||(f.instance=new f),f.instance}setClient(e,g){this.clients.set(e,g)}getClient(e){return this.clients.get(e)}removeClient(e){return this.clients.delete(e)}hasClient(e){return this.clients.has(e)}};_(f,"instance");let D=f;const H=D.getInstance(),ie=({type:r,channel:e,events:g,userId:s,socketId:re,pingInterval:z=3e4,debug:d=!0,enabled:L=!1})=>{const[c,T]=C(null),[n,I]=C(null),[M,K]=C(null),[y,P]=C(!1),v=Z(e),se=Y(te),l=Q(null),a=oe(t=>t.auth),[ce,R]=C(null);console.log("\u{1F50D} useLaravelEcho: Hook called with params:",{type:r,channel:e,userId:s,enabled:L,hasAuth:!!a?.user,authUserId:a?.user?.id,authenticated:a?.authenticated}),$(()=>{a.user?.id&&typeof a.user.id=="number"&&a.user.id!==s&&R(a.user.id),a?.authenticated===!1&&R(null)},[a]);const le=p("APP_ENV")==="production",i=(t,o)=>{d&&console.log(`%c\u{1F4E1} ${t}`,"color: #2196F3; font-weight: bold; font-size: 12px;",o||"")},A=(t,o)=>{d&&console.error(`%c\u{1F4E1} ${t}`,"color: #f44336; font-weight: bold; font-size: 12px;",o||"")},U=w(()=>{if(n&&n.connector&&n.connector.pusher)try{i("Sending custom ping event..."),n.connector.pusher.send_event("client-ping",{timestamp:new Date().toISOString()})}catch(t){A("Error pinging WebSocket connection:",t)}},[n,d]),x=w(()=>`${r}-${e||"global"}-${s||"public"}`,[r,s,e]),W=w(()=>{l.current&&(window.clearInterval(l.current),l.current=null),i("Disconnecting Laravel Echo client...",x()),n&&n.disconnect(),i("Setting Laravel Echo client to null..."),I(null),i("Setting Echo channel to null..."),T(null),i("Clearing current events..."),K(null),i("Setting connection status to false..."),P(!1),i("Removing client from Echo manager...")},[n]);$(()=>{if(!L){console.log("\u{1F50D} useLaravelEcho: Hook disabled, skipping WebSocket setup");return}if(!JSON.parse(p("APP_SOCKETS_ENABLED"))){console.log("\u{1F50D} useLaravelEcho: WebSockets disabled by APP_SOCKETS_ENABLED env var");return}const t=x();if(console.log("\u{1F50D} useLaravelEcho: Setting up WebSocket connection...",{clientId:t,type:r,channel:e,userId:s,enabled:L}),r==="private"&&!s){console.log("\u{1F50D} useLaravelEcho: Skipping private channel setup - no userId provided");return}if(r==="public"||r==="private"&&s){if(H.clients.has(t)){const m=H.getClient(t);console.log("\u{1F50D} useLaravelEcho: Using existing Echo client:",t),I(m);return}const o=s?N.getItem("token"):null,k=o?{headers:{Authorization:`Bearer ${o}`,Accept:"application/json","X-Requested-With":"XMLHttpRequest"}}:void 0;try{const m=p("APP_SOCKETS_HOST"),E=p("APP_SOCKETS_SCHEME")?.toLowerCase()==="https",X=m||window.location.hostname,O=p("APP_SOCKETS_PORT"),S={broadcaster:"pusher",key:p("APP_SOCKETS_KEY")||"dash",wsHost:X,...O&&O!==""?{wsPort:O}:{},secure:E,forceTLS:E,encrypted:E,useTLS:E,disableStats:!E,enabledTransports:E?["wss","ws"]:["ws"],disableCluster:!0,cluster:"mt1",logToConsole:d,activityTimeout:12e4,pongTimeout:3e4};if(console.log("\u{1F50D} useLaravelEcho: WebSocket config:",S),k){const h=p("APP_BACKEND_URL")||window.location.origin,b=p("APP_SOCKETS_AUTH_ENDPOINT")||"/api/ws/auth",j=h.endsWith("/")?h:`${h}/`,F=b.startsWith("/")?b.substring(1):b,B=`${j}${F}`;console.log("\u{1F50D} useLaravelEcho: Using auth endpoint:",B),S.authEndpoint=B,S.auth=k}console.log("\u{1F50D} useLaravelEcho: Initializing Echo client with config:",S);const u=new ee(S);u.connector&&u.connector.pusher&&(u.connector.pusher.bind_global((h,b)=>{i(`Global event received: ${h}`,b),K({event:h,data:b})}),u.connector.pusher.connection.bind("connected",()=>{i("Connected to Pusher!"),P(!0),N.setItem("socketConnectionState","true"),l.current&&window.clearInterval(l.current),l.current=window.setInterval(U,z)}),u.connector.pusher.connection.bind("disconnected",()=>{i("Disconnected from Pusher"),P(!1),l.current&&(window.clearInterval(l.current),l.current=null)}),u.connector.pusher.connection.bind("error",h=>{A("Pusher connection error:",h),P(!1)})),i("Setting Echo client",t),H.setClient(t,u),I(u)}catch(m){A("Error initializing Echo client:",m),W()}}return()=>{d&&(console.log("%c\u{1F4E1} Socket listener unmounted!","color: #ff6b6b; font-weight: bold;"),W())}},[s,L,e]),$(()=>{if(!n||!e||r==="private"&&!s)return;if(i(`Attempting to subscribe to ${r} channel: ${e}`),n.connector.channels[e.includes(".")?`private-${e}`:e]!==void 0){i("Skipping, already suscribed");return}if(c&&v&&e!==v&&(i(`Leaving previous channel: ${v}`),n.leaveChannel(v),T(null)),!c||e!==v)try{let o;r==="private"?(i(`Subscribing to private channel: ${e}`),o=n.private(e.replace("{userId}",s.toString()))):(i(`Subscribing to public channel: ${e}`),o=n.channel(e)),T(o),i("Channel subscription successful:",o)}catch(o){A(`Error subscribing to ${r} channel ${e}:`,o)}return()=>{n&&e&&n.leaveChannel(e)}},[n,e,r,s,v,d]),$(()=>{if(!n||!y)return;const t=()=>{document.visibilityState==="visible"&&n.connector&&n.connector.pusher&&n.connector.pusher.connection.state!=="connected"&&(i("Tab is visible again, reconnecting..."),n.connector.pusher.connect())},o=()=>{i("Browser is online, reconnecting..."),n.connector&&n.connector.pusher&&n.connector.pusher.connect()};return document.addEventListener("visibilitychange",t),window.addEventListener("online",o),()=>{document.removeEventListener("visibilitychange",t),window.removeEventListener("online",o)}},[n,y,d]);const q=w((t,o)=>{if(!c)return;console.log(`Adding listener for event: ${t}`);const k=t;c.listen(k,o)},[c]),V=w(t=>{if(!c)return;console.log(`Adding listener for event: ${t}`);const o=t;c.stopListening(o)},[c]);return{echoChannel:c,isConnected:y,lastEvent:M,ping:U,addListener:q,removeListener:V}};var Te=ie;export{Te as default,H as echoManager};
@@ -0,0 +1 @@
1
+ import{jsx as s}from"react/jsx-runtime";import y from"react";function i(e,r){for(const[o,t]of Object.entries(r))typeof t=="object"&&t!==null?e=i(e,t):e=Array.isArray(e)?e.join(", ").replace(o,t):typeof e=="string"?e.replace(o,t):e;return e}const a=y.createContext({dictionary:null,replacements:null,get:e=>e}),l=({dictionary:e,replacements:r,children:o})=>s(a.Provider,{value:{dictionary:e,replacements:r,get:(t,c)=>{let n=t;return c&&r&&(n=i(n,r)),e[n]?e[n]:n}},children:o});export{a as DictionaryContext,l as DictionaryProvider,a as default};
@@ -0,0 +1,17 @@
1
+ declare module '*.png';
2
+ declare module '*.jpg';
3
+ declare module '*.jpeg';
4
+ declare module '*.svg';
5
+ declare module '*.gif';
6
+
7
+ interface Window {
8
+ Pusher: any;
9
+ Echo: any;
10
+ io: any;
11
+ Laravel: any;
12
+ }
13
+
14
+ declare var Vue: any;
15
+ declare var axios: any;
16
+ declare var jQuery: any;
17
+ declare var Turbo: any;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as F}from"react/jsx-runtime";import*as c from"react";import{ToastContainer as l}from"react-toastify";import{DialogServiceProvider as P}from"@dashadmin/dash-dialog";import f from"@dashadmin/dash-modal";import{LaravelEchoProvider as v}from"../contexts/com/LaravelEchoContext";import{DASHAppConstants as h}from"@dashadmin/dash-constants";import{CacheInvalidatorContextProvider as C}from"../utils/cache/CacheInvalidatorContext";import u from"../utils/cache/CacheInvalidatorListenerComponent";import A from"../components/misc/DASHGlobalErrorHandler";import x from"../contexts/DashQueryClientContext";import{FCMProvider as y}from"../contexts/com/FCMContext";import D from"../hooks/notifications/WSMessagesManager";import{LocalizationProvider as T}from"@mui/x-date-pickers";import{AdapterDayjs as g}from"@mui/x-date-pickers/AdapterDayjs";import{AuthContextProvider as S}from"../contexts/auth";import{Provider as I}from"react-redux";import{DashThemeProvider as R}from"./DashThemeContext";import{ComponentRegistryProvider as M}from"@dashadmin/dash-auto-admin";import{I18nBridgeProvider as E,useI18nBridge as H}from"../contexts/I18nBridgeContext";const L=r=>{const{i18nProvider:o,locale:i}=H(),n=c.useCallback((t,d)=>{if(!o)return t;try{return o.translate(t,d)}catch{return t}},[o,i]),a=r.confirmText===void 0?n("dash.action.continue"):r.confirmText,m=r.cancelText===void 0?n("dash.action.cancel"):r.cancelText;return e(f,{...r,confirmText:a,cancelText:m})},U=({wsMessagesManager:r,dateAdapter:o,store:i,children:n,extendedThemeOptions:a,dashAutoAdminComponents:m,queryClient:t,queryPersister:d,CustomEchoProvider:s})=>{const p=e(E,{children:e(R,{extendedOptions:a,children:e(T,{dateAdapter:o||g,children:e(S,{children:e(x,{queryClient:t,persister:d,children:e(M,{customComponents:m||{},children:e(P,{component:L,componentProps:{sound:h.system.UI_SOUNDS},children:e(y,{children:e(s||v,{manager:r||D,children:F(C,{children:[e(u,{}),e(l,{style:{width:"520px"}}),e(A,{}),n]})})})})})})})})})});return i?e(I,{store:i,children:p}):p};var Pe=U;export{Pe as default};
@@ -0,0 +1 @@
1
+ import{jsx as g,jsxs as I}from"react/jsx-runtime";import{createContext as E,useContext as M,useState as h,useEffect as d}from"react";import{appTheme as T,getAntTheme as f}from"@dashadmin/dash-styles";import{AuthPersistenceService as u}from"@dashadmin/dash-auth";import{updateDomCssVariables as S}from"@dashadmin/dash-utils";import k from"@mui/material/CssBaseline";import O from"antd/es/config-provider";import{createTheme as v,ThemeProvider as H}from"@mui/material";const l=E(null);function y(r){const s=r.breakpoints;return s&&!s.internal_mediaKeys&&s.keys&&s.up&&(s.internal_mediaKeys=s.keys.map(t=>s.up(t))),r}const W=()=>{const r=M(l);if(!r)throw new Error("useDashThemeContext must be used within a DashThemeProvider");return r},X=({extendedOptions:r,children:s})=>{const[t,C]=h(()=>document.documentElement.getAttribute("data-theme")||"dark"),[D,b]=h(()=>{const e=u.getTenantSettings();return T(r,{currentMode:t,colors:e?.colors,tenantSettings:e})}),[p,w]=h(()=>{const e=u.getTenantSettings();return y(v(T(r,{currentMode:t,colors:e?.colors,tenantSettings:e})))}),[P,x]=h(()=>{const e=u.getTenantSettings();return f({currentMode:t,colors:e?.colors,tenantSettings:e})}),a=()=>u.getTenantSettings()||null,c=(e,m)=>{const n=e||a(),o=m||document.documentElement.getAttribute("data-theme")||"dark";console.log("Recreating MUI theme with tenant settings:",n,"mode:",o);const i=T(r,{tenantSettings:n,colors:n?.colors,currentMode:o}),R=y(v(i));b(i),w(R),x(f({tenantSettings:n,colors:n?.colors,currentMode:o})),S(o,n?.colors,n?.values)};d(()=>{const e=new MutationObserver(m=>{m.forEach(n=>{if(n.type==="attributes"&&n.attributeName==="data-theme"){const o=document.documentElement.getAttribute("data-theme")||"dark";if(o!==t){console.log("Theme mode changed from",t,"to",o),C(o);const i=a();console.log("Updating theme with new mode:",o,"and settings:",i),S(o,i?.colors,i?.values)}}})});return e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>e.disconnect()},[t]),d(()=>{console.log("Current mode updated to:",t);const e=a();c(e,t)},[t]),d(()=>{const e=a();e&&(console.log("Recreating MUI theme on mount"),c(e,t))},[]),d(()=>{const e=m=>{if(m.type==="DASHTRefreshTheme"){const n=a();c(n,t)}};return window.addEventListener("DASHTRefreshTheme",e),()=>window.removeEventListener("DASHTRefreshTheme",e)},[]);const A={theme:p,themeOptions:D,recreateTheme:c,currentMode:t};return I(H,{noSsr:!0,disableTransitionOnChange:!0,theme:p,children:[g(k,{}),g(l.Provider,{value:A,children:g(O,{theme:P,children:s})})]})};var Y=l;export{X as DashThemeProvider,Y as default,W as useDashThemeContext};
@@ -0,0 +1,143 @@
1
+ import React, { createContext, useContext, useState, useEffect } from 'react';
2
+ //import { createTheme } from '@mui/material/styles';
3
+ import { appTheme } from 'dash-styles';
4
+ import { useColorScheme } from '@mui/material/styles';
5
+ import { AuthPersistenceService } from 'dash-auth';
6
+ import { useSelector } from 'react-redux';
7
+ import { IDASHAppState } from 'dash-admin-state';
8
+ import { updateDomCssVariables } from './updateDomCssVariables';
9
+ import { Theme,createTheme } from '@mui/material';
10
+
11
+ interface DashThemeContextType {
12
+ theme: Theme;
13
+ themeOptions: ReturnType<typeof appTheme>;
14
+ updateFullTheme: (settings?: any) => void;
15
+ recreateTheme: (tenantSettings?: any) => void;
16
+ }
17
+
18
+ // Create context with null as default - we'll check for this in the hook
19
+ const DashThemeContext = createContext<DashThemeContextType | null>(null);
20
+
21
+ // Custom hook that ensures context is used within provider
22
+ export const useDashThemeContext = () => {
23
+ const context = useContext(DashThemeContext);
24
+ if (!context) {
25
+ throw new Error('useDashThemeContext must be used within a DashThemeProvider');
26
+ }
27
+ return context;
28
+ };
29
+
30
+ interface DashThemeProviderProps {
31
+ children?: React.ReactNode;
32
+ extendedOptions?: any;
33
+ }
34
+
35
+ export const DashThemeProvider: React.FC<DashThemeProviderProps> = ({ extendedOptions, children }) => {
36
+ const [themeOptions, setThemeOptions] = useState<ReturnType<typeof appTheme>>(() => appTheme(extendedOptions));
37
+ const [theme, setTheme] = useState<Theme>(() => createTheme(appTheme(extendedOptions)));
38
+ //const { auth, authenticated } = useAuthContext();
39
+
40
+ const { mode } = useColorScheme();
41
+ /*const dashThemeType = useSelector((state: IDASHAppState<any, any, any>) =>
42
+ state.settings.themeType
43
+ );*/
44
+
45
+ // Helper function to get tenant settings
46
+ const getTenantSettings = () => {
47
+ const persistedTenantSettings = AuthPersistenceService.getTenantSettings();
48
+
49
+ return persistedTenantSettings || null;
50
+ };
51
+
52
+ // Function to recreate the entire MUI theme with tenant settings
53
+ const recreateTheme = (tenantSettings?: any) => {
54
+ const settings = tenantSettings || getTenantSettings();
55
+
56
+ console.log('Recreating MUI theme with tenant settings:', settings);
57
+
58
+ // Create new theme options with tenant settings
59
+ const newThemeOptions = appTheme(
60
+ extendedOptions,
61
+ {
62
+ tenantSettings: settings,
63
+ colors: settings?.colors,
64
+ }
65
+ // Add any other tenant-specific theme customizations here
66
+ );
67
+
68
+ // Create new MUI theme
69
+ const newTheme = createTheme(newThemeOptions);
70
+
71
+ // Update state
72
+ setThemeOptions(newThemeOptions);
73
+ setTheme(newTheme);
74
+
75
+ // Also update CSS variables
76
+ if (settings?.colors || settings?.values) {
77
+ const currentTheme = mode || document.documentElement.getAttribute('data-theme') || 'light';
78
+ updateDomCssVariables(currentTheme, settings?.colors, settings?.values);
79
+ //document.documentElement.setAttribute('data-theme', currentTheme);
80
+ }
81
+ };
82
+
83
+ // Function to update CSS variables (keep existing functionality)
84
+ const updateFullTheme = (colors?: any) => {
85
+ const tenantSettings = getTenantSettings();
86
+ const colorsToUse = colors || tenantSettings?.colors || {};
87
+ const valuesToUse = tenantSettings?.values || {};
88
+ console.log('Updating custom CSS variables with colors:', colorsToUse);
89
+
90
+ const currentTheme = mode || document.documentElement.getAttribute('data-theme') || 'light';
91
+ updateDomCssVariables(currentTheme, colorsToUse, valuesToUse);
92
+ //document.documentElement.setAttribute('data-theme', currentTheme);
93
+ };
94
+
95
+ // Recreate theme when user authenticates or tenant settings change
96
+
97
+ useEffect(() => {
98
+ //if(!auth || !authenticated) {
99
+
100
+ const tenantSettings = getTenantSettings();
101
+ if (tenantSettings) {
102
+ console.log("recreating mui theme on mount")
103
+ recreateTheme(tenantSettings);
104
+ }
105
+ // }
106
+ }, []);
107
+
108
+ // Handle theme mode changes
109
+ useEffect(() => {
110
+
111
+ //if (authenticated) {
112
+ const tenantSettings = getTenantSettings();
113
+ if (tenantSettings) {
114
+
115
+ console.log("recreating mui theme on mode change")
116
+ recreateTheme(tenantSettings);
117
+ }
118
+ //}
119
+ }, [mode/*, dashThemeType*/]);
120
+
121
+ // Create the context value object
122
+ const contextValue: DashThemeContextType = {
123
+ theme,
124
+ themeOptions,
125
+ updateFullTheme,
126
+ recreateTheme
127
+ };
128
+
129
+ useEffect(() => {
130
+ console.log("mui theme updated",themeOptions,theme);
131
+ }, [themeOptions]);
132
+
133
+ return (
134
+ <DashThemeContext.Provider value={contextValue}>
135
+
136
+
137
+ {children}
138
+
139
+ </DashThemeContext.Provider>
140
+ );
141
+ };
142
+
143
+ export default DashThemeContext;
@@ -0,0 +1,306 @@
1
+ import React, { createContext, useContext, useState, useEffect } from 'react';
2
+ import { Theme, createTheme } from '@mui/material/styles';
3
+ import { appTheme } from 'dash-styles';
4
+ import { useAuthContext } from 'dash-admin';
5
+ import { useSelector } from 'react-redux';
6
+ import { IDASHAppState, DASH_THEME_SETTINGS } from 'dash-admin-state';
7
+ import { AuthPersistenceService } from 'dash-auth';
8
+ interface DashThemeContextType {
9
+ theme: Theme;
10
+ themeOptions: ReturnType<typeof appTheme>; // Expose theme options
11
+ updateFullTheme: (settings?: any) => void;
12
+ }
13
+
14
+ const defaultThemeOptions = appTheme();
15
+ const defaultTheme = createTheme(defaultThemeOptions);
16
+
17
+ const DashThemeContext = createContext<DashThemeContextType>({
18
+ theme: defaultTheme,
19
+ themeOptions: defaultThemeOptions,
20
+ updateFullTheme: () => { }
21
+ });
22
+
23
+ let themeStyleElement: HTMLStyleElement | null = null;
24
+ export const updateDomCssVariables = (theme: string, colors: { [x: string]: string }) => {
25
+
26
+ const themeSuffix = `--${theme}`;
27
+
28
+ if (!themeStyleElement) {
29
+ themeStyleElement = document.createElement('style');
30
+ themeStyleElement.id = 'dash-theme-variables';
31
+ document.head.appendChild(themeStyleElement);
32
+ }
33
+
34
+
35
+ let styleString = '';
36
+ Object.entries(colors).forEach(([key, value]) => {
37
+ if (key.endsWith(themeSuffix)) {
38
+ const baseKey = key.slice(0, -themeSuffix.length);
39
+ styleString += `--${baseKey}: ${value}; `;
40
+ }
41
+ });
42
+
43
+ themeStyleElement.textContent = `:root { ${styleString} }`;
44
+
45
+ };
46
+
47
+
48
+ export const useDashThemeContext = () => useContext(DashThemeContext);
49
+
50
+ interface DashThemeProviderProps {
51
+ children?: React.ReactNode;
52
+ extendedOptions?: any;
53
+ }
54
+
55
+ export const DashThemeProvider: React.FC<DashThemeProviderProps> = ({ extendedOptions, children }) => {
56
+ const [themeOptions, setThemeOptions] = useState<ReturnType<typeof appTheme>>(() => appTheme(extendedOptions));
57
+ const [theme, setTheme] = useState<Theme>(() => createTheme(appTheme(extendedOptions)));
58
+ const [cssVariablesCache, setCssVariablesCache] = useState<Record<string, string> | null>(null);
59
+ const { auth, authenticated } = useAuthContext();
60
+
61
+ // Get theme type from Redux state
62
+ const themeType = useSelector((state: IDASHAppState<any, any, any>) =>
63
+ state.settings.themeType
64
+ );
65
+
66
+ // Helper function to get tenant settings (prioritize persisted over auth)
67
+ const getTenantSettings = () => {
68
+ // First try to get persisted tenant settings
69
+ const persistedTenantSettings = AuthPersistenceService.getTenantSettings();
70
+ if (persistedTenantSettings) {
71
+ return persistedTenantSettings;
72
+ }
73
+
74
+ // Fallback to auth tenant settings if no persisted data
75
+ return auth?.tenantSettings || null;
76
+ };
77
+
78
+ const getAllCssVariablesFromStyleSheets = (selector: string) => {
79
+ if (cssVariablesCache) {
80
+ return cssVariablesCache;
81
+ }
82
+
83
+ const cssVariables = {};
84
+
85
+ // Loop through all style sheets
86
+ for (let i = 0; i < document.styleSheets.length; i++) {
87
+ try {
88
+ const styleSheet = document.styleSheets[i];
89
+ // Skip if the stylesheet is from a different origin and can't be accessed
90
+ if (!styleSheet.cssRules) continue;
91
+
92
+ // Loop through all CSS rules in the stylesheet
93
+ for (let j = 0; j < styleSheet.cssRules.length; j++) {
94
+ const rule = styleSheet.cssRules[j];
95
+
96
+ // Check if it's a style rule (type 1)
97
+
98
+ /* @ts-ignore */
99
+ if (rule.selectorText === selector) {
100
+
101
+ /* @ts-ignore */
102
+ const style = rule.style;
103
+
104
+ // Loop through all style properties
105
+ for (let k = 0; k < style.length; k++) {
106
+ const prop = style[k];
107
+ if (prop.startsWith('--')) {
108
+ //console.log(prop,style.getPropertyValue(prop).trim());
109
+ cssVariables[prop] = style.getPropertyValue(prop).trim();
110
+ }
111
+ }
112
+ }
113
+
114
+ }
115
+ } catch (e) {
116
+ // Skip cross-origin stylesheets that throw security errors
117
+ console.warn('Could not access stylesheet:', e);
118
+ }
119
+ }
120
+
121
+ setCssVariablesCache(cssVariables);
122
+ return cssVariables;
123
+ };
124
+
125
+ // Function to update CSS variables based on tenant settings
126
+ const updateCSSVariablesCopy = (themeType: string, settingsColors: { [x: string]: string }) => {
127
+
128
+ const root = document.documentElement
129
+
130
+ const _cssVars = getAllCssVariablesFromStyleSheets(":root");
131
+
132
+ const cssVars = Object.keys(_cssVars).filter(prop => prop.endsWith(`--${themeType}`));
133
+ cssVars.forEach(varName => {
134
+ //console.log(varName);
135
+ const baseVarName = varName.replace(`--${themeType}`, '');
136
+ const value = _cssVars[varName];
137
+ if (value) {
138
+ //console.log("replaced",themeType,baseVarName,value)
139
+ root.style.setProperty(baseVarName, value);
140
+ }
141
+ });
142
+
143
+ if (!settingsColors) return;
144
+ // Update CSS specific variables from backend config
145
+
146
+ // Update any CSS variables that match the incoming settings
147
+ Object.entries(settingsColors).forEach(([key, value]) => {
148
+ const cssVar = `--${key}`;
149
+ root.style.setProperty(cssVar, value);
150
+ });
151
+ };
152
+
153
+ // TODO: this is too slow, setting properties one by one.
154
+ const updateCSSVariables2 = (currentTheme, colors: { [x: string]: string }) => {
155
+
156
+
157
+ const themeSuffix = `--${currentTheme}`;
158
+
159
+ Object.entries(colors).forEach(([key, value]) => {
160
+ if (key.endsWith(themeSuffix)) {
161
+ const baseKey = key.slice(0, -themeSuffix.length);
162
+ document.documentElement.style.setProperty(`--${baseKey}`, String(value));
163
+ }
164
+ });
165
+
166
+
167
+
168
+ };
169
+
170
+ // TODO: this method is faster, but still slow.
171
+
172
+ const updateCSSVariables3 = (currentTheme, colors: { [x: string]: string }) => {
173
+
174
+
175
+ const themeSuffix = `--${currentTheme}`;
176
+
177
+ let styleString = '';
178
+ Object.entries(colors).forEach(([key, value]) => {
179
+ if (key.endsWith(themeSuffix)) {
180
+ const baseKey = key.slice(0, -themeSuffix.length);
181
+ styleString += `--${baseKey}: ${value}; `;
182
+ }
183
+ });
184
+ document.documentElement.setAttribute('style', styleString);
185
+
186
+
187
+
188
+ };
189
+
190
+
191
+
192
+ const updateCSSVariables = (currentTheme: string, colors: { [x: string]: string }) => {
193
+ const startTime = performance.now();
194
+ const themeSuffix = `--${currentTheme}`;
195
+
196
+ // Create or get existing style element
197
+ if (!themeStyleElement) {
198
+ themeStyleElement = document.createElement('style');
199
+ themeStyleElement.id = 'dash-theme-variables';
200
+ document.head.appendChild(themeStyleElement);
201
+ }
202
+
203
+ // Build CSS rule
204
+ /*const cssVariables: string[] = [];
205
+ Object.entries(colors).forEach(([key, value]) => {
206
+ if (key.endsWith(themeSuffix)) {
207
+ const baseKey = key.slice(0, -themeSuffix.length);
208
+ cssVariables.push(`--${baseKey}: ${value}`);
209
+ }
210
+ });*/
211
+
212
+ let styleString = '';
213
+ Object.entries(colors).forEach(([key, value]) => {
214
+ if (key.endsWith(themeSuffix)) {
215
+ const baseKey = key.slice(0, -themeSuffix.length);
216
+ styleString += `--${baseKey}: ${value}; `;
217
+ }
218
+ });
219
+
220
+ // Update the style element content in one operation
221
+ themeStyleElement.textContent = `:root { ${styleString} }`;
222
+
223
+ //const endTime = performance.now();
224
+ //console.log(`updateCSSVariables execution time: ${endTime - startTime}ms`);
225
+ };
226
+
227
+ // Function to recreate theme after CSS variables are updated
228
+ const updateFullTheme = (colors?: any) => {
229
+
230
+ // Get tenant settings from persisted data or auth
231
+ const tenantSettings = getTenantSettings();
232
+ const colorsToUse = colors || tenantSettings?.colors || {};
233
+
234
+ console.log('Updating theme with colors:', colorsToUse);
235
+ //console.log('Using tenant settings from:', tenantSettings ? 'persisted/auth data' : 'none available');
236
+
237
+ updateCSSVariables(themeType, colorsToUse);
238
+
239
+ /*
240
+ DEPRECTATED AS USING CSS VARS FOR MODE SWITCHING
241
+ // Determine which theme function to use based on theme type
242
+ let themeFunction = () => appTheme(extendedOptions);
243
+
244
+ // Recreate theme options with updated CSS variables and theme type
245
+ const newThemeOptions = themeFunction();
246
+ setThemeOptions(newThemeOptions);
247
+
248
+ // Create actual theme from options
249
+ const newTheme = createTheme(newThemeOptions);
250
+ setTheme(newTheme);
251
+ */
252
+ };
253
+
254
+ // Listen for tenant settings changes (both from auth and persisted)
255
+ useEffect(() => {
256
+ const tenantSettings = getTenantSettings();
257
+
258
+ if (tenantSettings?.colors) {
259
+ console.log('Tenant settings detected, updating theme');
260
+ updateFullTheme(tenantSettings.colors);
261
+ } else if (authenticated && auth) {
262
+ // Fallback to auth tenant settings if available
263
+ updateFullTheme(auth?.tenantSettings?.colors);
264
+ } else {
265
+ // Apply theme even without tenant settings (for theme type changes)
266
+ updateFullTheme();
267
+ }
268
+ }, [auth, authenticated]); // Remove auth?.tenantSettings from dependency since we're using getTenantSettings()
269
+
270
+ // Add this useEffect in the DashThemeProvider component:
271
+ useEffect(() => {
272
+ const handleThemeUpdate = (event: CustomEvent) => {
273
+ console.log('Theme update event received:', event.detail);
274
+ updateFullTheme(event.detail.colors);
275
+ };
276
+
277
+ window.addEventListener('dash-theme-update', handleThemeUpdate as EventListener);
278
+
279
+ return () => {
280
+ window.removeEventListener('dash-theme-update', handleThemeUpdate as EventListener);
281
+ };
282
+ }, [updateFullTheme]);
283
+ // Listen for theme type changes
284
+ useEffect(() => {
285
+
286
+ const tenantSettings = getTenantSettings();
287
+ updateFullTheme(tenantSettings?.colors);
288
+ }, [themeType]);
289
+
290
+ // Initialize theme on mount with persisted settings
291
+ useEffect(() => {
292
+ const tenantSettings = getTenantSettings();
293
+ if (tenantSettings?.colors) {
294
+ console.log('Initializing theme with persisted tenant settings');
295
+ updateFullTheme(tenantSettings.colors);
296
+ }
297
+ }, []); // Run only on mount
298
+
299
+ return (
300
+ <DashThemeContext.Provider value={{ theme, themeOptions, updateFullTheme }}>
301
+ {children}
302
+ </DashThemeContext.Provider>
303
+ );
304
+ };
305
+
306
+ export default DashThemeContext;
@@ -0,0 +1 @@
1
+ import{jsx as T}from"react/jsx-runtime";import{createContext as c,useContext as l,useEffect as a}from"react";import{AuthPersistenceService as p}from"@dashadmin/dash-auth";import{useColorScheme as u}from"@mui/material/styles";import{updateDomCssVariables as f}from"@dashadmin/dash-utils";import{dashStorage as s}from"@dashadmin/dash-utils";const m=()=>{const r=s.getItem("theme");return r==="light"||r==="dark"?r:"dark"},d=c({mode:m()}),k=()=>l(d),g=({children:r})=>{const{mode:e,setMode:n}=u(),i=e==="light"||e==="dark"?e:m(),h=()=>{const t=p.getTenantSettings();return t||null};return a(()=>{const t=s.getItem("theme");if(t&&(t==="light"||t==="dark")&&e!==t)n(t);else if(!t){const o="dark";s.setItem("theme",o),document.documentElement.setAttribute("data-theme",o),n(o)}},[]),a(()=>{if(e!=="light"&&e!=="dark")return;const t=new CustomEvent("dash-theme-mode-switched",{detail:{mode:e}});window.dispatchEvent(t);const o=h();(o?.colors||o?.values)&&(s.setItem("theme",e),document.documentElement.setAttribute("data-theme",e),f(e,o?.colors||{},o?.values||{}))},[e]),T(d.Provider,{value:{mode:i},children:r})};var S=g;export{g as DashThemeHelperProvider,S as default,k as useDashThemeHelperContext};