mui-atelier 0.1.0
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.
- package/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/NOTICE +32 -0
- package/README.md +282 -0
- package/dist/components/AddressFields.js +83 -0
- package/dist/components/AuthCard.js +94 -0
- package/dist/components/AuthSplash.js +88 -0
- package/dist/components/BrandHeader.js +81 -0
- package/dist/components/BrandLink.js +22 -0
- package/dist/components/BrandMark.js +69 -0
- package/dist/components/BrandProvider.js +14 -0
- package/dist/components/Breadcrumbs.js +62 -0
- package/dist/components/CardHead.js +46 -0
- package/dist/components/ConfirmProvider.js +77 -0
- package/dist/components/DashboardLayout.js +645 -0
- package/dist/components/DataTable.js +546 -0
- package/dist/components/DetailRows.js +42 -0
- package/dist/components/EmptyNote.js +28 -0
- package/dist/components/Eyebrow.js +21 -0
- package/dist/components/HeadingHelp.js +38 -0
- package/dist/components/HeadingLevel.js +18 -0
- package/dist/components/IconTile.js +42 -0
- package/dist/components/ImagePreviewDialog.js +86 -0
- package/dist/components/LabeledField.js +156 -0
- package/dist/components/LanguageSwitcher.js +43 -0
- package/dist/components/ListRow.js +59 -0
- package/dist/components/ModeToggle.js +35 -0
- package/dist/components/PageHeader.js +65 -0
- package/dist/components/PasswordField.js +43 -0
- package/dist/components/PublicLayout.js +27 -0
- package/dist/components/PublicNav.js +17 -0
- package/dist/components/RouteMessage.js +31 -0
- package/dist/components/RowList.js +10 -0
- package/dist/components/SafeHtml.js +57 -0
- package/dist/components/SaveState.js +13 -0
- package/dist/components/SectionPanel.js +48 -0
- package/dist/components/SectionTabs.js +139 -0
- package/dist/components/SiteNav.js +130 -0
- package/dist/components/Skeletons.js +63 -0
- package/dist/components/Sortable.js +81 -0
- package/dist/components/StatTile.js +66 -0
- package/dist/components/StatusChip.js +17 -0
- package/dist/components/StatusDot.js +42 -0
- package/dist/components/SubCard.js +30 -0
- package/dist/components/TabbedCard.js +20 -0
- package/dist/components/TableFilters.js +247 -0
- package/dist/components/ToastProvider.js +65 -0
- package/dist/eslint/chipRules.mjs +65 -0
- package/dist/hooks/useDocumentTitle.js +19 -0
- package/dist/hooks/useOverflowTabs.js +53 -0
- package/dist/hooks/useUnsavedChanges.js +46 -0
- package/dist/i18n/loadMessages.js +15 -0
- package/dist/i18n/mergeMessages.js +13 -0
- package/dist/i18n/messages/en.json +103 -0
- package/dist/i18n/messages/es.json +103 -0
- package/dist/i18n/messages/zh.json +103 -0
- package/dist/lib/authCard.js +4 -0
- package/dist/lib/chipTone.js +46 -0
- package/dist/lib/countryRegionData.js +29 -0
- package/dist/lib/countryRegionData.json +1 -0
- package/dist/lib/navLock.js +22 -0
- package/dist/lib/navTabSx.js +78 -0
- package/dist/lib/orgTime.js +243 -0
- package/dist/lib/pageHtml.js +139 -0
- package/dist/lib/safeNext.js +13 -0
- package/dist/lib/sanitizeHtml.js +36 -0
- package/dist/lib/slugify.js +7 -0
- package/dist/lib/tableFilter.js +147 -0
- package/dist/lib/tableStyle.js +87 -0
- package/dist/test/jsdomShims.js +53 -0
- package/dist/test/themeContract.js +178 -0
- package/dist/theme/OrgThemeRegistry.js +71 -0
- package/dist/theme/ThemeRegistry.js +17 -0
- package/dist/theme/berryNavRow.js +21 -0
- package/dist/theme/createSiteTheme.js +974 -0
- package/dist/theme/themes.js +438 -0
- package/package.json +118 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { useTheme } from "@mui/material/styles";
|
|
5
|
+
import AppBar from "@mui/material/AppBar";
|
|
6
|
+
import Toolbar from "@mui/material/Toolbar";
|
|
7
|
+
import Box from "@mui/material/Box";
|
|
8
|
+
import Drawer from "@mui/material/Drawer";
|
|
9
|
+
import List from "@mui/material/List";
|
|
10
|
+
import ListItem from "@mui/material/ListItem";
|
|
11
|
+
import ListItemButton from "@mui/material/ListItemButton";
|
|
12
|
+
import ListItemIcon from "@mui/material/ListItemIcon";
|
|
13
|
+
import ListItemText from "@mui/material/ListItemText";
|
|
14
|
+
import ListSubheader from "@mui/material/ListSubheader";
|
|
15
|
+
import Typography from "@mui/material/Typography";
|
|
16
|
+
import IconButton from "@mui/material/IconButton";
|
|
17
|
+
import Avatar from "@mui/material/Avatar";
|
|
18
|
+
import Menu from "@mui/material/Menu";
|
|
19
|
+
import MenuItem from "@mui/material/MenuItem";
|
|
20
|
+
import ListItemAvatar from "@mui/material/ListItemAvatar";
|
|
21
|
+
import Chip from "@mui/material/Chip";
|
|
22
|
+
import Divider from "@mui/material/Divider";
|
|
23
|
+
import Stack from "@mui/material/Stack";
|
|
24
|
+
import Collapse from "@mui/material/Collapse";
|
|
25
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
26
|
+
import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
|
|
27
|
+
import MenuIcon from "@mui/icons-material/Menu";
|
|
28
|
+
import MenuOpenIcon from "@mui/icons-material/MenuOpen";
|
|
29
|
+
import ButtonBase from "@mui/material/ButtonBase";
|
|
30
|
+
import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined";
|
|
31
|
+
import ApartmentOutlinedIcon from "@mui/icons-material/ApartmentOutlined";
|
|
32
|
+
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
|
33
|
+
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|
34
|
+
import Link from "next/link";
|
|
35
|
+
import { useTranslations } from "next-intl";
|
|
36
|
+
import ModeToggle from "./ModeToggle.js";
|
|
37
|
+
import LanguageSwitcher from "./LanguageSwitcher.js";
|
|
38
|
+
import BrandMark from "./BrandMark.js";
|
|
39
|
+
import { useBrand } from "./BrandProvider.js";
|
|
40
|
+
import HeadingHelp from "./HeadingHelp.js";
|
|
41
|
+
import { useNavLocked } from "../lib/navLock.js";
|
|
42
|
+
import berryNavRowSx from "../theme/berryNavRow.js";
|
|
43
|
+
const DRAWER_WIDTH = 260;
|
|
44
|
+
const NAV_GAP = 12;
|
|
45
|
+
const APPBAR_H = 64;
|
|
46
|
+
const MINI_WIDTH = 76;
|
|
47
|
+
const NAV_COLLAPSED_KEY = "rt:nav:collapsed";
|
|
48
|
+
function NavRow({ item, open, onToggle, collapsed = false, onExpand }) {
|
|
49
|
+
const t = useTranslations("uikit");
|
|
50
|
+
const kids = item.children ?? [];
|
|
51
|
+
const hasKids = kids.length > 0;
|
|
52
|
+
const locked = useNavLocked();
|
|
53
|
+
const showsSelected = Boolean(item.selected) || hasKids && !open && kids.some((c) => c.selected);
|
|
54
|
+
const dead = Boolean(item.disabled) || locked;
|
|
55
|
+
const behaviour = hasKids ? collapsed ? { onClick: locked ? void 0 : onExpand } : { onClick: locked ? void 0 : onToggle, "aria-expanded": open } : { component: dead ? "div" : Link, href: dead ? void 0 : item.href };
|
|
56
|
+
const button = /* @__PURE__ */ jsx(ListItem, { disablePadding: true, sx: { mb: 0.25 }, children: /* @__PURE__ */ jsxs(
|
|
57
|
+
ListItemButton,
|
|
58
|
+
{
|
|
59
|
+
...behaviour,
|
|
60
|
+
selected: showsSelected,
|
|
61
|
+
disabled: dead,
|
|
62
|
+
"aria-disabled": dead || void 0,
|
|
63
|
+
sx: [collapsed && { justifyContent: "center", px: 1.25 }, (theme) => {
|
|
64
|
+
const nav = theme.rt?.ui?.nav;
|
|
65
|
+
if (nav === "inverse") {
|
|
66
|
+
return {
|
|
67
|
+
borderRadius: 2,
|
|
68
|
+
pl: item.sub ? 2.5 : void 0,
|
|
69
|
+
"&:hover": { backgroundColor: "rgba(255,255,255,0.06)" },
|
|
70
|
+
"&.Mui-selected": {
|
|
71
|
+
backgroundImage: "linear-gradient(96deg, var(--rt-grad-from), var(--rt-grad-to))",
|
|
72
|
+
color: "#FFFFFF",
|
|
73
|
+
"& .MuiListItemIcon-root": { color: "#FFFFFF" },
|
|
74
|
+
boxShadow: "0 8px 18px -10px rgba(0,0,0,0.55)",
|
|
75
|
+
"&:hover": { filter: "brightness(1.07)" }
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (nav === "rail") {
|
|
80
|
+
const railFg = theme.rt?.rail?.fg ?? "#FFFFFF";
|
|
81
|
+
return {
|
|
82
|
+
borderRadius: 2,
|
|
83
|
+
pl: item.sub ? 2.5 : void 0,
|
|
84
|
+
color: railFg,
|
|
85
|
+
"& .MuiListItemIcon-root": { color: `color-mix(in srgb, ${railFg} 78%, transparent)` },
|
|
86
|
+
"&:hover": { backgroundColor: `color-mix(in srgb, ${railFg} 9%, transparent)` },
|
|
87
|
+
"&.Mui-selected": {
|
|
88
|
+
backgroundColor: theme.vars.palette.background.paper,
|
|
89
|
+
color: theme.vars.palette.primary.dark,
|
|
90
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.dark },
|
|
91
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.18), 0 8px 16px -10px rgba(0,0,0,0.45)",
|
|
92
|
+
"&:hover": { backgroundColor: theme.vars.palette.background.paper }
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (nav === "bar") {
|
|
97
|
+
return {
|
|
98
|
+
borderRadius: 0,
|
|
99
|
+
pl: item.sub ? 4 : 2.5,
|
|
100
|
+
"&:hover": { backgroundColor: theme.vars.palette.action.hover },
|
|
101
|
+
"&.Mui-selected": {
|
|
102
|
+
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.08)`,
|
|
103
|
+
boxShadow: `inset 3px 0 0 ${theme.vars.palette.primary.main}`,
|
|
104
|
+
color: theme.vars.palette.primary.dark,
|
|
105
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.main },
|
|
106
|
+
"&:hover": { backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.14)` }
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (nav === "ruled") {
|
|
111
|
+
return {
|
|
112
|
+
borderRadius: 0,
|
|
113
|
+
minHeight: 42,
|
|
114
|
+
pl: item.sub ? 4.5 : 2.75,
|
|
115
|
+
borderBottom: `1px solid color-mix(in srgb, ${theme.vars.palette.divider} 55%, transparent)`,
|
|
116
|
+
"&:hover": { backgroundColor: theme.vars.palette.action.hover },
|
|
117
|
+
"&.Mui-selected": {
|
|
118
|
+
backgroundColor: theme.vars.palette.background.default,
|
|
119
|
+
color: theme.vars.palette.primary.dark,
|
|
120
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.main },
|
|
121
|
+
"& .MuiListItemText-primary": { fontWeight: 700 },
|
|
122
|
+
"&::before": {
|
|
123
|
+
content: '"\\25B8"',
|
|
124
|
+
// ▸
|
|
125
|
+
position: "absolute",
|
|
126
|
+
left: 8,
|
|
127
|
+
color: theme.vars.palette.primary.main,
|
|
128
|
+
fontSize: 14,
|
|
129
|
+
lineHeight: 1
|
|
130
|
+
},
|
|
131
|
+
"&:hover": { backgroundColor: theme.vars.palette.background.default }
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (nav === "quiet") {
|
|
136
|
+
return {
|
|
137
|
+
borderRadius: 0,
|
|
138
|
+
minHeight: 36,
|
|
139
|
+
paddingBlock: "4px",
|
|
140
|
+
pl: item.sub ? 4 : 2.5,
|
|
141
|
+
"& .MuiListItemIcon-root": { minWidth: item.sub ? 28 : 32, "& svg": { fontSize: 18 } },
|
|
142
|
+
"& .MuiListItemText-primary": { fontSize: "0.84rem" },
|
|
143
|
+
"&.Mui-selected": {
|
|
144
|
+
backgroundColor: theme.vars.palette.text.primary,
|
|
145
|
+
color: theme.vars.palette.background.paper,
|
|
146
|
+
"& .MuiListItemIcon-root": { color: "inherit" },
|
|
147
|
+
"&:hover": { backgroundColor: theme.vars.palette.text.primary }
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (nav === "accent") {
|
|
152
|
+
return {
|
|
153
|
+
borderRadius: 2,
|
|
154
|
+
pl: item.sub ? 2.5 : void 0,
|
|
155
|
+
"&.Mui-selected": {
|
|
156
|
+
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.08)`,
|
|
157
|
+
boxShadow: `inset 0 0 0 1px rgba(${theme.vars.palette.primary.mainChannel} / 0.45)`,
|
|
158
|
+
color: theme.vars.palette.primary.main,
|
|
159
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.main },
|
|
160
|
+
"&:hover": { backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.14)` }
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (nav === "pill") {
|
|
165
|
+
return {
|
|
166
|
+
// A pill by default; a square block when the theme has zeroed its
|
|
167
|
+
// radii (a square theme). A theme can also opt THIS left-nav
|
|
168
|
+
// selection out of the pill with radii.nav — matching its own
|
|
169
|
+
// corners instead of taking the full 999 (the floating search bar
|
|
170
|
+
// is separate and keeps its pill). radii.nav is an EXACT px string:
|
|
171
|
+
// in `sx`, a bare number multiplies theme.shape.borderRadius (so 8
|
|
172
|
+
// would render as 8×base, not 8px); 999/0 stay numbers on purpose —
|
|
173
|
+
// any huge multiple caps to a pill, and 0 stays square.
|
|
174
|
+
borderRadius: theme.rt?.radii?.nav != null ? `${theme.rt.radii.nav}px` : theme.rt?.radii?.card === 0 ? 0 : 999,
|
|
175
|
+
pl: item.sub ? 2.5 : void 0,
|
|
176
|
+
"&:hover": { backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.10)` },
|
|
177
|
+
"&.Mui-selected": {
|
|
178
|
+
backgroundColor: theme.vars.palette.primary.main,
|
|
179
|
+
color: theme.vars.palette.primary.contrastText,
|
|
180
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.contrastText },
|
|
181
|
+
boxShadow: `0 6px 16px -8px rgba(${theme.vars.palette.primary.mainChannel} / 0.55)`,
|
|
182
|
+
"&:hover": { backgroundColor: theme.vars.palette.primary.main, filter: "brightness(1.04)" }
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (nav === "berry") {
|
|
187
|
+
return {
|
|
188
|
+
...berryNavRowSx(theme),
|
|
189
|
+
paddingBlock: "10px",
|
|
190
|
+
mb: 0.5,
|
|
191
|
+
pl: item.sub ? 3 : 2,
|
|
192
|
+
"& .MuiListItemIcon-root": { minWidth: 36, "& svg": { fontSize: 20 } }
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
borderRadius: 2,
|
|
197
|
+
pl: item.sub ? 2.5 : void 0,
|
|
198
|
+
"&.Mui-selected": {
|
|
199
|
+
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.12)`,
|
|
200
|
+
color: theme.vars.palette.primary.main,
|
|
201
|
+
"& .MuiListItemIcon-root": { color: theme.vars.palette.primary.main },
|
|
202
|
+
"&:hover": {
|
|
203
|
+
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.18)`
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}],
|
|
208
|
+
children: [
|
|
209
|
+
item.icon ? /* @__PURE__ */ jsx(ListItemIcon, { sx: { minWidth: collapsed ? 0 : item.sub ? 34 : 40, justifyContent: "center", color: "inherit" }, children: item.icon }) : null,
|
|
210
|
+
collapsed ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
211
|
+
/* @__PURE__ */ jsx(ListItemText, { primary: item.label, slotProps: { primary: { fontWeight: item.selected ? 600 : 500 } } }),
|
|
212
|
+
item.disabled || item.soon ? /* @__PURE__ */ jsx(Chip, { label: t("shell.soon"), size: "small", variant: "outlined" }) : null,
|
|
213
|
+
hasKids ? /* @__PURE__ */ jsx(Box, { component: "span", sx: { display: "flex", color: "text.secondary" }, children: open ? /* @__PURE__ */ jsx(ExpandLessIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(ExpandMoreIcon, { fontSize: "small" }) }) : null
|
|
214
|
+
] })
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
) });
|
|
218
|
+
return collapsed ? /* @__PURE__ */ jsx(Tooltip, { title: item.label, placement: "right", disableInteractive: true, children: button }) : button;
|
|
219
|
+
}
|
|
220
|
+
function NavList({ navItems, brand = null, floating = false, collapsed = false, onExpand, footer = null, barHeight = 64 }) {
|
|
221
|
+
const [toggled, setToggled] = useState({});
|
|
222
|
+
const nav = useTheme().rt?.ui?.nav;
|
|
223
|
+
const berry = nav === "berry";
|
|
224
|
+
return (
|
|
225
|
+
// A column, full height, so an app's `drawerFooter` (a promo card, a
|
|
226
|
+
// version chip) can sit at the bottom of the drawer under any length of nav.
|
|
227
|
+
/* @__PURE__ */ jsxs(Box, { sx: { width: collapsed ? MINI_WIDTH : DRAWER_WIDTH, display: "flex", flexDirection: "column", minHeight: "100%" }, role: "navigation", children: [
|
|
228
|
+
brand ? (
|
|
229
|
+
/*
|
|
230
|
+
* nav:'inverse' only — the rail owns its full column (the AppBar sits
|
|
231
|
+
* beside it, see DashboardLayout), so its top is REACHABLE and carries
|
|
232
|
+
* the reference chrome's tenant card: logo + the title node (which may
|
|
233
|
+
* be an organisation switcher), in a lifted panel. `color: inherit`
|
|
234
|
+
* cascades the rail's light-on-dark text into whatever node the title
|
|
235
|
+
* is; the switcher's Menu is a portal and keeps normal colours.
|
|
236
|
+
*/
|
|
237
|
+
/* @__PURE__ */ jsx(Box, { sx: { p: 1.5, pb: 0.5 }, children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1.25, px: 1.5, py: 1.25, borderRadius: (t) => `${t.rt?.radii?.card ?? 12}px`, bgcolor: "rgba(255,255,255,0.07)", border: "1px solid rgba(255,255,255,0.09)", "& .MuiTypography-root": { color: "inherit" } }, children: [
|
|
238
|
+
brand.logoUrl ? /* @__PURE__ */ jsx(BrandMark, { size: 30, logoUrl: brand.logoUrl, alt: "" }) : null,
|
|
239
|
+
/* @__PURE__ */ jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: brand.title })
|
|
240
|
+
] }) })
|
|
241
|
+
) : floating ? (
|
|
242
|
+
/*
|
|
243
|
+
* A floating nav (ui.navFloat) already sits BELOW the AppBar — its paper
|
|
244
|
+
* is inset with a top offset in DashboardLayout — so it needs no spacer
|
|
245
|
+
* to clear the bar, and no divider at the very top of a detached card.
|
|
246
|
+
* A little breathing room at the top of the card is enough.
|
|
247
|
+
*/
|
|
248
|
+
/* @__PURE__ */ jsx(Box, { sx: { pt: 1 } })
|
|
249
|
+
) : berry ? (
|
|
250
|
+
// berry: the bar is 88px, not the Toolbar's 64 — the spacer follows rt.barHeight.
|
|
251
|
+
/* @__PURE__ */ jsx(Box, { sx: { height: barHeight, flexShrink: 0 } })
|
|
252
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
253
|
+
/* @__PURE__ */ jsx(Toolbar, {}),
|
|
254
|
+
/* @__PURE__ */ jsx(Divider, {})
|
|
255
|
+
] }),
|
|
256
|
+
/* @__PURE__ */ jsx(List, { sx: nav === "quiet" ? { px: 0, py: 0.75 } : berry ? { px: collapsed ? 0.75 : 2, py: 0 } : { px: collapsed ? 0.75 : 1.5, py: 1 }, children: navItems.map((item, i) => (
|
|
257
|
+
// A `{ heading }` item renders a section label; grouped items carry
|
|
258
|
+
// `sub` so they sit slightly indented under it. A section label has no
|
|
259
|
+
// room in an icon rail, so it drops when collapsed.
|
|
260
|
+
/*
|
|
261
|
+
* A `{ divider: true }` item CLOSES the group above it, for a set of
|
|
262
|
+
* rows that has to stay visually aligned with the previous group but
|
|
263
|
+
* is not part of it — e.g. Settings and Help sitting at the previous
|
|
264
|
+
* group's indent so their icons line up; without this the heading
|
|
265
|
+
* would claim them.
|
|
266
|
+
*
|
|
267
|
+
* Dropped when the rail is collapsed, like a heading: an icon-only
|
|
268
|
+
* column has no groups to separate.
|
|
269
|
+
*/
|
|
270
|
+
item.divider ? collapsed ? null : /* @__PURE__ */ jsx(Box, { component: "li", sx: { listStyle: "none" }, children: /* @__PURE__ */ jsx(Divider, { sx: { my: 1, mx: 1.5 } }) }, `divider-${i}`) : item.heading ? collapsed ? null : berry ? (
|
|
271
|
+
/*
|
|
272
|
+
* berry: Berry's NavGroup caption — sentence case, 0.875rem/500 in
|
|
273
|
+
* the heading ink, and a divider CLOSING the previous group rather
|
|
274
|
+
* than opening this one (Berry rules under each group).
|
|
275
|
+
*/
|
|
276
|
+
/* @__PURE__ */ jsxs(Box, { component: "li", sx: { listStyle: "none" }, children: [
|
|
277
|
+
i === 0 ? null : /* @__PURE__ */ jsx(Divider, { sx: { mt: 0.25, mb: 1.25 } }),
|
|
278
|
+
/* @__PURE__ */ jsx(Typography, { component: "div", sx: { fontSize: "0.875rem", fontWeight: 500, color: "var(--mui-palette-text-heading, inherit)", p: 0.75, mt: i === 0 ? 1.25 : 0, mb: 0.5 }, children: item.heading })
|
|
279
|
+
] }, `heading-${item.heading}`)
|
|
280
|
+
) : /* @__PURE__ */ jsx(
|
|
281
|
+
ListSubheader,
|
|
282
|
+
{
|
|
283
|
+
disableSticky: true,
|
|
284
|
+
sx: {
|
|
285
|
+
bgcolor: "transparent",
|
|
286
|
+
color: "text.secondary",
|
|
287
|
+
fontWeight: 700,
|
|
288
|
+
textTransform: "uppercase",
|
|
289
|
+
lineHeight: 2.2,
|
|
290
|
+
mt: i === 0 ? 0 : 1.5,
|
|
291
|
+
// 'quiet' and 'bar' both align headings with their full-bleed
|
|
292
|
+
// rows and speak even smaller; 'rail' and 'ruled' keep the
|
|
293
|
+
// padded-list metrics.
|
|
294
|
+
...nav === "quiet" || nav === "bar" ? { fontSize: "0.64rem", letterSpacing: "0.1em", px: 2.5 } : { fontSize: "0.68rem", letterSpacing: "0.08em", px: 1.5 }
|
|
295
|
+
},
|
|
296
|
+
children: item.heading
|
|
297
|
+
},
|
|
298
|
+
`heading-${item.heading}`
|
|
299
|
+
) : (() => {
|
|
300
|
+
const kids = item.children ?? [];
|
|
301
|
+
const open = toggled[item.label] ?? kids.some((c) => c.selected);
|
|
302
|
+
return /* @__PURE__ */ jsx(Box, { component: "li", sx: { display: "block" }, children: /* @__PURE__ */ jsxs(List, { disablePadding: true, children: [
|
|
303
|
+
/* @__PURE__ */ jsx(
|
|
304
|
+
NavRow,
|
|
305
|
+
{
|
|
306
|
+
item,
|
|
307
|
+
open,
|
|
308
|
+
onToggle: () => setToggled((s) => ({ ...s, [item.label]: !open })),
|
|
309
|
+
collapsed,
|
|
310
|
+
onExpand
|
|
311
|
+
}
|
|
312
|
+
),
|
|
313
|
+
kids.length && !collapsed ? /* @__PURE__ */ jsx(Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsx(List, { disablePadding: true, children: kids.map((child) => /* @__PURE__ */ jsx(Box, { sx: { pl: 2 }, children: /* @__PURE__ */ jsx(NavRow, { item: { ...child, sub: true }, open: false, onToggle: () => {
|
|
314
|
+
} }) }, child.label)) }) }) : null
|
|
315
|
+
] }) }, item.href ?? `group:${item.label}`);
|
|
316
|
+
})()
|
|
317
|
+
)) }),
|
|
318
|
+
footer && !collapsed ? /* @__PURE__ */ jsx(Box, { sx: { mt: "auto", p: 2, pt: 3 }, children: footer }) : null
|
|
319
|
+
] })
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
function DashboardLayout({
|
|
323
|
+
title,
|
|
324
|
+
titleHelp = null,
|
|
325
|
+
logoUrl = null,
|
|
326
|
+
navItems = [],
|
|
327
|
+
user = null,
|
|
328
|
+
onSignOut,
|
|
329
|
+
homeLink = null,
|
|
330
|
+
actions = null,
|
|
331
|
+
search = null,
|
|
332
|
+
notifications = null,
|
|
333
|
+
drawerFooter = null,
|
|
334
|
+
children
|
|
335
|
+
}) {
|
|
336
|
+
const brand = useBrand();
|
|
337
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
338
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
339
|
+
const [collapsed, setCollapsed] = useState(() => {
|
|
340
|
+
if (typeof window === "undefined") return false;
|
|
341
|
+
try {
|
|
342
|
+
return window.localStorage.getItem(NAV_COLLAPSED_KEY) === "1";
|
|
343
|
+
} catch {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
const setCollapsedRemembered = (next) => {
|
|
348
|
+
setCollapsed(next);
|
|
349
|
+
try {
|
|
350
|
+
window.localStorage.setItem(NAV_COLLAPSED_KEY, next ? "1" : "0");
|
|
351
|
+
} catch {
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
const t = useTranslations("uikit");
|
|
355
|
+
const theme = useTheme();
|
|
356
|
+
const rtUi = theme.rt?.ui ?? {};
|
|
357
|
+
const berry = rtUi.chrome === "berry";
|
|
358
|
+
const barH = theme.rt?.barHeight ?? APPBAR_H;
|
|
359
|
+
const navStyle = rtUi.nav;
|
|
360
|
+
const inverseNav = navStyle === "inverse" || navStyle === "rail";
|
|
361
|
+
const floatingNav = !inverseNav && Boolean(rtUi.navFloat);
|
|
362
|
+
const collapsible = !inverseNav && Boolean(rtUi.navCollapsible);
|
|
363
|
+
const mini = collapsible && collapsed;
|
|
364
|
+
const drawerW = mini ? MINI_WIDTH : DRAWER_WIDTH;
|
|
365
|
+
const colW = floatingNav ? drawerW + NAV_GAP * 2 : drawerW;
|
|
366
|
+
const barFloat = !inverseNav && Boolean(rtUi.barFloat);
|
|
367
|
+
return /* @__PURE__ */ jsxs(Box, { sx: [{ display: "flex", minHeight: "100dvh" }, berry && ((t2) => ({ backgroundColor: t2.rt?.chrome?.light ?? t2.vars.palette.background.paper, ...t2.applyStyles("dark", { backgroundColor: t2.rt?.chrome?.dark ?? t2.vars.palette.background.paper }) }))], children: [
|
|
368
|
+
/* @__PURE__ */ jsx(
|
|
369
|
+
Box,
|
|
370
|
+
{
|
|
371
|
+
component: "a",
|
|
372
|
+
href: "#rt-main",
|
|
373
|
+
sx: {
|
|
374
|
+
position: "absolute",
|
|
375
|
+
left: 8,
|
|
376
|
+
top: -64,
|
|
377
|
+
zIndex: (t2) => t2.zIndex.drawer + 3,
|
|
378
|
+
px: 2,
|
|
379
|
+
py: 1,
|
|
380
|
+
borderRadius: 1,
|
|
381
|
+
bgcolor: "background.paper",
|
|
382
|
+
color: "text.primary",
|
|
383
|
+
boxShadow: 3,
|
|
384
|
+
transition: "top 120ms",
|
|
385
|
+
"&:focus-visible": { top: 8 }
|
|
386
|
+
},
|
|
387
|
+
children: t("nav.skipToContent")
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
/* @__PURE__ */ jsx(
|
|
391
|
+
AppBar,
|
|
392
|
+
{
|
|
393
|
+
position: "fixed",
|
|
394
|
+
"data-bar-float": barFloat ? "true" : void 0,
|
|
395
|
+
sx: (t2) => {
|
|
396
|
+
if (inverseNav) return { zIndex: t2.zIndex.drawer - 1, pl: { md: `${DRAWER_WIDTH}px` } };
|
|
397
|
+
if (barFloat) {
|
|
398
|
+
const pad = t2.spacing(3);
|
|
399
|
+
return {
|
|
400
|
+
zIndex: t2.zIndex.drawer + 1,
|
|
401
|
+
top: NAV_GAP,
|
|
402
|
+
right: pad,
|
|
403
|
+
left: { xs: pad, md: `calc(${colW}px + ${pad})` },
|
|
404
|
+
width: "auto",
|
|
405
|
+
borderRadius: `${t2.rt?.radii?.card ?? 16}px`,
|
|
406
|
+
boxShadow: `0 6px 20px -12px rgba(${t2.vars.palette.primary.mainChannel} / 0.30), 0 2px 8px rgba(0,0,0,0.06)`
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
return { zIndex: t2.zIndex.drawer + 1 };
|
|
410
|
+
},
|
|
411
|
+
children: /* @__PURE__ */ jsxs(Toolbar, { sx: berry ? { gap: 1, minHeight: `${barH}px !important`, px: 2 } : { gap: 1 }, children: [
|
|
412
|
+
/* @__PURE__ */ jsx(
|
|
413
|
+
IconButton,
|
|
414
|
+
{
|
|
415
|
+
edge: "start",
|
|
416
|
+
onClick: () => setMobileOpen(true),
|
|
417
|
+
sx: { display: { md: "none" } },
|
|
418
|
+
"aria-label": t("shell.openNav"),
|
|
419
|
+
children: /* @__PURE__ */ jsx(MenuIcon, {})
|
|
420
|
+
}
|
|
421
|
+
),
|
|
422
|
+
collapsible ? /* @__PURE__ */ jsx(
|
|
423
|
+
IconButton,
|
|
424
|
+
{
|
|
425
|
+
onClick: () => setCollapsedRemembered(!collapsed),
|
|
426
|
+
sx: [
|
|
427
|
+
{ display: { xs: "none", md: "inline-flex" } },
|
|
428
|
+
berry && ((t2) => ({
|
|
429
|
+
order: 1,
|
|
430
|
+
width: 34,
|
|
431
|
+
height: 34,
|
|
432
|
+
borderRadius: "8px",
|
|
433
|
+
color: t2.vars.palette.primary.dark,
|
|
434
|
+
backgroundColor: `rgba(${t2.vars.palette.primary.mainChannel} / 0.12)`,
|
|
435
|
+
"&:hover": { color: t2.vars.palette.primary.contrastText, backgroundColor: t2.vars.palette.primary.dark },
|
|
436
|
+
"& svg": { fontSize: 20 }
|
|
437
|
+
}))
|
|
438
|
+
],
|
|
439
|
+
"aria-label": mini ? "Expand navigation" : "Collapse navigation",
|
|
440
|
+
children: mini ? /* @__PURE__ */ jsx(MenuIcon, {}) : /* @__PURE__ */ jsx(MenuOpenIcon, {})
|
|
441
|
+
}
|
|
442
|
+
) : null,
|
|
443
|
+
/* @__PURE__ */ jsxs(Box, { sx: { flexGrow: berry ? 0 : 1, ...berry ? { minWidth: { md: 186 }, maxWidth: { md: 300 }, mr: 1, order: 0 } : null, minWidth: 0, display: "flex", alignItems: "center", gap: 1, overflow: "hidden", ...inverseNav ? { visibility: { md: "hidden" } } : null }, children: [
|
|
444
|
+
logoUrl ? /* @__PURE__ */ jsx(BrandMark, { size: 26, logoUrl, alt: "" }) : null,
|
|
445
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", component: "div", noWrap: true, sx: { minWidth: 0 }, children: title }),
|
|
446
|
+
/* @__PURE__ */ jsx(HeadingHelp, { text: titleHelp, label: typeof title === "string" ? title : void 0, color: "inherit" })
|
|
447
|
+
] }),
|
|
448
|
+
berry ? /* @__PURE__ */ jsx(Box, { sx: { order: 2, ml: 2, display: { xs: "none", md: "flex" }, alignItems: "center", minWidth: 0 }, children: search }) : search,
|
|
449
|
+
berry ? /* @__PURE__ */ jsx(Box, { sx: { order: 3, flexGrow: 1 } }) : null,
|
|
450
|
+
/* @__PURE__ */ jsxs(Box, { sx: berry ? { order: 4, display: "flex", alignItems: "center", gap: 1 } : { display: "contents" }, children: [
|
|
451
|
+
notifications,
|
|
452
|
+
actions,
|
|
453
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: { xs: "none", sm: "contents" } }, children: [
|
|
454
|
+
/* @__PURE__ */ jsx(LanguageSwitcher, {}),
|
|
455
|
+
/* @__PURE__ */ jsx(ModeToggle, {})
|
|
456
|
+
] })
|
|
457
|
+
] }),
|
|
458
|
+
user ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
459
|
+
berry ? (
|
|
460
|
+
/*
|
|
461
|
+
* Berry's ProfileSection: a 48px chip in the data hue's wash —
|
|
462
|
+
* the avatar and a dropdown caret — that opens the account menu.
|
|
463
|
+
* The caret was a settings cog in CodedThemes' original, but a
|
|
464
|
+
* cog beside the account read as a link to Settings and opened
|
|
465
|
+
* the account dropdown instead; the caret says "menu", which is
|
|
466
|
+
* what this is. (Settings has its own gear in the bar's actions.)
|
|
467
|
+
*/
|
|
468
|
+
/* @__PURE__ */ jsxs(
|
|
469
|
+
ButtonBase,
|
|
470
|
+
{
|
|
471
|
+
onClick: (e) => setAnchorEl(e.currentTarget),
|
|
472
|
+
"aria-label": t("shell.accountMenu"),
|
|
473
|
+
sx: (t2) => ({
|
|
474
|
+
order: 5,
|
|
475
|
+
ml: 1,
|
|
476
|
+
height: 48,
|
|
477
|
+
pl: 0.75,
|
|
478
|
+
pr: 1.5,
|
|
479
|
+
gap: 1,
|
|
480
|
+
borderRadius: "27px",
|
|
481
|
+
border: `1px solid rgba(${t2.vars.palette.secondary.mainChannel} / 0.12)`,
|
|
482
|
+
backgroundColor: `rgba(${t2.vars.palette.secondary.mainChannel} / 0.12)`,
|
|
483
|
+
color: t2.vars.palette.secondary.main,
|
|
484
|
+
transition: "all .2s ease-in-out",
|
|
485
|
+
"&:hover": { backgroundColor: t2.vars.palette.secondary.main, color: t2.vars.palette.secondary.contrastText }
|
|
486
|
+
}),
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ jsx(Avatar, { sx: { width: 34, height: 34, fontSize: 14, color: "#fff", backgroundImage: "linear-gradient(135deg, var(--rt-grad-from), var(--rt-grad-to))" }, children: (user.email || "?")[0].toUpperCase() }),
|
|
489
|
+
/* @__PURE__ */ jsx(ExpandMoreIcon, { fontSize: "small" })
|
|
490
|
+
]
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
) : /* @__PURE__ */ jsx(IconButton, { onClick: (e) => setAnchorEl(e.currentTarget), size: "small", "aria-label": t("shell.accountMenu"), children: /* @__PURE__ */ jsx(Avatar, { sx: { width: 30, height: 30, fontSize: 14, color: "#fff", backgroundImage: "linear-gradient(135deg, var(--rt-grad-from), var(--rt-grad-to))" }, children: (user.email || "?")[0].toUpperCase() }) }),
|
|
494
|
+
/* @__PURE__ */ jsxs(Menu, { anchorEl, open: Boolean(anchorEl), onClose: () => setAnchorEl(null), children: [
|
|
495
|
+
/* @__PURE__ */ jsx(MenuItem, { disabled: true, sx: { opacity: "1 !important" }, children: /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary" }, children: user.email }) }),
|
|
496
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
497
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: { xs: "block", sm: "none" } }, children: [
|
|
498
|
+
/* @__PURE__ */ jsxs(MenuItem, { disableRipple: true, sx: { gap: 1, justifyContent: "flex-start" }, children: [
|
|
499
|
+
/* @__PURE__ */ jsx(LanguageSwitcher, {}),
|
|
500
|
+
/* @__PURE__ */ jsx(ModeToggle, {})
|
|
501
|
+
] }),
|
|
502
|
+
/* @__PURE__ */ jsx(Divider, {})
|
|
503
|
+
] }),
|
|
504
|
+
homeLink ? /* @__PURE__ */ jsx(MenuItem, { component: Link, href: homeLink.href, onClick: () => setAnchorEl(null), children: /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, children: [
|
|
505
|
+
/* @__PURE__ */ jsx(ApartmentOutlinedIcon, { fontSize: "small" }),
|
|
506
|
+
/* @__PURE__ */ jsx("span", { children: homeLink.label })
|
|
507
|
+
] }) }) : null,
|
|
508
|
+
/* @__PURE__ */ jsx(MenuItem, { onClick: () => {
|
|
509
|
+
setAnchorEl(null);
|
|
510
|
+
onSignOut?.();
|
|
511
|
+
}, children: /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, children: [
|
|
512
|
+
/* @__PURE__ */ jsx(LogoutOutlinedIcon, { fontSize: "small" }),
|
|
513
|
+
/* @__PURE__ */ jsx("span", { children: t("account.signOut") })
|
|
514
|
+
] }) })
|
|
515
|
+
] })
|
|
516
|
+
] }) : null
|
|
517
|
+
] })
|
|
518
|
+
}
|
|
519
|
+
),
|
|
520
|
+
/* @__PURE__ */ jsx(
|
|
521
|
+
Drawer,
|
|
522
|
+
{
|
|
523
|
+
variant: "temporary",
|
|
524
|
+
open: mobileOpen,
|
|
525
|
+
onClose: () => setMobileOpen(false),
|
|
526
|
+
ModalProps: { keepMounted: true },
|
|
527
|
+
sx: { display: { xs: "block", md: "none" }, zIndex: (t2) => t2.zIndex.drawer + 2 },
|
|
528
|
+
children: /* @__PURE__ */ jsxs(Box, { onClick: (e) => {
|
|
529
|
+
if (e.target.closest("a")) setMobileOpen(false);
|
|
530
|
+
}, children: [
|
|
531
|
+
/* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "flex-end", p: 1 }, children: /* @__PURE__ */ jsx(IconButton, { onClick: () => setMobileOpen(false), size: "small", "aria-label": t("nav.close"), children: /* @__PURE__ */ jsx(CloseRoundedIcon, { fontSize: "small" }) }) }),
|
|
532
|
+
/* @__PURE__ */ jsx(NavList, { navItems, brand: inverseNav ? { logoUrl, title } : null, footer: drawerFooter, barHeight: barH })
|
|
533
|
+
] })
|
|
534
|
+
}
|
|
535
|
+
),
|
|
536
|
+
/* @__PURE__ */ jsx(
|
|
537
|
+
Drawer,
|
|
538
|
+
{
|
|
539
|
+
variant: "permanent",
|
|
540
|
+
"data-float": floatingNav ? "true" : void 0,
|
|
541
|
+
"data-collapsed": mini ? "true" : void 0,
|
|
542
|
+
sx: {
|
|
543
|
+
display: { xs: "none", md: "block" },
|
|
544
|
+
// The floating column reserves a gap on BOTH sides — the paper insets
|
|
545
|
+
// by NAV_GAP on the left, so widen the column by 2× to keep a matching
|
|
546
|
+
// gap between the panel and the content. `drawerW` shrinks both the
|
|
547
|
+
// column and the paper when the rail is collapsed.
|
|
548
|
+
width: floatingNav ? drawerW + NAV_GAP * 2 : drawerW,
|
|
549
|
+
flexShrink: 0,
|
|
550
|
+
// The width animates so collapsing/expanding glides rather than jumps.
|
|
551
|
+
"& .MuiDrawer-paper": floatingNav ? {
|
|
552
|
+
width: drawerW,
|
|
553
|
+
boxSizing: "border-box",
|
|
554
|
+
transition: "width 180ms ease",
|
|
555
|
+
// Detach from the edges: below the bar, inset left, lifted off
|
|
556
|
+
// the bottom, with rounded corners and a soft shadow. height:auto
|
|
557
|
+
// lets top+bottom drive the height so it never runs to the edge.
|
|
558
|
+
left: NAV_GAP,
|
|
559
|
+
// Below the full-width bar normally; but when the bar ALSO floats
|
|
560
|
+
// it sits beside this panel, so the panel runs full height.
|
|
561
|
+
top: barFloat ? NAV_GAP : `calc(${APPBAR_H}px + ${NAV_GAP}px)`,
|
|
562
|
+
bottom: NAV_GAP,
|
|
563
|
+
height: "auto",
|
|
564
|
+
border: 0,
|
|
565
|
+
borderRadius: (t2) => `${t2.rt?.radii?.card ?? 16}px`,
|
|
566
|
+
boxShadow: (t2) => `0 10px 30px -14px rgba(${t2.vars.palette.primary.mainChannel} / 0.30), 0 2px 8px rgba(0,0,0,0.06)`,
|
|
567
|
+
overflowY: "auto"
|
|
568
|
+
} : { width: drawerW, boxSizing: "border-box", transition: "width 180ms ease" }
|
|
569
|
+
},
|
|
570
|
+
open: true,
|
|
571
|
+
children: /* @__PURE__ */ jsx(
|
|
572
|
+
NavList,
|
|
573
|
+
{
|
|
574
|
+
navItems,
|
|
575
|
+
brand: inverseNav ? { logoUrl, title } : null,
|
|
576
|
+
floating: floatingNav,
|
|
577
|
+
collapsed: mini,
|
|
578
|
+
onExpand: () => setCollapsedRemembered(false),
|
|
579
|
+
footer: drawerFooter,
|
|
580
|
+
barHeight: barH
|
|
581
|
+
}
|
|
582
|
+
)
|
|
583
|
+
}
|
|
584
|
+
),
|
|
585
|
+
berry ? (
|
|
586
|
+
/*
|
|
587
|
+
* Berry's MainContentStyled: the well. Grey ground (background.default),
|
|
588
|
+
* 20px padding, a 20px right margin, rounded TOP corners only, starting
|
|
589
|
+
* under the 88px bar and running to the bottom. The root paints the
|
|
590
|
+
* chrome colour so the corners read against it.
|
|
591
|
+
*/
|
|
592
|
+
/* @__PURE__ */ jsxs(
|
|
593
|
+
Box,
|
|
594
|
+
{
|
|
595
|
+
component: "main",
|
|
596
|
+
id: "rt-main",
|
|
597
|
+
tabIndex: -1,
|
|
598
|
+
sx: {
|
|
599
|
+
flexGrow: 1,
|
|
600
|
+
minWidth: 0,
|
|
601
|
+
mt: `${barH}px`,
|
|
602
|
+
mr: { xs: 1.25, md: 2.5 },
|
|
603
|
+
ml: { xs: 1.25, md: 0 },
|
|
604
|
+
p: { xs: 2, md: 2.5 },
|
|
605
|
+
minHeight: `calc(100dvh - ${barH}px)`,
|
|
606
|
+
bgcolor: "background.default",
|
|
607
|
+
borderRadius: `${theme.rt?.radii?.card ?? 8}px ${theme.rt?.radii?.card ?? 8}px 0 0`,
|
|
608
|
+
display: "flex",
|
|
609
|
+
flexDirection: "column"
|
|
610
|
+
},
|
|
611
|
+
children: [
|
|
612
|
+
/* @__PURE__ */ jsx(Box, { sx: { flexGrow: 1 }, children }),
|
|
613
|
+
brand.copyright ? /* @__PURE__ */ jsx(Box, { sx: { pt: 3, mt: "auto" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "caption", sx: { color: "text.secondary" }, children: [
|
|
614
|
+
"\xA9 ",
|
|
615
|
+
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
616
|
+
" ",
|
|
617
|
+
brand.copyright
|
|
618
|
+
] }) }) : null
|
|
619
|
+
]
|
|
620
|
+
}
|
|
621
|
+
)
|
|
622
|
+
) : /* @__PURE__ */ jsxs(
|
|
623
|
+
Box,
|
|
624
|
+
{
|
|
625
|
+
component: "main",
|
|
626
|
+
id: "rt-main",
|
|
627
|
+
tabIndex: -1,
|
|
628
|
+
sx: { flexGrow: 1, p: 3, minWidth: 0, display: "flex", flexDirection: "column" },
|
|
629
|
+
children: [
|
|
630
|
+
/* @__PURE__ */ jsx(Toolbar, {}),
|
|
631
|
+
/* @__PURE__ */ jsx(Box, { sx: { flexGrow: 1 }, children }),
|
|
632
|
+
brand.copyright ? /* @__PURE__ */ jsx(Box, { sx: { pt: 3, mt: "auto" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "caption", sx: { color: "text.secondary" }, children: [
|
|
633
|
+
"\xA9 ",
|
|
634
|
+
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
635
|
+
" ",
|
|
636
|
+
brand.copyright
|
|
637
|
+
] }) }) : null
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
)
|
|
641
|
+
] });
|
|
642
|
+
}
|
|
643
|
+
export {
|
|
644
|
+
DashboardLayout as default
|
|
645
|
+
};
|