@wikex/admin-kit 0.6.0 → 0.7.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 CHANGED
@@ -2,6 +2,16 @@
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.7.0 - 2026-09-13
6
+
7
+ - Thay toàn bộ admin shell bằng component MUI thật theo Minimal UI: AppBar, navigation,
8
+ workspace switcher, account menu, theme switch, view-site và logout.
9
+ - Đồng bộ kích thước layout gốc của Minimal với sidebar 300/88px, header 72/64px,
10
+ Public Sans và palette xanh `#00A76F`.
11
+ - Chuẩn hóa table, filter, select, input, block, rich-text và document sidebar của Payload
12
+ theo token/bề mặt Minimal trong khi giữ nguyên hành vi, permission và Live Preview.
13
+ - Loại bỏ implementation shell cũ để các export công khai chỉ còn trỏ tới giao diện Minimal.
14
+
5
15
  ## 0.6.0 - 2026-09-13
6
16
 
7
17
  - Tích hợp MUI 7 và Emotion bằng App Router cache provider chính thức cho Next.js 16.
package/README.md CHANGED
@@ -4,7 +4,7 @@ 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
- - navigation, header, đăng nhập, đổi theme và branding động;
7
+ - navigation, header, đăng nhập, account menu, đổi theme và branding động bằng MUI;
8
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;
@@ -59,11 +59,7 @@ mode với Payload. Các màn hình custom có thể dùng trực tiếp các pr
59
59
  ```tsx
60
60
  'use client'
61
61
 
62
- import {
63
- MinimalBlockCard,
64
- MinimalDataTable,
65
- MinimalSelect,
66
- } from '@wikex/admin-kit/minimal'
62
+ import { MinimalBlockCard, MinimalDataTable, MinimalSelect } from '@wikex/admin-kit/minimal'
67
63
 
68
64
  export const ProductPanel = () => (
69
65
  <MinimalBlockCard label="Catalog" title="Hàng hóa">
@@ -85,6 +81,9 @@ export const ProductPanel = () => (
85
81
 
86
82
  Theme dùng palette gốc của Minimal UI (`primary.main = #00A76F`) và không chèn
87
83
  `CssBaseline`, nhờ vậy không reset CSS form/document có sẵn của Payload.
84
+ Admin shell dùng trực tiếp component MUI của Minimal; các control nội bộ của Payload
85
+ (table, filter, select, block, editor) được ánh xạ sang cùng token và kích thước để giữ
86
+ nguyên sorting, permission, localization và Live Preview.
88
87
 
89
88
  Live Preview provider của dự án là adapter khai báo route và component khả dụng:
90
89
 
@@ -137,7 +136,7 @@ Xem consumer không thuộc lĩnh vực bất động sản tại `examples/corp
137
136
  ## Cài vào dự án khác — một package, một cấu hình
138
137
 
139
138
  ```bash
140
- pnpm add @wikex/admin-kit@0.6.0
139
+ pnpm add @wikex/admin-kit@0.7.0
141
140
  ```
142
141
 
143
142
  Không cần `.npmrc`, GitLab token hay npm token ở dự án consumer. Các peer dependency
@@ -4,24 +4,25 @@ import {
4
4
  useAdminBrand
5
5
  } from "../chunk-X7VETFVD.js";
6
6
 
7
- // src/admin/BeforeLogin.tsx
7
+ // src/admin/MinimalBeforeLogin.tsx
8
+ import { Box, Typography } from "@mui/material";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  var BeforeLogin = () => {
10
11
  const { siteName } = useAdminBrand();
11
- return /* @__PURE__ */ jsxs("div", { className: "admin-login-intro", children: [
12
- /* @__PURE__ */ jsxs("span", { className: "admin-login-intro__eyebrow", children: [
12
+ return /* @__PURE__ */ jsxs(Box, { className: "admin-login-intro", children: [
13
+ /* @__PURE__ */ jsxs(Typography, { className: "admin-login-intro__eyebrow", color: "primary", variant: "overline", children: [
13
14
  siteName,
14
15
  " \xB7 Trung t\xE2m n\u1ED9i dung"
15
16
  ] }),
16
- /* @__PURE__ */ jsx("h1", { children: "Ch\xE0o m\u1EEBng tr\u1EDF l\u1EA1i." }),
17
- /* @__PURE__ */ jsxs("p", { children: [
17
+ /* @__PURE__ */ jsx(Typography, { component: "h1", variant: "h4", children: "Ch\xE0o m\u1EEBng tr\u1EDF l\u1EA1i." }),
18
+ /* @__PURE__ */ jsxs(Typography, { color: "text.secondary", variant: "body2", children: [
18
19
  "\u0110\u0103ng nh\u1EADp \u0111\u1EC3 qu\u1EA3n l\xFD n\u1ED9i dung, h\xECnh \u1EA3nh v\xE0 xu\u1EA5t b\u1EA3n c\u1EE7a ",
19
20
  siteName,
20
21
  "."
21
22
  ] })
22
23
  ] });
23
24
  };
24
- var BeforeLogin_default = BeforeLogin;
25
+ var MinimalBeforeLogin_default = BeforeLogin;
25
26
  export {
26
- BeforeLogin_default as default
27
+ MinimalBeforeLogin_default as default
27
28
  };
@@ -5,25 +5,32 @@ import {
5
5
  } from "../chunk-SM6CCKQQ.js";
6
6
  import "../chunk-X7VETFVD.js";
7
7
  import {
8
- ThemeToggle_default
9
- } from "../chunk-SAI5SWZA.js";
8
+ MinimalThemeToggle_default
9
+ } from "../chunk-N7CP6ZLG.js";
10
+ import {
11
+ MinimalViewSite_default
12
+ } from "../chunk-BKR24U6B.js";
10
13
 
11
- // src/admin/Header.tsx
14
+ // src/admin/MinimalHeader.tsx
15
+ import {
16
+ AppBar,
17
+ Avatar,
18
+ Box,
19
+ Divider,
20
+ IconButton,
21
+ ListItemIcon,
22
+ Menu,
23
+ MenuItem,
24
+ Stack,
25
+ Toolbar,
26
+ Tooltip,
27
+ Typography
28
+ } from "@mui/material";
12
29
  import { Link, useAuth, useConfig, useNav } from "@payloadcms/ui";
13
- import { Menu, Settings2 } from "lucide-react";
30
+ import { LogOut, Menu as MenuIcon, Settings2, UserRound } from "lucide-react";
14
31
  import { formatAdminURL } from "payload/shared";
15
-
16
- // src/admin/ViewSite.tsx
17
- import { ArrowUpRight } from "lucide-react";
32
+ import { useState } from "react";
18
33
  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: [
20
- "Xem website",
21
- /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": "true" })
22
- ] });
23
- var ViewSite_default = AdminViewSite;
24
-
25
- // src/admin/Header.tsx
26
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
27
34
  var getInitials = (name, email) => {
28
35
  const source = name?.trim() || email?.split("@")[0] || "AD";
29
36
  return source.split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
@@ -37,60 +44,95 @@ var AdminHeader = () => {
37
44
  routes: { admin: adminRoute }
38
45
  }
39
46
  } = useConfig();
47
+ const [accountAnchor, setAccountAnchor] = useState(null);
40
48
  const userLabel = user?.name?.trim() || user?.email?.split("@")[0] || "Qu\u1EA3n tr\u1ECB vi\xEAn";
41
49
  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(
45
- "button",
46
- {
47
- "aria-label": "M\u1EDF menu qu\u1EA3n tr\u1ECB",
48
- className: "minimal-admin-header__menu",
49
- onClick: () => setNavOpen(true),
50
- type: "button",
51
- children: /* @__PURE__ */ jsx2(Menu, { "aria-hidden": "true" })
52
- }
53
- ),
54
- /* @__PURE__ */ jsx2(
55
- Link,
56
- {
57
- "aria-label": "V\u1EC1 dashboard",
58
- className: "minimal-admin-header__mobile-brand",
59
- href: adminRoute,
60
- prefetch: false,
61
- children: /* @__PURE__ */ jsx2(AdminIcon, {})
62
- }
63
- )
50
+ const accountURL = formatAdminURL({ adminRoute, path: adminRoutes.account });
51
+ const logoutURL = formatAdminURL({ adminRoute, path: adminRoutes.logout });
52
+ const openAccountMenu = (event) => setAccountAnchor(event.currentTarget);
53
+ const closeAccountMenu = () => setAccountAnchor(null);
54
+ return /* @__PURE__ */ jsxs(AppBar, { className: "minimal-admin-header", color: "transparent", elevation: 0, position: "fixed", children: [
55
+ /* @__PURE__ */ jsxs(Toolbar, { className: "minimal-admin-header__toolbar", disableGutters: true, children: [
56
+ /* @__PURE__ */ jsxs(Stack, { alignItems: "center", className: "minimal-admin-header__left", direction: "row", children: [
57
+ /* @__PURE__ */ jsx(
58
+ IconButton,
59
+ {
60
+ "aria-label": "M\u1EDF menu qu\u1EA3n tr\u1ECB",
61
+ className: "minimal-admin-header__menu",
62
+ onClick: () => setNavOpen(true),
63
+ children: /* @__PURE__ */ jsx(MenuIcon, { "aria-hidden": "true", size: 21 })
64
+ }
65
+ ),
66
+ /* @__PURE__ */ jsx(
67
+ Link,
68
+ {
69
+ "aria-label": "V\u1EC1 dashboard",
70
+ className: "minimal-admin-header__mobile-brand",
71
+ href: adminRoute,
72
+ prefetch: false,
73
+ children: /* @__PURE__ */ jsx(AdminIcon, {})
74
+ }
75
+ )
76
+ ] }),
77
+ /* @__PURE__ */ jsx(Box, { sx: { flexGrow: 1 } }),
78
+ /* @__PURE__ */ jsxs(Stack, { alignItems: "center", className: "minimal-admin-header__actions", direction: "row", children: [
79
+ /* @__PURE__ */ jsx(MinimalViewSite_default, {}),
80
+ /* @__PURE__ */ jsx(MinimalThemeToggle_default, {}),
81
+ /* @__PURE__ */ jsx(Tooltip, { title: "C\xE0i \u0111\u1EB7t t\xE0i kho\u1EA3n", children: /* @__PURE__ */ jsx(
82
+ IconButton,
83
+ {
84
+ "aria-label": `M\u1EDF c\xE0i \u0111\u1EB7t t\xE0i kho\u1EA3n ${userLabel}`,
85
+ className: "minimal-admin-header__settings",
86
+ component: Link,
87
+ href: accountURL,
88
+ prefetch: false,
89
+ children: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true", size: 20 })
90
+ }
91
+ ) }),
92
+ /* @__PURE__ */ jsx(Tooltip, { title: userLabel, children: /* @__PURE__ */ jsx(
93
+ IconButton,
94
+ {
95
+ "aria-controls": accountAnchor ? "minimal-account-menu" : void 0,
96
+ "aria-expanded": accountAnchor ? "true" : void 0,
97
+ "aria-haspopup": "menu",
98
+ "aria-label": `M\u1EDF menu t\xE0i kho\u1EA3n ${userLabel}`,
99
+ className: "minimal-admin-header__account",
100
+ onClick: openAccountMenu,
101
+ children: /* @__PURE__ */ jsx(Avatar, { children: initials })
102
+ }
103
+ ) })
104
+ ] })
64
105
  ] }),
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
- )
90
- ] })
106
+ /* @__PURE__ */ jsxs(
107
+ Menu,
108
+ {
109
+ anchorEl: accountAnchor,
110
+ anchorOrigin: { horizontal: "right", vertical: "bottom" },
111
+ id: "minimal-account-menu",
112
+ onClose: closeAccountMenu,
113
+ open: Boolean(accountAnchor),
114
+ slotProps: { paper: { className: "minimal-account-menu" } },
115
+ transformOrigin: { horizontal: "right", vertical: "top" },
116
+ children: [
117
+ /* @__PURE__ */ jsxs(Box, { className: "minimal-account-menu__profile", children: [
118
+ /* @__PURE__ */ jsx(Typography, { fontWeight: 600, noWrap: true, variant: "subtitle2", children: userLabel }),
119
+ /* @__PURE__ */ jsx(Typography, { color: "text.secondary", noWrap: true, variant: "caption", children: user?.email || "T\xE0i kho\u1EA3n qu\u1EA3n tr\u1ECB" })
120
+ ] }),
121
+ /* @__PURE__ */ jsx(Divider, {}),
122
+ /* @__PURE__ */ jsxs(MenuItem, { component: Link, href: accountURL, onClick: closeAccountMenu, prefetch: false, children: [
123
+ /* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(UserRound, { size: 18 }) }),
124
+ "T\xE0i kho\u1EA3n"
125
+ ] }),
126
+ /* @__PURE__ */ jsxs(MenuItem, { component: Link, href: logoutURL, onClick: closeAccountMenu, prefetch: false, children: [
127
+ /* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(LogOut, { size: 18 }) }),
128
+ "\u0110\u0103ng xu\u1EA5t"
129
+ ] })
130
+ ]
131
+ }
132
+ )
91
133
  ] });
92
134
  };
93
- var Header_default = AdminHeader;
135
+ var MinimalHeader_default = AdminHeader;
94
136
  export {
95
- Header_default as default
137
+ MinimalHeader_default as default
96
138
  };
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  "use client";
3
3
  import {
4
- LogoutButton_default
5
- } from "../chunk-GZ2B5BTH.js";
4
+ MinimalLogoutButton_default
5
+ } from "../chunk-B6FIGT4Q.js";
6
6
  export {
7
- LogoutButton_default as default
7
+ MinimalLogoutButton_default as default
8
8
  };