@wikex/admin-kit 0.4.0 → 0.5.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 +6 -0
- package/README.md +3 -3
- package/dist/admin/before-login.js +2 -2
- package/dist/admin/brand.js +1 -1
- package/dist/admin/header.js +53 -137
- package/dist/admin/nav-client.js +147 -87
- package/dist/{chunk-AY7N3B45.js → chunk-SM6CCKQQ.js} +5 -5
- package/dist/starter-client.js +1 -1
- package/package.json +1 -1
- package/src/styles/admin.scss +0 -3
- package/src/styles/_minimal-dashboard.scss +0 -724
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Các thay đổi đáng chú ý của `@wikex/admin-kit` được ghi tại đây theo Semantic Versioning.
|
|
4
4
|
|
|
5
|
+
## 0.5.0 - 2026-09-13
|
|
6
|
+
|
|
7
|
+
- Hoàn thiện admin shell Minimal với navigation mini/mobile, workspace header và account actions.
|
|
8
|
+
- Giữ đúng client boundary của Payload trong các admin component được build để publish.
|
|
9
|
+
- Phát hành project route và component scanner cho các project consumer.
|
|
10
|
+
|
|
5
11
|
## 0.4.0 - 2026-09-13
|
|
6
12
|
|
|
7
13
|
- Thay admin shell cũ bằng dashboard layout dựa trên Minimal TypeScript 7.6.1.
|
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ Admin shell dùng chung cho các website Payload CMS của Wikex.
|
|
|
4
4
|
|
|
5
5
|
Package sở hữu:
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
7
|
+
- navigation, header, đăng nhập, đổi theme và branding động;
|
|
8
|
+
- Minimal UI skin và các bản vá layout Payload;
|
|
9
9
|
- Live Preview editor, drawer thuộc tính, block picker và resize text;
|
|
10
10
|
- font family, line-height và runtime áp dụng typography;
|
|
11
11
|
- chuẩn hóa tiếng Việt và hướng dẫn kích thước upload ảnh.
|
|
@@ -104,7 +104,7 @@ Xem consumer không thuộc lĩnh vực bất động sản tại `examples/corp
|
|
|
104
104
|
## Cài vào dự án khác — một package, một cấu hình
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
|
-
pnpm add @wikex/admin-kit@0.
|
|
107
|
+
pnpm add @wikex/admin-kit@0.5.0
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
Không cần `.npmrc`, GitLab token hay npm token ở dự án consumer. Các peer dependency
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
var BeforeLogin = () => {
|
|
10
10
|
const { siteName } = useAdminBrand();
|
|
11
|
-
return /* @__PURE__ */ jsxs("div", { className: "
|
|
12
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
11
|
+
return /* @__PURE__ */ jsxs("div", { className: "admin-login-intro", children: [
|
|
12
|
+
/* @__PURE__ */ jsxs("span", { className: "admin-login-intro__eyebrow", children: [
|
|
13
13
|
siteName,
|
|
14
14
|
" \xB7 Trung t\xE2m n\u1ED9i dung"
|
|
15
15
|
] }),
|
package/dist/admin/brand.js
CHANGED
package/dist/admin/header.js
CHANGED
|
@@ -1,178 +1,94 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
"use client";
|
|
3
|
-
import {
|
|
4
|
-
LogoutButton_default
|
|
5
|
-
} from "../chunk-GZ2B5BTH.js";
|
|
6
3
|
import {
|
|
7
4
|
AdminIcon
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import
|
|
10
|
-
useAdminBrand
|
|
11
|
-
} from "../chunk-X7VETFVD.js";
|
|
5
|
+
} from "../chunk-SM6CCKQQ.js";
|
|
6
|
+
import "../chunk-X7VETFVD.js";
|
|
12
7
|
import {
|
|
13
8
|
ThemeToggle_default
|
|
14
9
|
} from "../chunk-SAI5SWZA.js";
|
|
15
10
|
|
|
16
11
|
// src/admin/Header.tsx
|
|
17
|
-
import { Link
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
// src/admin/AccountDrawer.tsx
|
|
21
|
-
import { Link, useAuth, useConfig } from "@payloadcms/ui";
|
|
22
|
-
import { Settings2, X } from "lucide-react";
|
|
23
|
-
import { usePathname } from "next/navigation";
|
|
12
|
+
import { Link, useAuth, useConfig, useNav } from "@payloadcms/ui";
|
|
13
|
+
import { Menu, Settings2 } from "lucide-react";
|
|
24
14
|
import { formatAdminURL } from "payload/shared";
|
|
25
|
-
import { useEffect, useMemo, useState } from "react";
|
|
26
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
27
|
-
var getInitials = (name, email) => {
|
|
28
|
-
const source = name?.trim() || email?.split("@")[0] || "AD";
|
|
29
|
-
return source.split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
30
|
-
};
|
|
31
|
-
var AccountDrawer = () => {
|
|
32
|
-
const pathname = usePathname();
|
|
33
|
-
const { user } = useAuth();
|
|
34
|
-
const {
|
|
35
|
-
config: {
|
|
36
|
-
admin: { routes: adminRoutes },
|
|
37
|
-
routes: { admin: adminRoute }
|
|
38
|
-
}
|
|
39
|
-
} = useConfig();
|
|
40
|
-
const [open, setOpen] = useState(false);
|
|
41
|
-
const userLabel = user?.name?.trim() || user?.email?.split("@")[0] || "Qu\u1EA3n tr\u1ECB vi\xEAn";
|
|
42
|
-
const initials = useMemo(() => getInitials(user?.name, user?.email), [user?.email, user?.name]);
|
|
43
|
-
useEffect(() => setOpen(false), [pathname]);
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
if (!open) return;
|
|
46
|
-
const closeOnEscape = (event) => {
|
|
47
|
-
if (event.key === "Escape") setOpen(false);
|
|
48
|
-
};
|
|
49
|
-
window.addEventListener("keydown", closeOnEscape);
|
|
50
|
-
return () => window.removeEventListener("keydown", closeOnEscape);
|
|
51
|
-
}, [open]);
|
|
52
|
-
return /* @__PURE__ */ jsxs("div", { className: `wikex-account-drawer ${open ? "wikex-account-drawer--open" : ""}`, children: [
|
|
53
|
-
/* @__PURE__ */ jsx(
|
|
54
|
-
"button",
|
|
55
|
-
{
|
|
56
|
-
"aria-expanded": open,
|
|
57
|
-
"aria-label": `M\u1EDF t\xE0i kho\u1EA3n ${userLabel}`,
|
|
58
|
-
className: "wikex-account-button",
|
|
59
|
-
onClick: () => setOpen(true),
|
|
60
|
-
title: userLabel,
|
|
61
|
-
type: "button",
|
|
62
|
-
children: /* @__PURE__ */ jsx("span", { children: initials })
|
|
63
|
-
}
|
|
64
|
-
),
|
|
65
|
-
/* @__PURE__ */ jsx(
|
|
66
|
-
"button",
|
|
67
|
-
{
|
|
68
|
-
"aria-label": "\u0110\xF3ng t\xE0i kho\u1EA3n",
|
|
69
|
-
className: "wikex-account-drawer__backdrop",
|
|
70
|
-
onClick: () => setOpen(false),
|
|
71
|
-
tabIndex: open ? 0 : -1,
|
|
72
|
-
type: "button"
|
|
73
|
-
}
|
|
74
|
-
),
|
|
75
|
-
/* @__PURE__ */ jsxs(
|
|
76
|
-
"aside",
|
|
77
|
-
{
|
|
78
|
-
"aria-hidden": !open,
|
|
79
|
-
"aria-label": "T\xE0i kho\u1EA3n qu\u1EA3n tr\u1ECB",
|
|
80
|
-
"aria-modal": "true",
|
|
81
|
-
className: "wikex-account-drawer__panel",
|
|
82
|
-
role: "dialog",
|
|
83
|
-
children: [
|
|
84
|
-
/* @__PURE__ */ jsx(
|
|
85
|
-
"button",
|
|
86
|
-
{
|
|
87
|
-
"aria-label": "\u0110\xF3ng",
|
|
88
|
-
className: "wikex-account-drawer__close",
|
|
89
|
-
onClick: () => setOpen(false),
|
|
90
|
-
tabIndex: open ? 0 : -1,
|
|
91
|
-
type: "button",
|
|
92
|
-
children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
|
|
93
|
-
}
|
|
94
|
-
),
|
|
95
|
-
/* @__PURE__ */ jsxs("div", { className: "wikex-account-drawer__profile", children: [
|
|
96
|
-
/* @__PURE__ */ jsx("span", { className: "wikex-account-drawer__avatar", children: initials }),
|
|
97
|
-
/* @__PURE__ */ jsx("strong", { children: userLabel }),
|
|
98
|
-
/* @__PURE__ */ jsx("small", { children: user?.email || "T\xE0i kho\u1EA3n qu\u1EA3n tr\u1ECB" })
|
|
99
|
-
] }),
|
|
100
|
-
/* @__PURE__ */ jsx("div", { className: "wikex-account-drawer__menu", children: /* @__PURE__ */ jsxs(
|
|
101
|
-
Link,
|
|
102
|
-
{
|
|
103
|
-
className: "wikex-account-drawer__link",
|
|
104
|
-
href: formatAdminURL({ adminRoute, path: adminRoutes.account }),
|
|
105
|
-
prefetch: false,
|
|
106
|
-
tabIndex: open ? 0 : -1,
|
|
107
|
-
children: [
|
|
108
|
-
/* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true" }),
|
|
109
|
-
"C\xE0i \u0111\u1EB7t t\xE0i kho\u1EA3n"
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
) }),
|
|
113
|
-
/* @__PURE__ */ jsx("div", { className: "wikex-account-drawer__footer", children: /* @__PURE__ */ jsx(LogoutButton_default, { tabIndex: open ? 0 : -1 }) })
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
)
|
|
117
|
-
] });
|
|
118
|
-
};
|
|
119
|
-
var AccountDrawer_default = AccountDrawer;
|
|
120
15
|
|
|
121
16
|
// src/admin/ViewSite.tsx
|
|
122
17
|
import { ArrowUpRight } from "lucide-react";
|
|
123
|
-
import { jsx
|
|
124
|
-
var AdminViewSite = () => /* @__PURE__ */
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
var AdminViewSite = () => /* @__PURE__ */ jsxs("a", { className: "admin-view-site", "data-slot": "button", href: "/", rel: "noreferrer", target: "_blank", children: [
|
|
125
20
|
"Xem website",
|
|
126
|
-
/* @__PURE__ */
|
|
21
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": "true" })
|
|
127
22
|
] });
|
|
128
23
|
var ViewSite_default = AdminViewSite;
|
|
129
24
|
|
|
130
25
|
// src/admin/Header.tsx
|
|
131
|
-
import { jsx as
|
|
26
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
27
|
+
var getInitials = (name, email) => {
|
|
28
|
+
const source = name?.trim() || email?.split("@")[0] || "AD";
|
|
29
|
+
return source.split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
30
|
+
};
|
|
132
31
|
var AdminHeader = () => {
|
|
133
|
-
const
|
|
32
|
+
const { user } = useAuth();
|
|
134
33
|
const { setNavOpen } = useNav();
|
|
135
34
|
const {
|
|
136
35
|
config: {
|
|
36
|
+
admin: { routes: adminRoutes },
|
|
137
37
|
routes: { admin: adminRoute }
|
|
138
38
|
}
|
|
139
|
-
} =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
39
|
+
} = useConfig();
|
|
40
|
+
const userLabel = user?.name?.trim() || user?.email?.split("@")[0] || "Qu\u1EA3n tr\u1ECB vi\xEAn";
|
|
41
|
+
const initials = getInitials(user?.name, user?.email);
|
|
42
|
+
return /* @__PURE__ */ jsxs2("header", { className: "minimal-admin-header", children: [
|
|
43
|
+
/* @__PURE__ */ jsxs2("div", { className: "minimal-admin-header__left", children: [
|
|
44
|
+
/* @__PURE__ */ jsx2(
|
|
143
45
|
"button",
|
|
144
46
|
{
|
|
145
47
|
"aria-label": "M\u1EDF menu qu\u1EA3n tr\u1ECB",
|
|
146
|
-
className: "
|
|
48
|
+
className: "minimal-admin-header__menu",
|
|
147
49
|
onClick: () => setNavOpen(true),
|
|
148
50
|
type: "button",
|
|
149
|
-
children: /* @__PURE__ */
|
|
51
|
+
children: /* @__PURE__ */ jsx2(Menu, { "aria-hidden": "true" })
|
|
150
52
|
}
|
|
151
53
|
),
|
|
152
|
-
/* @__PURE__ */
|
|
153
|
-
|
|
54
|
+
/* @__PURE__ */ jsx2(
|
|
55
|
+
Link,
|
|
154
56
|
{
|
|
155
57
|
"aria-label": "V\u1EC1 dashboard",
|
|
156
|
-
className: "
|
|
58
|
+
className: "minimal-admin-header__mobile-brand",
|
|
157
59
|
href: adminRoute,
|
|
158
60
|
prefetch: false,
|
|
159
|
-
children: /* @__PURE__ */
|
|
61
|
+
children: /* @__PURE__ */ jsx2(AdminIcon, {})
|
|
160
62
|
}
|
|
161
|
-
)
|
|
162
|
-
/* @__PURE__ */ jsxs3("div", { className: "wikex-dashboard-header__workspace", children: [
|
|
163
|
-
/* @__PURE__ */ jsx3("span", { className: "wikex-dashboard-header__workspace-icon", children: /* @__PURE__ */ jsx3(GalleryVerticalEnd, { "aria-hidden": "true" }) }),
|
|
164
|
-
/* @__PURE__ */ jsxs3("span", { className: "wikex-dashboard-header__workspace-copy", children: [
|
|
165
|
-
/* @__PURE__ */ jsx3("small", { children: "Kh\xF4ng gian l\xE0m vi\u1EC7c" }),
|
|
166
|
-
/* @__PURE__ */ jsx3("strong", { children: brand.siteName })
|
|
167
|
-
] })
|
|
168
|
-
] })
|
|
63
|
+
)
|
|
169
64
|
] }),
|
|
170
|
-
/* @__PURE__ */
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ jsxs2("div", { className: "minimal-admin-header__actions", children: [
|
|
66
|
+
/* @__PURE__ */ jsx2(ViewSite_default, {}),
|
|
67
|
+
/* @__PURE__ */ jsx2(ThemeToggle_default, {}),
|
|
68
|
+
/* @__PURE__ */ jsx2(
|
|
69
|
+
Link,
|
|
70
|
+
{
|
|
71
|
+
"aria-label": `M\u1EDF t\xE0i kho\u1EA3n ${userLabel}`,
|
|
72
|
+
className: "minimal-admin-header__settings",
|
|
73
|
+
href: formatAdminURL({ adminRoute, path: adminRoutes.account }),
|
|
74
|
+
prefetch: false,
|
|
75
|
+
title: "C\xE0i \u0111\u1EB7t t\xE0i kho\u1EA3n",
|
|
76
|
+
children: /* @__PURE__ */ jsx2(Settings2, { "aria-hidden": "true" })
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ jsx2(
|
|
80
|
+
Link,
|
|
81
|
+
{
|
|
82
|
+
"aria-label": `M\u1EDF t\xE0i kho\u1EA3n ${userLabel}`,
|
|
83
|
+
className: "minimal-admin-header__account",
|
|
84
|
+
href: formatAdminURL({ adminRoute, path: adminRoutes.account }),
|
|
85
|
+
prefetch: false,
|
|
86
|
+
title: userLabel,
|
|
87
|
+
children: /* @__PURE__ */ jsx2("span", { children: initials })
|
|
88
|
+
}
|
|
89
|
+
)
|
|
174
90
|
] })
|
|
175
|
-
] })
|
|
91
|
+
] });
|
|
176
92
|
};
|
|
177
93
|
var Header_default = AdminHeader;
|
|
178
94
|
export {
|
package/dist/admin/nav-client.js
CHANGED
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
import {
|
|
4
4
|
AdminIcon,
|
|
5
5
|
AdminLogo
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-SM6CCKQQ.js";
|
|
7
7
|
import {
|
|
8
8
|
useAdminBrand
|
|
9
9
|
} from "../chunk-X7VETFVD.js";
|
|
10
|
+
import {
|
|
11
|
+
LogoutButton_default
|
|
12
|
+
} from "../chunk-GZ2B5BTH.js";
|
|
10
13
|
|
|
11
14
|
// src/admin/NavClient.tsx
|
|
12
|
-
import { Link, useConfig, useNav } from "@payloadcms/ui";
|
|
15
|
+
import { Link, useAuth, useConfig, useNav } from "@payloadcms/ui";
|
|
13
16
|
import {
|
|
14
17
|
BookOpenText,
|
|
15
18
|
BriefcaseBusiness,
|
|
@@ -17,10 +20,12 @@ import {
|
|
|
17
20
|
ChevronRight,
|
|
18
21
|
FileText,
|
|
19
22
|
FolderKanban,
|
|
23
|
+
GalleryVerticalEnd,
|
|
20
24
|
Home,
|
|
21
25
|
Image,
|
|
22
26
|
LayoutDashboard,
|
|
23
27
|
Library,
|
|
28
|
+
Menu,
|
|
24
29
|
PanelBottom,
|
|
25
30
|
PanelTop,
|
|
26
31
|
Settings2,
|
|
@@ -30,7 +35,7 @@ import {
|
|
|
30
35
|
} from "lucide-react";
|
|
31
36
|
import { usePathname } from "next/navigation";
|
|
32
37
|
import { formatAdminURL } from "payload/shared";
|
|
33
|
-
import
|
|
38
|
+
import { useEffect, useMemo, useState } from "react";
|
|
34
39
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
35
40
|
var iconBySlug = {
|
|
36
41
|
categories: Tags,
|
|
@@ -46,9 +51,14 @@ var iconBySlug = {
|
|
|
46
51
|
users: Users
|
|
47
52
|
};
|
|
48
53
|
var translateGroupLabel = (label) => label === "Collections" ? "B\u1ED9 s\u01B0u t\u1EADp" : label === "Globals" ? "Thi\u1EBFt l\u1EADp chung" : label;
|
|
54
|
+
var getInitials = (name, email) => {
|
|
55
|
+
const source = name?.trim() || email?.split("@")[0] || "AD";
|
|
56
|
+
return source.split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
57
|
+
};
|
|
49
58
|
var AdminNavClient = ({ groups }) => {
|
|
50
59
|
const pathname = usePathname();
|
|
51
60
|
const brand = useAdminBrand();
|
|
61
|
+
const { user } = useAuth();
|
|
52
62
|
const { hydrated, navOpen, navRef, setNavOpen, shouldAnimate } = useNav();
|
|
53
63
|
const {
|
|
54
64
|
config: {
|
|
@@ -60,7 +70,8 @@ var AdminNavClient = ({ groups }) => {
|
|
|
60
70
|
const [isMini, setIsMini] = useState(false);
|
|
61
71
|
const [isMobile, setIsMobile] = useState(false);
|
|
62
72
|
useEffect(() => {
|
|
63
|
-
|
|
73
|
+
const storedValue = window.localStorage.getItem("minimal-admin-nav-mini");
|
|
74
|
+
setIsMini(storedValue === "true");
|
|
64
75
|
}, []);
|
|
65
76
|
useEffect(() => {
|
|
66
77
|
const mediaQuery = window.matchMedia("(max-width: 768px)");
|
|
@@ -70,119 +81,168 @@ var AdminNavClient = ({ groups }) => {
|
|
|
70
81
|
return () => mediaQuery.removeEventListener("change", syncViewport);
|
|
71
82
|
}, []);
|
|
72
83
|
useEffect(() => {
|
|
73
|
-
document.documentElement.style.setProperty(
|
|
74
|
-
|
|
75
|
-
isMini ? "var(--layout-nav-mini-width)" : "var(--layout-nav-vertical-width)"
|
|
76
|
-
);
|
|
77
|
-
window.localStorage.setItem("wikex-dashboard-nav-mini", String(isMini));
|
|
84
|
+
document.documentElement.style.setProperty("--nav-width", isMini ? "88px" : "280px");
|
|
85
|
+
window.localStorage.setItem("minimal-admin-nav-mini", String(isMini));
|
|
78
86
|
return () => {
|
|
79
87
|
document.documentElement.style.removeProperty("--nav-width");
|
|
80
88
|
};
|
|
81
89
|
}, [isMini]);
|
|
90
|
+
const userLabel = user?.name?.trim() || user?.email?.split("@")[0] || "Qu\u1EA3n tr\u1ECB vi\xEAn";
|
|
91
|
+
const initials = useMemo(() => getInitials(user?.name, user?.email), [user?.email, user?.name]);
|
|
82
92
|
const closeMobileNav = () => {
|
|
83
93
|
if (window.matchMedia("(max-width: 768px)").matches) setNavOpen(false);
|
|
84
94
|
};
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
hydrated && "wikex-dashboard-nav--hydrated"
|
|
95
|
+
const classes = [
|
|
96
|
+
"minimal-nav",
|
|
97
|
+
navOpen && "minimal-nav--open",
|
|
98
|
+
isMini && "minimal-nav--mini",
|
|
99
|
+
shouldAnimate && "minimal-nav--animate",
|
|
100
|
+
hydrated && "minimal-nav--hydrated"
|
|
92
101
|
].filter(Boolean).join(" ");
|
|
93
|
-
const
|
|
94
|
-
active,
|
|
95
|
-
href,
|
|
96
|
-
icon: Icon,
|
|
97
|
-
label
|
|
98
|
-
}) => /* @__PURE__ */ jsxs(
|
|
99
|
-
Link,
|
|
100
|
-
{
|
|
101
|
-
"aria-current": active ? "page" : void 0,
|
|
102
|
-
className: `wikex-nav-section__item ${active ? "wikex-nav-section__item--active" : ""}`,
|
|
103
|
-
href,
|
|
104
|
-
onClick: closeMobileNav,
|
|
105
|
-
prefetch: false,
|
|
106
|
-
title: label,
|
|
107
|
-
children: [
|
|
108
|
-
/* @__PURE__ */ jsx("span", { className: "wikex-nav-section__icon", children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) }),
|
|
109
|
-
/* @__PURE__ */ jsx("span", { className: "wikex-nav-section__title", children: label })
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
);
|
|
102
|
+
const isActive = (href) => pathname === href || href !== adminRoute && pathname.startsWith(`${href}/`);
|
|
113
103
|
return /* @__PURE__ */ jsxs(
|
|
114
104
|
"aside",
|
|
115
105
|
{
|
|
116
106
|
"aria-label": "\u0110i\u1EC1u h\u01B0\u1EDBng qu\u1EA3n tr\u1ECB",
|
|
117
|
-
className:
|
|
107
|
+
className: classes,
|
|
118
108
|
inert: isMobile && !navOpen || void 0,
|
|
119
109
|
children: [
|
|
120
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
110
|
+
/* @__PURE__ */ jsxs("div", { className: "minimal-nav__scroll", ref: navRef, children: [
|
|
111
|
+
/* @__PURE__ */ jsxs("div", { className: "minimal-nav__brand-row", children: [
|
|
112
|
+
/* @__PURE__ */ jsxs(
|
|
113
|
+
Link,
|
|
114
|
+
{
|
|
115
|
+
"aria-label": `V\u1EC1 dashboard ${brand.siteName}`,
|
|
116
|
+
className: "minimal-nav__brand",
|
|
117
|
+
href: adminRoute,
|
|
118
|
+
onClick: closeMobileNav,
|
|
119
|
+
prefetch: false,
|
|
120
|
+
children: [
|
|
121
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__brand-full", children: /* @__PURE__ */ jsx(AdminLogo, {}) }),
|
|
122
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__brand-icon", children: /* @__PURE__ */ jsx(AdminIcon, {}) })
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
"button",
|
|
128
|
+
{
|
|
129
|
+
"aria-label": "\u0110\xF3ng menu",
|
|
130
|
+
className: "minimal-nav__mobile-close",
|
|
131
|
+
onClick: () => setNavOpen(false),
|
|
132
|
+
type: "button",
|
|
133
|
+
children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" })
|
|
134
|
+
}
|
|
135
|
+
)
|
|
136
|
+
] }),
|
|
121
137
|
/* @__PURE__ */ jsxs(
|
|
122
138
|
Link,
|
|
123
139
|
{
|
|
124
|
-
"
|
|
125
|
-
className: "wikex-dashboard-nav__logo",
|
|
140
|
+
className: "minimal-nav__workspace",
|
|
126
141
|
href: adminRoute,
|
|
127
142
|
onClick: closeMobileNav,
|
|
128
143
|
prefetch: false,
|
|
144
|
+
title: brand.siteName,
|
|
129
145
|
children: [
|
|
130
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
131
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__workspace-icon", children: /* @__PURE__ */ jsx(GalleryVerticalEnd, { "aria-hidden": "true" }) }),
|
|
147
|
+
/* @__PURE__ */ jsxs("span", { className: "minimal-nav__workspace-copy", children: [
|
|
148
|
+
/* @__PURE__ */ jsx("small", { children: "Kh\xF4ng gian l\xE0m vi\u1EC7c" }),
|
|
149
|
+
/* @__PURE__ */ jsx("strong", { children: brand.siteName })
|
|
150
|
+
] }),
|
|
151
|
+
/* @__PURE__ */ jsx(Menu, { "aria-hidden": "true", className: "minimal-nav__workspace-menu" })
|
|
132
152
|
]
|
|
133
153
|
}
|
|
134
154
|
),
|
|
135
|
-
/* @__PURE__ */
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
/* @__PURE__ */ jsxs("nav", { className: "minimal-nav__menu", children: [
|
|
156
|
+
/* @__PURE__ */ jsxs("div", { className: "minimal-nav__group", children: [
|
|
157
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__group-label", children: "T\u1ED5ng quan" }),
|
|
158
|
+
/* @__PURE__ */ jsxs(
|
|
159
|
+
Link,
|
|
160
|
+
{
|
|
161
|
+
"aria-current": pathname === adminRoute ? "page" : void 0,
|
|
162
|
+
className: `minimal-nav__item ${pathname === adminRoute ? "minimal-nav__item--active" : ""}`,
|
|
163
|
+
href: adminRoute,
|
|
164
|
+
onClick: closeMobileNav,
|
|
165
|
+
prefetch: false,
|
|
166
|
+
title: "Dashboard",
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsx(LayoutDashboard, { "aria-hidden": "true" }),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { children: "T\u1ED5ng quan" })
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
] }),
|
|
174
|
+
groups.map((group) => /* @__PURE__ */ jsxs("div", { className: "minimal-nav__group", children: [
|
|
175
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__group-label", children: translateGroupLabel(group.label) }),
|
|
176
|
+
group.items.map((item) => {
|
|
177
|
+
const href = formatAdminURL({
|
|
178
|
+
adminRoute,
|
|
179
|
+
path: `/${item.type}/${item.slug}`
|
|
180
|
+
});
|
|
181
|
+
const Icon = iconBySlug[item.slug] || FileText;
|
|
182
|
+
const active = isActive(href);
|
|
183
|
+
return /* @__PURE__ */ jsxs(
|
|
184
|
+
Link,
|
|
185
|
+
{
|
|
186
|
+
"aria-current": active ? "page" : void 0,
|
|
187
|
+
className: `minimal-nav__item ${active ? "minimal-nav__item--active" : ""}`,
|
|
188
|
+
href,
|
|
189
|
+
onClick: closeMobileNav,
|
|
190
|
+
prefetch: false,
|
|
191
|
+
title: item.label,
|
|
192
|
+
children: [
|
|
193
|
+
/* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }),
|
|
194
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
`${item.type}-${item.slug}`
|
|
198
|
+
);
|
|
199
|
+
})
|
|
200
|
+
] }, group.label)),
|
|
201
|
+
folders && folders.browseByFolder && /* @__PURE__ */ jsxs("div", { className: "minimal-nav__group", children: [
|
|
202
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__group-label", children: "Th\u01B0 vi\u1EC7n" }),
|
|
203
|
+
/* @__PURE__ */ jsxs(
|
|
204
|
+
Link,
|
|
205
|
+
{
|
|
206
|
+
"aria-current": isActive(formatAdminURL({ adminRoute, path: adminRoutes.browseByFolder })) ? "page" : void 0,
|
|
207
|
+
className: `minimal-nav__item ${isActive(formatAdminURL({ adminRoute, path: adminRoutes.browseByFolder })) ? "minimal-nav__item--active" : ""}`,
|
|
208
|
+
href: formatAdminURL({ adminRoute, path: adminRoutes.browseByFolder }),
|
|
209
|
+
onClick: closeMobileNav,
|
|
210
|
+
prefetch: false,
|
|
211
|
+
title: "Duy\u1EC7t theo th\u01B0 m\u1EE5c",
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ jsx(Library, { "aria-hidden": "true" }),
|
|
214
|
+
/* @__PURE__ */ jsx("span", { children: "Duy\u1EC7t theo th\u01B0 m\u1EE5c" })
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
] })
|
|
155
219
|
] }),
|
|
156
|
-
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
path:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
href: formatAdminURL({ adminRoute, path: adminRoutes.browseByFolder }),
|
|
176
|
-
icon: Library,
|
|
177
|
-
label: "Duy\u1EC7t theo th\u01B0 m\u1EE5c"
|
|
178
|
-
})
|
|
220
|
+
/* @__PURE__ */ jsxs("div", { className: "minimal-nav__footer", children: [
|
|
221
|
+
/* @__PURE__ */ jsxs(
|
|
222
|
+
Link,
|
|
223
|
+
{
|
|
224
|
+
className: "minimal-nav__account",
|
|
225
|
+
href: formatAdminURL({ adminRoute, path: adminRoutes.account }),
|
|
226
|
+
onClick: closeMobileNav,
|
|
227
|
+
prefetch: false,
|
|
228
|
+
title: userLabel,
|
|
229
|
+
children: [
|
|
230
|
+
/* @__PURE__ */ jsx("span", { className: "minimal-nav__avatar", children: initials }),
|
|
231
|
+
/* @__PURE__ */ jsxs("span", { className: "minimal-nav__account-copy", children: [
|
|
232
|
+
/* @__PURE__ */ jsx("strong", { children: userLabel }),
|
|
233
|
+
/* @__PURE__ */ jsx("small", { children: user?.email || "T\xE0i kho\u1EA3n qu\u1EA3n tr\u1ECB" })
|
|
234
|
+
] })
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
),
|
|
238
|
+
/* @__PURE__ */ jsx("div", { className: "minimal-nav__logout", children: /* @__PURE__ */ jsx(LogoutButton_default, {}) })
|
|
179
239
|
] })
|
|
180
|
-
] })
|
|
240
|
+
] }),
|
|
181
241
|
/* @__PURE__ */ jsx(
|
|
182
242
|
"button",
|
|
183
243
|
{
|
|
184
244
|
"aria-label": isMini ? "M\u1EDF r\u1ED9ng menu" : "Thu g\u1ECDn menu",
|
|
185
|
-
className: "
|
|
245
|
+
className: "minimal-nav__collapse",
|
|
186
246
|
onClick: () => setIsMini((current) => !current),
|
|
187
247
|
title: isMini ? "M\u1EDF r\u1ED9ng menu" : "Thu g\u1ECDn menu",
|
|
188
248
|
type: "button",
|
|
@@ -14,7 +14,7 @@ var BrandLogo = ({
|
|
|
14
14
|
}) => /* @__PURE__ */ jsx(
|
|
15
15
|
"span",
|
|
16
16
|
{
|
|
17
|
-
className: ["
|
|
17
|
+
className: ["brand-logo", className].filter(Boolean).join(" "),
|
|
18
18
|
style: { alignItems: "center", display: "inline-flex", height, maxWidth },
|
|
19
19
|
children: /* @__PURE__ */ jsx(
|
|
20
20
|
Image,
|
|
@@ -31,11 +31,11 @@ var BrandLogo = ({
|
|
|
31
31
|
);
|
|
32
32
|
var AdminIcon = () => {
|
|
33
33
|
const brand = useAdminBrand();
|
|
34
|
-
return /* @__PURE__ */ jsx("span", { className: "
|
|
34
|
+
return /* @__PURE__ */ jsx("span", { className: "aurea-brand aurea-brand--icon", children: /* @__PURE__ */ jsx(
|
|
35
35
|
BrandLogo,
|
|
36
36
|
{
|
|
37
37
|
asset: brand.logo,
|
|
38
|
-
className: "
|
|
38
|
+
className: "aurea-brand__image",
|
|
39
39
|
height: 32,
|
|
40
40
|
maxWidth: 32,
|
|
41
41
|
siteName: brand.siteName
|
|
@@ -44,11 +44,11 @@ var AdminIcon = () => {
|
|
|
44
44
|
};
|
|
45
45
|
var AdminLogo = () => {
|
|
46
46
|
const brand = useAdminBrand();
|
|
47
|
-
return /* @__PURE__ */ jsx("span", { "aria-label": brand.siteName, className: "
|
|
47
|
+
return /* @__PURE__ */ jsx("span", { "aria-label": brand.siteName, className: "aurea-brand aurea-brand--logo", role: "img", children: /* @__PURE__ */ jsx(
|
|
48
48
|
BrandLogo,
|
|
49
49
|
{
|
|
50
50
|
asset: brand.logo,
|
|
51
|
-
className: "
|
|
51
|
+
className: "aurea-brand__image",
|
|
52
52
|
height: 42,
|
|
53
53
|
maxWidth: 190,
|
|
54
54
|
siteName: brand.siteName
|