@goplusvn/core 0.1.16 → 0.1.18

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
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.18 — SettingsProvider nhận `defaults` (đổi màu/theme mặc định theo app)
4
+
5
+ Customizer khóa cứng `defaultSettings.theme = "blue"` trong core → app không đặt
6
+ được màu mặc định riêng (vd wu-vpbank muốn "green"). Thêm prop tùy chọn `defaults?:
7
+ Partial<SettingsType>` cho `SettingsProvider` — merge lên core defaults (áp cho state
8
+ đầu, khi không có cookie, và resetSettings). Additive/backward-compatible. App dùng:
9
+ `<SettingsProvider locale={locale} defaults={{ theme: "green" }}>`.
10
+
11
+
12
+ ## 0.1.17 — Fix: khôi phục nền màu tab (page-tabs) theo golden vinhhoa
13
+
14
+ Bản "neutral single-style" trước đó bỏ gradient nền tab NHƯNG vẫn để icon/chữ
15
+ `text-white` (thiết kế cho nền tối) → tab inactive: chữ/icon trắng trên nền xám
16
+ nhạt = mất màu/mờ (không lấy theo --primary). Khôi phục `getTabBackgroundColor`
17
+ bản golden vinhhoa: tab inactive = 1 gradient tối theo hash path (bộ 21 màu), chữ
18
+ `text-white`; tab active = nền trang (trắng) + viền `border-primary`. Mọi app hiện
19
+ màu nền tab như vinhhoa.
20
+
21
+
3
22
  ## 0.1.16 — RBAC roles route-handler factory
4
23
 
5
24
  Slice ⑧b. Mỗi app hand-write /api/roles + /api/roles/[id] (list users[], create/update
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@goplusvn/core",
3
3
  "description": "GoPlusVN Platform Kit - ERP kernel: layout, RBAC, CRUD, multi-tenant, system pages",
4
- "version": "0.1.16",
4
+ "version": "0.1.18",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "registry": "https://registry.npmjs.org",
@@ -39,14 +39,20 @@ export const SettingsContext = createContext<
39
39
  export function SettingsProvider({
40
40
  locale,
41
41
  children,
42
+ defaults,
42
43
  }: {
43
44
  locale: LocaleType;
44
45
  children: ReactNode;
46
+ /** App-level overrides của defaultSettings (vd theme, radius). Truyền object
47
+ * ỔN ĐỊNH (module-level const) để tránh re-render. Mặc định = defaultSettings core. */
48
+ defaults?: Partial<SettingsType>;
45
49
  }) {
50
+ // Mặc định của app = core defaults + override từ app (vd theme:"green").
51
+ const base = { ...defaultSettings, ...defaults };
46
52
  const [storedSettings, setStoredSettings, deleteStoredSettings] =
47
53
  useCookie("settings");
48
54
  const [settings, setSettings] = useState<SettingsType>(() => ({
49
- ...defaultSettings,
55
+ ...base,
50
56
  locale,
51
57
  }));
52
58
 
@@ -54,14 +60,15 @@ export function SettingsProvider({
54
60
  if (storedSettings) {
55
61
  try {
56
62
  const parsedSettings = JSON.parse(storedSettings);
57
- setSettings({ ...defaultSettings, ...parsedSettings });
63
+ setSettings({ ...base, ...parsedSettings });
58
64
  } catch {
59
- setSettings({ ...defaultSettings, locale });
65
+ setSettings({ ...base, locale });
60
66
  }
61
67
  } else {
62
- setSettings({ ...defaultSettings, locale });
68
+ setSettings({ ...base, locale });
63
69
  }
64
- }, [storedSettings, locale]);
70
+ // eslint-disable-next-line react-hooks/exhaustive-deps
71
+ }, [storedSettings, locale, defaults]);
65
72
 
66
73
  const updateSettings = useCallback(
67
74
  (newSettings: SettingsType) => {
@@ -73,8 +80,8 @@ export function SettingsProvider({
73
80
 
74
81
  const resetSettings = useCallback(() => {
75
82
  deleteStoredSettings();
76
- setSettings(defaultSettings);
77
- }, [deleteStoredSettings]);
83
+ setSettings({ ...defaultSettings, ...defaults });
84
+ }, [deleteStoredSettings, defaults]);
78
85
 
79
86
  // Apply the appearance choices the Customizer exposes but that nothing else
80
87
  // wires up. Without this, the "Radius" and "Density" controls store a value
@@ -85,10 +85,42 @@ export function PageTabs({
85
85
  currentTabIndex >= 0 && currentTabIndex < sortedTabs.length - 1;
86
86
  const hasOtherTabs = sortedTabs.length > 1;
87
87
 
88
- // Neutral, single-style tab background (was a per-path rainbow gradient).
89
- // Active tabs sit on the page surface; inactive tabs are a muted chip.
90
- const getTabBackgroundColor = (_path: string, isActive: boolean) => {
91
- return isActive ? "bg-background" : "bg-muted/60";
88
+ // Nền tab: active = mặt phẳng trang (trắng); inactive = 1 gradient tối theo hash
89
+ // của path (bộ 21 màu cố định) bám thiết kế golden vinhhoa (icon/chữ trắng đọc
90
+ // trên nền tối). KHÔNG dùng --primary để mỗi tab có màu riêng, dễ phân biệt.
91
+ const getTabBackgroundColor = (path: string, isActive: boolean) => {
92
+ if (isActive) return "bg-background";
93
+
94
+ const normalizedPath = path.replace(/^\/[a-z]{2}(\/|$)/, "/");
95
+ const hash = normalizedPath.split("").reduce((acc, char) => {
96
+ return (acc << 5) - acc + char.charCodeAt(0);
97
+ }, 0);
98
+
99
+ const gradients = [
100
+ "bg-gradient-to-r from-slate-700 to-slate-600",
101
+ "bg-gradient-to-r from-zinc-700 to-zinc-600",
102
+ "bg-gradient-to-r from-stone-700 to-stone-600",
103
+ "bg-gradient-to-r from-neutral-700 to-neutral-600",
104
+ "bg-gradient-to-r from-blue-700 to-blue-600",
105
+ "bg-gradient-to-r from-indigo-700 to-indigo-600",
106
+ "bg-gradient-to-r from-purple-700 to-purple-600",
107
+ "bg-gradient-to-r from-violet-700 to-violet-600",
108
+ "bg-gradient-to-r from-fuchsia-700 to-fuchsia-600",
109
+ "bg-gradient-to-r from-pink-700 to-pink-600",
110
+ "bg-gradient-to-r from-rose-700 to-rose-600",
111
+ "bg-gradient-to-r from-red-700 to-red-600",
112
+ "bg-gradient-to-r from-orange-700 to-orange-600",
113
+ "bg-gradient-to-r from-amber-700 to-amber-600",
114
+ "bg-gradient-to-r from-yellow-700 to-yellow-600",
115
+ "bg-gradient-to-r from-lime-700 to-lime-600",
116
+ "bg-gradient-to-r from-green-700 to-green-600",
117
+ "bg-gradient-to-r from-emerald-700 to-emerald-600",
118
+ "bg-gradient-to-r from-teal-700 to-teal-600",
119
+ "bg-gradient-to-r from-cyan-700 to-cyan-600",
120
+ "bg-gradient-to-r from-sky-700 to-sky-600",
121
+ ];
122
+
123
+ return gradients[Math.abs(hash) % gradients.length];
92
124
  };
93
125
 
94
126
  return (
@@ -135,11 +167,11 @@ export function PageTabs({
135
167
  variant === "default" &&
136
168
  (isActive
137
169
  ? "bg-background text-foreground border-b-2 border-primary shadow-sm shadow-primary/10 border-t border-x border-b-0 rounded-t-md -mb-px z-10"
138
- : "text-muted-foreground hover:bg-muted hover:text-foreground border-b border-border rounded-t-md"),
170
+ : "text-white hover:text-white border-b border-white/10 rounded-t-md"),
139
171
  variant === "header" &&
140
172
  (isActive
141
173
  ? "bg-background text-foreground border-b-2 border-primary shadow-sm shadow-primary/10 border-t border-x rounded-t-md z-10"
142
- : "text-muted-foreground hover:bg-muted hover:text-foreground border-b border-border rounded-t-md"),
174
+ : "text-white hover:text-white border-b border-white/10 rounded-t-md"),
143
175
  !isLast &&
144
176
  !isActive &&
145
177
  variant === "default" &&