@dashadmin/dash-admin 1.3.45 → 1.3.47

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 (43) hide show
  1. package/dist/components/i18n/BridgedLocalesMenuButton.js +1 -2
  2. package/dist/components/menu/DarkToggleMode.js +1 -1
  3. package/dist/components/subscription/PlanPricesSettings.js +4 -2
  4. package/dist/components/tenancy/GlobalTenantWrapper.js +64 -0
  5. package/dist/components/tenancy/TenantSwitcher.js +389 -0
  6. package/dist/contexts/com/components/EchoNotificationsCenter.js +40 -0
  7. package/dist/default-theme/menu/AppMenuComponents/expanded/SidebarItem.js +1 -0
  8. package/dist/index.js +60 -40
  9. package/dist/pages/Profile.js +32 -38
  10. package/dist/providers/i18n/en.js +33 -0
  11. package/dist/providers/i18n/es.js +33 -0
  12. package/dist/resources/User/components/AvatarUploadField.js +61 -0
  13. package/dist/resources/User/components/PasswordFields.js +67 -0
  14. package/dist/resources/User/getProfileMenu.js +36 -0
  15. package/dist/resources/User/profileResource.js +33 -0
  16. package/dist/resources/User/userLayout.js +58 -0
  17. package/dist/resources/User/userResource.js +90 -0
  18. package/dist/resources/User/userSchema.js +206 -0
  19. package/dist/resources/User/usersFilters.js +22 -0
  20. package/dist/systemResources.js +30 -19
  21. package/package.json +1 -1
  22. package/src/components/i18n/BridgedLocalesMenuButton.tsx +1 -2
  23. package/src/components/menu/DarkToggleMode.tsx +1 -1
  24. package/src/components/subscription/PlanPricesSettings.tsx +2 -2
  25. package/src/components/tenancy/GlobalTenantWrapper.tsx +84 -0
  26. package/src/components/tenancy/TenantSwitcher.tsx +485 -0
  27. package/src/contexts/com/components/EchoNotificationsCenter.tsx +65 -0
  28. package/src/default-theme/menu/AppMaterialMenu.tsx +1 -1
  29. package/src/default-theme/menu/AppMenuComponents/expanded/SidebarItem.tsx +1 -0
  30. package/src/default-theme/menu/SidebarActions.tsx +1 -1
  31. package/src/index.tsx +15 -0
  32. package/src/pages/Profile.tsx +69 -107
  33. package/src/providers/i18n/en.ts +33 -0
  34. package/src/providers/i18n/es.ts +33 -0
  35. package/src/resources/User/components/AvatarUploadField.tsx +57 -0
  36. package/src/resources/User/components/PasswordFields.tsx +73 -0
  37. package/src/resources/User/getProfileMenu.ts +57 -0
  38. package/src/resources/User/profileResource.tsx +51 -0
  39. package/src/resources/User/userLayout.tsx +62 -0
  40. package/src/resources/User/userResource.tsx +111 -0
  41. package/src/resources/User/userSchema.tsx +213 -0
  42. package/src/resources/User/usersFilters.tsx +21 -0
  43. package/src/systemResources.tsx +31 -20
@@ -77,8 +77,7 @@ const BridgedLocalesMenuButton = ({
77
77
  IconButton,
78
78
  {
79
79
  onClick: handleClick,
80
- color: "inherit",
81
- size: "small",
80
+ className: "dash-icon-button-color dash-icon-button-bg",
82
81
  "aria-label": "change language",
83
82
  "aria-controls": open ? "locale-menu" : void 0,
84
83
  "aria-haspopup": "true",
@@ -26,7 +26,7 @@ const DarkToggleMode = () => {
26
26
  setMode(storedTheme);
27
27
  }
28
28
  }, []);
29
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { onClick, children: /* @__PURE__ */ jsx(DashThemeHelperProvider, { children: /* @__PURE__ */ jsx(
29
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { className: "dash-theme-mode-switcher", onClick, children: /* @__PURE__ */ jsx(DashThemeHelperProvider, { children: /* @__PURE__ */ jsx(
30
30
  Avatar,
31
31
  {
32
32
  sizes: "small",
@@ -40,7 +40,8 @@ const PlanPricesView = () => {
40
40
  const plan = useRecordContext();
41
41
  const prices = plan == null ? void 0 : plan.prices;
42
42
  const { data: currencies, isLoading } = useGetList(
43
- "ecommerce/currency",
43
+ "system/currency",
44
+ // core "shared master data" — works for every domain, unlike ecommerce/currency (kitchntabs-backend-domain only)
44
45
  {
45
46
  pagination: { page: 1, perPage: 100 },
46
47
  sort: { field: "code", order: "ASC" },
@@ -118,7 +119,8 @@ const PlanPricesEdit = ({ method }) => {
118
119
  const formContext = useFormContext();
119
120
  const { register, setValue, watch } = formContext;
120
121
  const { data: currencies, isLoading, error } = useGetList(
121
- "ecommerce/currency",
122
+ "system/currency",
123
+ // core "shared master data" — works for every domain, unlike ecommerce/currency (kitchntabs-backend-domain only)
122
124
  {
123
125
  pagination: { page: 1, perPage: 100 },
124
126
  sort: { field: "code", order: "ASC" },
@@ -0,0 +1,64 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ import { Fragment, jsx } from "react/jsx-runtime";
18
+ import { AuthPersistenceService } from "dash-auth";
19
+ import { DASH_REDUX_ACTIONS } from "dash-admin-state";
20
+ import { useDispatch } from "react-redux";
21
+ import DashThemeContext from "../../default-theme/DashThemeContext";
22
+ import React, { useEffect } from "react";
23
+ const GlobalTenantWrapper = (props) => {
24
+ const {
25
+ tenantData = null,
26
+ children
27
+ } = props;
28
+ const dispatch = useDispatch();
29
+ const themeContext = React.useContext(DashThemeContext);
30
+ const recreateTheme = themeContext == null ? void 0 : themeContext.recreateTheme;
31
+ useEffect(() => {
32
+ var _a, _b, _c;
33
+ if (!tenantData) {
34
+ return;
35
+ }
36
+ if (tenantData.tenantImages) {
37
+ const logos = __spreadValues(__spreadValues(__spreadValues({}, ((_a = tenantData.tenantImages.horizontal_logo) == null ? void 0 : _a.original) && {
38
+ horizontalLogo: tenantData.tenantImages.horizontal_logo.original
39
+ }), ((_b = tenantData.tenantImages.squared_logo) == null ? void 0 : _b.original) && {
40
+ squaredLogo: tenantData.tenantImages.squared_logo.original
41
+ }), ((_c = tenantData.tenantImages.banner) == null ? void 0 : _c.original) && {
42
+ loginBackground: tenantData.tenantImages.banner.original
43
+ });
44
+ dispatch(DASH_REDUX_ACTIONS.setPanelSettings(logos));
45
+ }
46
+ if (tenantData.tenantSettings && recreateTheme) {
47
+ recreateTheme(tenantData.tenantSettings);
48
+ }
49
+ const publicAuthData = {
50
+ auth: {
51
+ tenantImages: tenantData.tenantImages,
52
+ tenantSettings: tenantData.tenantSettings,
53
+ tenant: tenantData.tenant
54
+ },
55
+ systemValues: tenantData.systemValues
56
+ };
57
+ AuthPersistenceService.saveAuth(publicAuthData);
58
+ }, [tenantData]);
59
+ return /* @__PURE__ */ jsx(Fragment, {});
60
+ };
61
+ var GlobalTenantWrapper_default = GlobalTenantWrapper;
62
+ export {
63
+ GlobalTenantWrapper_default as default
64
+ };
@@ -0,0 +1,389 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
41
+ import { useState, useRef, useEffect, useCallback } from "react";
42
+ import {
43
+ Avatar,
44
+ Box,
45
+ Typography,
46
+ CircularProgress
47
+ } from "@mui/material";
48
+ import BusinessIcon from "@mui/icons-material/Business";
49
+ import StoreIcon from "@mui/icons-material/Store";
50
+ import SwapHorizIcon from "@mui/icons-material/SwapHoriz";
51
+ import ReactDOM from "react-dom";
52
+ import { dashStorage } from "dash-utils";
53
+ import { AuthPersistenceService } from "dash-auth";
54
+ import { DASHAdminSystemConstants, getEnv } from "dash-constants";
55
+ import { useAxios } from "dash-axios-hook";
56
+ import { updateDomCssVariables } from "dash-utils";
57
+ import DASHLayoutSettings from "../../theme/AppLayoutSetting";
58
+ import { useDispatch, useSelector } from "react-redux";
59
+ import { setPanelSettings } from "dash-admin-state/redux/actions/Common";
60
+ import { useWindowSize } from "dash-utils";
61
+ import { setAuthEvent } from "../../contexts/auth";
62
+ const dispatchTenantSwitchEvent = (detail) => {
63
+ window.dispatchEvent(new CustomEvent("tenant_switch", { detail }));
64
+ };
65
+ const getActiveTenantId = () => {
66
+ if (!isTenantImpersonationEnabled()) {
67
+ return null;
68
+ }
69
+ return dashStorage.getItem("active_tenant_id") || null;
70
+ };
71
+ const isTenantImpersonationEnabled = () => {
72
+ const val = DASHAdminSystemConstants.system.ENABLE_TENANT_IMPERSONATION;
73
+ if (typeof val === "boolean") return val;
74
+ if (typeof val === "string") return val === "true" || val === "1";
75
+ return !!val;
76
+ };
77
+ const TenantSwitcher = ({
78
+ defaultHorizontalLogo,
79
+ defaultSquaredLogo,
80
+ defaultLoginBackground
81
+ }) => {
82
+ var _a, _b;
83
+ const axios = useAxios();
84
+ const dispatch = useDispatch();
85
+ const windowSize = useWindowSize();
86
+ const [open, setOpen] = useState(false);
87
+ const [switching, setSwitching] = useState(false);
88
+ const avatarRef = useRef(null);
89
+ const menuRef = useRef(null);
90
+ const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
91
+ const timeoutRef = useRef(null);
92
+ const [webView, setWebView] = useState(false);
93
+ const [activeTenantId, setActiveTenantId] = useState(
94
+ getActiveTenantId()
95
+ );
96
+ const panelSettings = useSelector(
97
+ (state) => {
98
+ var _a2;
99
+ return (_a2 = state.common) == null ? void 0 : _a2.panelSettings;
100
+ }
101
+ );
102
+ const sidebarPosition = (panelSettings == null ? void 0 : panelSettings.sidebarPosition) || "left";
103
+ const systemValues = AuthPersistenceService.getSystemValues();
104
+ const tenants = (systemValues == null ? void 0 : systemValues.tenants) || [];
105
+ const tenancy = systemValues == null ? void 0 : systemValues.tenancy;
106
+ const auth = AuthPersistenceService.getAuth();
107
+ const currentTenantName = activeTenantId ? ((_a = tenants.find((t) => t.id === activeTenantId)) == null ? void 0 : _a.name) || "Tenant" : (tenancy == null ? void 0 : tenancy.public_name) || ((_b = auth == null ? void 0 : auth.tenant) == null ? void 0 : _b.name) || "Tenancy Account";
108
+ useEffect(() => {
109
+ if (document.body.classList.contains("webview")) {
110
+ setWebView(true);
111
+ }
112
+ }, []);
113
+ if (!isTenantImpersonationEnabled() || tenants.length === 0) {
114
+ return null;
115
+ }
116
+ const calculateMenuPosition = () => {
117
+ if (avatarRef.current && windowSize.width && windowSize.height) {
118
+ const rect = avatarRef.current.getBoundingClientRect();
119
+ const menuWidth = 230;
120
+ const menuHeight = 120;
121
+ let left = rect.left + window.scrollX;
122
+ let top = rect.top + window.scrollY;
123
+ if (left + menuWidth > windowSize.width) {
124
+ left = windowSize.width - menuWidth - 10;
125
+ }
126
+ if (left < 10) {
127
+ left = 10;
128
+ }
129
+ if (sidebarPosition === "bottom") {
130
+ top = rect.top + window.scrollY - menuHeight - 10;
131
+ }
132
+ setMenuPosition({
133
+ top,
134
+ left: left + 40
135
+ });
136
+ }
137
+ };
138
+ const handleMouseEnter = (e) => {
139
+ e.preventDefault();
140
+ if (timeoutRef.current) {
141
+ clearTimeout(timeoutRef.current);
142
+ timeoutRef.current = null;
143
+ }
144
+ setOpen(true);
145
+ calculateMenuPosition();
146
+ };
147
+ const handleClick = (e) => {
148
+ e.preventDefault();
149
+ setOpen((prev) => !prev);
150
+ calculateMenuPosition();
151
+ };
152
+ const handleMouseLeave = () => {
153
+ if (!webView) {
154
+ timeoutRef.current = setTimeout(() => setOpen(false), 150);
155
+ }
156
+ };
157
+ const handleMenuMouseEnter = () => {
158
+ if (timeoutRef.current) {
159
+ clearTimeout(timeoutRef.current);
160
+ timeoutRef.current = null;
161
+ }
162
+ };
163
+ const handleMenuMouseLeave = () => {
164
+ if (!webView) {
165
+ setOpen(false);
166
+ }
167
+ };
168
+ useEffect(() => {
169
+ return () => {
170
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
171
+ };
172
+ }, []);
173
+ useEffect(() => {
174
+ if (open) calculateMenuPosition();
175
+ }, [open, windowSize.width]);
176
+ const handleSwitch = useCallback((tenantId) => __async(null, null, function* () {
177
+ var _a2, _b2, _c, _d, _e, _f, _g, _h;
178
+ if (switching) return;
179
+ if (tenantId === activeTenantId) {
180
+ setOpen(false);
181
+ return;
182
+ }
183
+ setSwitching(true);
184
+ setOpen(false);
185
+ try {
186
+ const isTenancyLevel = tenantId === null;
187
+ const authEndpoint = getEnv("APP_GETAUTH_ENDPOINT") || "auth/tenancyAuth";
188
+ const headers = {};
189
+ if (!isTenancyLevel && tenantId) {
190
+ headers["X-Tenant-Id"] = tenantId;
191
+ }
192
+ if (tenantId) {
193
+ dashStorage.setItem("active_tenant_id", tenantId);
194
+ dashStorage.setItem("tenant_id", tenantId);
195
+ } else {
196
+ dashStorage.removeItem("active_tenant_id");
197
+ dashStorage.removeItem("tenant_id");
198
+ }
199
+ const { data: authData } = yield axios.get(authEndpoint, { headers });
200
+ AuthPersistenceService.saveAuth(authData);
201
+ dashStorage.setItem("authenticated", "true");
202
+ dashStorage.setItem("user", JSON.stringify(authData.user));
203
+ if ((_a2 = authData.user) == null ? void 0 : _a2.roles) {
204
+ dashStorage.setItem("roles", JSON.stringify(authData.user.roles));
205
+ }
206
+ setAuthEvent({
207
+ authenticated: true,
208
+ user: authData.user,
209
+ auth: authData.auth,
210
+ token: dashStorage.getItem("token"),
211
+ roles: (_b2 = authData.user) == null ? void 0 : _b2.roles
212
+ });
213
+ const tenantSettings = (_c = authData.auth) == null ? void 0 : _c.tenantSettings;
214
+ try {
215
+ const currentThemeMode = document.documentElement.getAttribute("data-theme") || DASHLayoutSettings.THEME_TYPE_DARK;
216
+ updateDomCssVariables(currentThemeMode, tenantSettings == null ? void 0 : tenantSettings.colors, tenantSettings == null ? void 0 : tenantSettings.values);
217
+ } catch (err) {
218
+ console.error("[TenantSwitcher] Error updating CSS variables:", err);
219
+ }
220
+ const tenantImages = (_d = authData.auth) == null ? void 0 : _d.tenantImages;
221
+ if (tenantImages) {
222
+ AuthPersistenceService.setTenantImages(tenantImages);
223
+ dispatch(setPanelSettings(__spreadProps(__spreadValues({}, panelSettings || {}), {
224
+ horizontalLogo: ((_e = tenantImages.horizontal_logo) == null ? void 0 : _e.original) || (panelSettings == null ? void 0 : panelSettings.horizontalLogo),
225
+ squaredLogo: ((_f = tenantImages.squared_logo) == null ? void 0 : _f.original) || (panelSettings == null ? void 0 : panelSettings.squaredLogo),
226
+ loginBackground: ((_g = tenantImages.banner) == null ? void 0 : _g.original) || (panelSettings == null ? void 0 : panelSettings.loginBackground)
227
+ })));
228
+ } else {
229
+ AuthPersistenceService.clearTenantImages();
230
+ dispatch(setPanelSettings(__spreadProps(__spreadValues({}, panelSettings || {}), {
231
+ horizontalLogo: defaultHorizontalLogo,
232
+ squaredLogo: defaultSquaredLogo,
233
+ loginBackground: defaultLoginBackground
234
+ })));
235
+ }
236
+ if (tenantSettings) {
237
+ AuthPersistenceService.setTenantSettings(tenantSettings);
238
+ } else {
239
+ AuthPersistenceService.clearTenantSettings();
240
+ }
241
+ setActiveTenantId(tenantId);
242
+ const tenantName = isTenancyLevel ? (tenancy == null ? void 0 : tenancy.public_name) || "Tenancy Account" : ((_h = tenants.find((t) => t.id === tenantId)) == null ? void 0 : _h.name) || "Tenant";
243
+ dispatchTenantSwitchEvent({
244
+ tenantId,
245
+ tenantName,
246
+ isTenanancyLevel: isTenancyLevel
247
+ });
248
+ console.log(`[TenantSwitcher] Switched to ${isTenancyLevel ? "Tenancy Account" : tenantName} (${tenantId})`);
249
+ } catch (error) {
250
+ console.error("[TenantSwitcher] Switch failed:", error);
251
+ if (activeTenantId) {
252
+ dashStorage.setItem("active_tenant_id", activeTenantId);
253
+ dashStorage.setItem("tenant_id", activeTenantId);
254
+ } else {
255
+ dashStorage.removeItem("active_tenant_id");
256
+ dashStorage.removeItem("tenant_id");
257
+ }
258
+ } finally {
259
+ setSwitching(false);
260
+ }
261
+ }), [activeTenantId, switching, axios, dispatch, panelSettings, tenants, tenancy, defaultHorizontalLogo, defaultSquaredLogo, defaultLoginBackground]);
262
+ const isSelected = (id) => id === activeTenantId;
263
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
264
+ /* @__PURE__ */ jsx(
265
+ "div",
266
+ __spreadProps(__spreadValues({
267
+ ref: avatarRef,
268
+ className: "dash-tenant-switcher-trigger"
269
+ }, !webView ? { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave } : { onClick: handleClick }), {
270
+ style: { cursor: "pointer", display: "flex", alignItems: "center" },
271
+ children: switching ? /* @__PURE__ */ jsx(
272
+ CircularProgress,
273
+ {
274
+ className: "dash-icon-button-color dash-icon-button-bg",
275
+ size: 30
276
+ }
277
+ ) : /* @__PURE__ */ jsx(
278
+ Avatar,
279
+ {
280
+ className: "dash-icon-button-color dash-icon-button-bg",
281
+ sx: {
282
+ width: 30,
283
+ height: 30,
284
+ fontSize: "0.8rem"
285
+ },
286
+ children: activeTenantId ? /* @__PURE__ */ jsx(StoreIcon, { sx: { fontSize: 18 } }) : /* @__PURE__ */ jsx(BusinessIcon, { sx: { fontSize: 18 } })
287
+ }
288
+ )
289
+ })
290
+ ),
291
+ open && ReactDOM.createPortal(
292
+ /* @__PURE__ */ jsx(
293
+ "div",
294
+ {
295
+ ref: menuRef,
296
+ className: "dash-tenant-switcher-portal",
297
+ onMouseEnter: !webView ? handleMenuMouseEnter : void 0,
298
+ onMouseLeave: !webView ? handleMenuMouseLeave : void 0,
299
+ children: /* @__PURE__ */ jsxs(
300
+ "div",
301
+ {
302
+ className: "dash-tenant-switcher-menu",
303
+ style: {
304
+ top: menuPosition.top,
305
+ left: menuPosition.left,
306
+ zIndex: 1e4,
307
+ position: "absolute"
308
+ },
309
+ children: [
310
+ /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1.5, borderBottom: "1px solid rgba(255,255,255,0.08)" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "caption", sx: { color: "text.secondary", fontWeight: 600, textTransform: "uppercase", letterSpacing: 0.5 }, children: [
311
+ /* @__PURE__ */ jsx(SwapHorizIcon, { sx: { fontSize: 14, mr: 0.5, verticalAlign: "middle" } }),
312
+ "Switch Environment"
313
+ ] }) }),
314
+ /* @__PURE__ */ jsxs(
315
+ "div",
316
+ {
317
+ onClick: () => handleSwitch(null),
318
+ style: {
319
+ padding: "10px 16px",
320
+ cursor: "pointer",
321
+ display: "flex",
322
+ alignItems: "center",
323
+ gap: 10,
324
+ backgroundColor: isSelected(null) ? "rgba(var(--dash-primary-rgb, 25, 118, 210), 0.15)" : "transparent",
325
+ borderLeft: isSelected(null) ? "3px solid var(--dash-primary, #1976d2)" : "3px solid transparent",
326
+ transition: "background-color 0.15s ease"
327
+ },
328
+ onMouseOver: (e) => {
329
+ if (!isSelected(null)) e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.05)";
330
+ },
331
+ onMouseOut: (e) => {
332
+ if (!isSelected(null)) e.currentTarget.style.backgroundColor = "transparent";
333
+ },
334
+ children: [
335
+ /* @__PURE__ */ jsx(BusinessIcon, { sx: { fontSize: 20, color: isSelected(null) ? "primary.main" : "text.secondary" } }),
336
+ /* @__PURE__ */ jsxs(Box, { children: [
337
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { fontWeight: isSelected(null) ? 600 : 400, color: isSelected(null) ? "primary.main" : "text.primary" }, children: (tenancy == null ? void 0 : tenancy.public_name) || "Tenancy Account" }),
338
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { color: "text.secondary" }, children: "Manager Account" })
339
+ ] })
340
+ ]
341
+ }
342
+ ),
343
+ /* @__PURE__ */ jsx(Box, { sx: { borderTop: "1px solid rgba(255,255,255,0.06)", mx: 1 } }),
344
+ tenants.map((tenant) => /* @__PURE__ */ jsxs(
345
+ "div",
346
+ {
347
+ onClick: () => handleSwitch(tenant.id),
348
+ style: {
349
+ padding: "10px 16px",
350
+ cursor: "pointer",
351
+ display: "flex",
352
+ alignItems: "center",
353
+ gap: 10,
354
+ backgroundColor: isSelected(tenant.id) ? "rgba(var(--dash-primary-rgb, 25, 118, 210), 0.15)" : "transparent",
355
+ borderLeft: isSelected(tenant.id) ? "3px solid var(--dash-primary, #1976d2)" : "3px solid transparent",
356
+ transition: "background-color 0.15s ease"
357
+ },
358
+ onMouseOver: (e) => {
359
+ if (!isSelected(tenant.id)) e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.05)";
360
+ },
361
+ onMouseOut: (e) => {
362
+ if (!isSelected(tenant.id)) e.currentTarget.style.backgroundColor = "transparent";
363
+ },
364
+ children: [
365
+ /* @__PURE__ */ jsx(StoreIcon, { sx: { fontSize: 20, color: isSelected(tenant.id) ? "primary.main" : "text.secondary" } }),
366
+ /* @__PURE__ */ jsxs(Box, { children: [
367
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { fontWeight: isSelected(tenant.id) ? 600 : 400, color: isSelected(tenant.id) ? "primary.main" : "text.primary" }, children: tenant.name }),
368
+ tenant.slug && /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { color: "text.secondary" }, children: tenant.slug })
369
+ ] })
370
+ ]
371
+ },
372
+ tenant.id
373
+ ))
374
+ ]
375
+ }
376
+ )
377
+ }
378
+ ),
379
+ document.body
380
+ )
381
+ ] });
382
+ };
383
+ var TenantSwitcher_default = TenantSwitcher;
384
+ export {
385
+ TenantSwitcher_default as default,
386
+ dispatchTenantSwitchEvent,
387
+ getActiveTenantId,
388
+ isTenantImpersonationEnabled
389
+ };
@@ -0,0 +1,40 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useContext, useEffect } from "react";
3
+ import { NotificationsCenter, useNotificationsCenter } from "dash-components";
4
+ import LaravelEchoContext from "../LaravelEchoContext";
5
+ const spanishLabels = {
6
+ title: "Notificaciones",
7
+ markAll: "Marcar todas",
8
+ noNotifications: "No hay notificaciones",
9
+ close: "Cerrar",
10
+ acknowledge: "Entendido",
11
+ customer: "Cliente:",
12
+ store: "Tienda:",
13
+ received: "Recibido:",
14
+ now: "Ahora",
15
+ minutesAgo: "m",
16
+ hoursAgo: "h",
17
+ daysAgo: "d"
18
+ };
19
+ const EchoNotificationsCenter = () => {
20
+ const { lastEvent } = useContext(LaravelEchoContext);
21
+ const hook = useNotificationsCenter({ labels: spanishLabels });
22
+ useEffect(() => {
23
+ var _a, _b;
24
+ if (lastEvent && lastEvent.type === "urgency-alert") {
25
+ const notification = lastEvent == null ? void 0 : lastEvent.notificationPayload;
26
+ hook.addNotification({
27
+ title: (notification == null ? void 0 : notification.title) || "Alerta",
28
+ message: (notification == null ? void 0 : notification.message) || "",
29
+ customer: ((_a = notification == null ? void 0 : notification.customer_info) == null ? void 0 : _a.name) ? `${notification.customer_info.name} - Mesa ${notification.customer_info.table}` : "",
30
+ store: ((_b = notification == null ? void 0 : notification.store_info) == null ? void 0 : _b.name) || "",
31
+ data: notification
32
+ }, { showDialog: true, showToast: true, toastSeverity: "warning" });
33
+ }
34
+ }, [lastEvent]);
35
+ return /* @__PURE__ */ jsx(NotificationsCenter, { notificationsHook: hook });
36
+ };
37
+ var EchoNotificationsCenter_default = EchoNotificationsCenter;
38
+ export {
39
+ EchoNotificationsCenter_default as default
40
+ };
@@ -47,6 +47,7 @@ const SidebarItem = ({
47
47
  return /* @__PURE__ */ jsxs(
48
48
  ListItemButton,
49
49
  {
50
+ className,
50
51
  selected: isCurrent,
51
52
  onClick: (e) => {
52
53
  playClick();