gov-layout 1.2.23 → 1.2.25

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/dist/index.d.mts CHANGED
@@ -82,6 +82,7 @@ interface SidebarUserProfileProps {
82
82
  }
83
83
  declare function SidebarUserProfile({ user, roleLabel, onLogout, collapsed, onProfile, }: SidebarUserProfileProps): react_jsx_runtime.JSX.Element | null;
84
84
 
85
+ type NotificationCategory = 'action' | 'general';
85
86
  interface NotificationItem {
86
87
  id: string | number;
87
88
  title: string;
@@ -89,6 +90,8 @@ interface NotificationItem {
89
90
  date: string;
90
91
  type: 'info' | 'success' | 'warning' | 'error' | 'reminder';
91
92
  isRead: boolean;
93
+ /** หมวดหมู่การแจ้งเตือน: 'action' = ต้องดำเนินการ, 'general' = แจ้งเตือนทั่วไป */
94
+ category?: NotificationCategory;
92
95
  }
93
96
  interface UserHeaderProps {
94
97
  user?: {
@@ -262,4 +265,4 @@ declare const Icons: {
262
265
  readonly Trash: typeof TrashIcon;
263
266
  };
264
267
 
265
- export { AlertTriangleIcon, BarChartIcon, BellIcon, BottomBar, type BottomBarProps, BuildingIcon, CalendarIcon, CheckCircleIcon, ClipboardIcon, DatabaseIcon, DownloadIcon, EditIcon, EyeIcon, FONT_SIZE_OPTIONS, FileTextIcon, FolderIcon, type FontSizeKey, type FontSizeOption, FontSizeSettings, GearIcon, HeartIcon, HelpCircleIcon, HistoryIcon, HomeIcon, type IconProps, Icons, LogOutIcon, MailIcon, MapPinIcon, type MenuItem, type NotificationItem, PhoneIcon, PlusCircleIcon, PrinterIcon, SearchIcon, SettingsPanel, SettingsProvider, ShieldIcon, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, StarIcon, type Theme, ThemeSettings, TrashIcon, UploadIcon, type User, UserHeader, UserIcon, UserSidebar, UsersIcon, WrenchIcon, XCircleIcon, useDarkMode, useSettings };
268
+ export { AlertTriangleIcon, BarChartIcon, BellIcon, BottomBar, type BottomBarProps, BuildingIcon, CalendarIcon, CheckCircleIcon, ClipboardIcon, DatabaseIcon, DownloadIcon, EditIcon, EyeIcon, FONT_SIZE_OPTIONS, FileTextIcon, FolderIcon, type FontSizeKey, type FontSizeOption, FontSizeSettings, GearIcon, HeartIcon, HelpCircleIcon, HistoryIcon, HomeIcon, type IconProps, Icons, LogOutIcon, MailIcon, MapPinIcon, type MenuItem, type NotificationCategory, type NotificationItem, PhoneIcon, PlusCircleIcon, PrinterIcon, SearchIcon, SettingsPanel, SettingsProvider, ShieldIcon, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, StarIcon, type Theme, ThemeSettings, TrashIcon, UploadIcon, type User, UserHeader, UserIcon, UserSidebar, UsersIcon, WrenchIcon, XCircleIcon, useDarkMode, useSettings };
package/dist/index.d.ts CHANGED
@@ -82,6 +82,7 @@ interface SidebarUserProfileProps {
82
82
  }
83
83
  declare function SidebarUserProfile({ user, roleLabel, onLogout, collapsed, onProfile, }: SidebarUserProfileProps): react_jsx_runtime.JSX.Element | null;
84
84
 
85
+ type NotificationCategory = 'action' | 'general';
85
86
  interface NotificationItem {
86
87
  id: string | number;
87
88
  title: string;
@@ -89,6 +90,8 @@ interface NotificationItem {
89
90
  date: string;
90
91
  type: 'info' | 'success' | 'warning' | 'error' | 'reminder';
91
92
  isRead: boolean;
93
+ /** หมวดหมู่การแจ้งเตือน: 'action' = ต้องดำเนินการ, 'general' = แจ้งเตือนทั่วไป */
94
+ category?: NotificationCategory;
92
95
  }
93
96
  interface UserHeaderProps {
94
97
  user?: {
@@ -262,4 +265,4 @@ declare const Icons: {
262
265
  readonly Trash: typeof TrashIcon;
263
266
  };
264
267
 
265
- export { AlertTriangleIcon, BarChartIcon, BellIcon, BottomBar, type BottomBarProps, BuildingIcon, CalendarIcon, CheckCircleIcon, ClipboardIcon, DatabaseIcon, DownloadIcon, EditIcon, EyeIcon, FONT_SIZE_OPTIONS, FileTextIcon, FolderIcon, type FontSizeKey, type FontSizeOption, FontSizeSettings, GearIcon, HeartIcon, HelpCircleIcon, HistoryIcon, HomeIcon, type IconProps, Icons, LogOutIcon, MailIcon, MapPinIcon, type MenuItem, type NotificationItem, PhoneIcon, PlusCircleIcon, PrinterIcon, SearchIcon, SettingsPanel, SettingsProvider, ShieldIcon, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, StarIcon, type Theme, ThemeSettings, TrashIcon, UploadIcon, type User, UserHeader, UserIcon, UserSidebar, UsersIcon, WrenchIcon, XCircleIcon, useDarkMode, useSettings };
268
+ export { AlertTriangleIcon, BarChartIcon, BellIcon, BottomBar, type BottomBarProps, BuildingIcon, CalendarIcon, CheckCircleIcon, ClipboardIcon, DatabaseIcon, DownloadIcon, EditIcon, EyeIcon, FONT_SIZE_OPTIONS, FileTextIcon, FolderIcon, type FontSizeKey, type FontSizeOption, FontSizeSettings, GearIcon, HeartIcon, HelpCircleIcon, HistoryIcon, HomeIcon, type IconProps, Icons, LogOutIcon, MailIcon, MapPinIcon, type MenuItem, type NotificationCategory, type NotificationItem, PhoneIcon, PlusCircleIcon, PrinterIcon, SearchIcon, SettingsPanel, SettingsProvider, ShieldIcon, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, StarIcon, type Theme, ThemeSettings, TrashIcon, UploadIcon, type User, UserHeader, UserIcon, UserSidebar, UsersIcon, WrenchIcon, XCircleIcon, useDarkMode, useSettings };
package/dist/index.js CHANGED
@@ -1130,6 +1130,7 @@ function UserHeader({
1130
1130
  const displayName = `${user?.firstName || ""} ${user?.lastName || ""}`.trim() || "\u0E1C\u0E39\u0E49\u0E43\u0E0A\u0E49";
1131
1131
  const firstChar = user?.firstName?.charAt(0) || "\u0E1C";
1132
1132
  const [isNotifOpen, setIsNotifOpen] = react.useState(false);
1133
+ const [activeFilter, setActiveFilter] = react.useState("all");
1133
1134
  const notifRef = react.useRef(null);
1134
1135
  const isDark = useDarkMode();
1135
1136
  react.useEffect(() => {
@@ -1142,6 +1143,13 @@ function UserHeader({
1142
1143
  return () => document.removeEventListener("mousedown", handleClickOutside);
1143
1144
  }, []);
1144
1145
  const unreadCount = notifications.filter((n) => !n.isRead).length;
1146
+ const actionCount = notifications.filter((n) => n.category === "action").length;
1147
+ const generalCount = notifications.filter((n) => !n.category || n.category === "general").length;
1148
+ const filteredNotifications = notifications.filter((n) => {
1149
+ if (activeFilter === "all") return true;
1150
+ if (activeFilter === "action") return n.category === "action";
1151
+ return !n.category || n.category === "general";
1152
+ });
1145
1153
  return /* @__PURE__ */ jsxRuntime.jsx(
1146
1154
  "header",
1147
1155
  {
@@ -1181,7 +1189,10 @@ function UserHeader({
1181
1189
  cursor: onProfile ? "pointer" : "default",
1182
1190
  padding: "4px 8px",
1183
1191
  borderRadius: "10px",
1184
- transition: "background-color 0.15s ease"
1192
+ transition: "background-color 0.15s ease",
1193
+ flex: 1,
1194
+ minWidth: 0,
1195
+ overflow: "hidden"
1185
1196
  },
1186
1197
  children: [
1187
1198
  user?.pictureUrl ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1337,34 +1348,95 @@ function UserHeader({
1337
1348
  "div",
1338
1349
  {
1339
1350
  style: {
1340
- padding: "16px",
1341
- borderBottom: `1px solid ${isDark ? "#374151" : "#f3f4f6"}`,
1342
- display: "flex",
1343
- alignItems: "center",
1344
- justifyContent: "space-between",
1351
+ padding: "16px 16px 0",
1345
1352
  background: isDark ? "#1f2937" : "#fafafa"
1346
1353
  },
1347
1354
  children: [
1348
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, fontSize: "14px", color: isDark ? "#ffffff" : "#111" }, children: "\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19" }),
1349
- onMarkAllRead && /* @__PURE__ */ jsxRuntime.jsx(
1350
- "button",
1355
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "12px" }, children: [
1356
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, fontSize: "14px", color: isDark ? "#ffffff" : "#111" }, children: "\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19" }),
1357
+ onMarkAllRead && /* @__PURE__ */ jsxRuntime.jsx(
1358
+ "button",
1359
+ {
1360
+ onClick: onMarkAllRead,
1361
+ style: {
1362
+ fontSize: "12px",
1363
+ color: "var(--color-alias-color-brand-primary, #1e7d55)",
1364
+ background: "none",
1365
+ border: "none",
1366
+ cursor: "pointer",
1367
+ fontWeight: 500
1368
+ },
1369
+ children: "\u0E2D\u0E48\u0E32\u0E19\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14"
1370
+ }
1371
+ )
1372
+ ] }),
1373
+ /* @__PURE__ */ jsxRuntime.jsx(
1374
+ "div",
1351
1375
  {
1352
- onClick: onMarkAllRead,
1353
1376
  style: {
1354
- fontSize: "12px",
1355
- color: "var(--color-alias-color-brand-primary, #1e7d55)",
1356
- background: "none",
1357
- border: "none",
1358
- cursor: "pointer",
1359
- fontWeight: 500
1377
+ display: "flex",
1378
+ gap: "6px",
1379
+ paddingBottom: "12px",
1380
+ borderBottom: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`
1360
1381
  },
1361
- children: "\u0E2D\u0E48\u0E32\u0E19\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14"
1382
+ children: [
1383
+ { key: "all", label: "\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14", count: notifications.length },
1384
+ { key: "action", label: "\u0E15\u0E49\u0E2D\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23", count: actionCount },
1385
+ { key: "general", label: "\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19\u0E17\u0E31\u0E48\u0E27\u0E44\u0E1B", count: generalCount }
1386
+ ].map((tab) => {
1387
+ const isActive = activeFilter === tab.key;
1388
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1389
+ "button",
1390
+ {
1391
+ onClick: () => setActiveFilter(tab.key),
1392
+ style: {
1393
+ display: "inline-flex",
1394
+ alignItems: "center",
1395
+ gap: "5px",
1396
+ padding: "5px 10px",
1397
+ fontSize: "12px",
1398
+ fontWeight: isActive ? 600 : 400,
1399
+ color: isActive ? isDark ? "#ffffff" : "#1e7d55" : isDark ? "#9ca3af" : "#6b7280",
1400
+ background: isActive ? isDark ? "rgba(30,125,85,0.2)" : "rgba(30,125,85,0.08)" : "transparent",
1401
+ border: `1px solid ${isActive ? isDark ? "rgba(30,125,85,0.4)" : "rgba(30,125,85,0.25)" : isDark ? "#4b5563" : "#e5e7eb"}`,
1402
+ borderRadius: "16px",
1403
+ cursor: "pointer",
1404
+ transition: "all 0.15s ease",
1405
+ whiteSpace: "nowrap"
1406
+ },
1407
+ children: [
1408
+ tab.label,
1409
+ /* @__PURE__ */ jsxRuntime.jsx(
1410
+ "span",
1411
+ {
1412
+ style: {
1413
+ minWidth: "18px",
1414
+ height: "18px",
1415
+ display: "inline-flex",
1416
+ alignItems: "center",
1417
+ justifyContent: "center",
1418
+ borderRadius: "9px",
1419
+ fontSize: "10px",
1420
+ fontWeight: 700,
1421
+ lineHeight: 1,
1422
+ padding: "0 4px",
1423
+ background: isActive ? isDark ? "#1e7d55" : "#1e7d55" : isDark ? "#4b5563" : "#e5e7eb",
1424
+ color: isActive ? "#ffffff" : isDark ? "#d1d5db" : "#6b7280"
1425
+ },
1426
+ children: tab.count
1427
+ }
1428
+ )
1429
+ ]
1430
+ },
1431
+ tab.key
1432
+ );
1433
+ })
1362
1434
  }
1363
1435
  )
1364
1436
  ]
1365
1437
  }
1366
1438
  ),
1367
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { maxHeight: "60vh", overflowY: "auto" }, children: notifications.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1439
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { maxHeight: "60vh", overflowY: "auto" }, children: filteredNotifications.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1368
1440
  "div",
1369
1441
  {
1370
1442
  style: {
@@ -1373,21 +1445,22 @@ function UserHeader({
1373
1445
  color: "#9ca3af",
1374
1446
  fontSize: "14px"
1375
1447
  },
1376
- children: "\u{1F514} \u0E44\u0E21\u0E48\u0E21\u0E35\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19\u0E43\u0E2B\u0E21\u0E48"
1448
+ children: activeFilter === "all" ? "\u{1F514} \u0E44\u0E21\u0E48\u0E21\u0E35\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19\u0E43\u0E2B\u0E21\u0E48" : activeFilter === "action" ? "\u2705 \u0E44\u0E21\u0E48\u0E21\u0E35\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E15\u0E49\u0E2D\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23" : "\u{1F4CB} \u0E44\u0E21\u0E48\u0E21\u0E35\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19\u0E17\u0E31\u0E48\u0E27\u0E44\u0E1B"
1377
1449
  }
1378
- ) : notifications.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
1450
+ ) : filteredNotifications.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
1379
1451
  "div",
1380
1452
  {
1381
1453
  onClick: () => onNotificationClick?.(item),
1382
1454
  style: {
1383
1455
  padding: "12px 16px",
1384
- borderBottom: "1px solid #f9fafb",
1456
+ borderBottom: `1px solid ${isDark ? "#2d3748" : "#f3f4f6"}`,
1385
1457
  cursor: "pointer",
1386
1458
  background: !item.isRead ? isDark ? "rgba(59,130,246,0.15)" : "rgba(219,234,254,0.3)" : "transparent",
1387
1459
  position: "relative",
1388
1460
  display: "flex",
1389
1461
  gap: "12px",
1390
- alignItems: "flex-start"
1462
+ alignItems: "flex-start",
1463
+ transition: "background-color 0.15s ease"
1391
1464
  },
1392
1465
  onMouseEnter: (e) => {
1393
1466
  e.currentTarget.style.backgroundColor = isDark ? "#1f2937" : "#f9fafb";
@@ -1429,6 +1502,22 @@ function UserHeader({
1429
1502
  }
1430
1503
  ),
1431
1504
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
1505
+ item.category === "action" && /* @__PURE__ */ jsxRuntime.jsx(
1506
+ "span",
1507
+ {
1508
+ style: {
1509
+ display: "inline-block",
1510
+ fontSize: "10px",
1511
+ fontWeight: 600,
1512
+ color: "#b45309",
1513
+ background: "#fef3c7",
1514
+ padding: "1px 6px",
1515
+ borderRadius: "4px",
1516
+ marginBottom: "4px"
1517
+ },
1518
+ children: "\u0E15\u0E49\u0E2D\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23"
1519
+ }
1520
+ ),
1432
1521
  /* @__PURE__ */ jsxRuntime.jsx(
1433
1522
  "p",
1434
1523
  {