gov-layout 1.0.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/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # gov-layout
2
+
3
+ Government Layout Components — Staff Sidebar + User Header/Sidebar
4
+
5
+ > ใช้คู่กับ `gov-token-css` เพื่อให้สีตรงตาม Design System
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install gov-layout gov-token-css
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 📦 Components
16
+
17
+ ### 1. StaffSidebar (เจ้าหน้าที่)
18
+
19
+ Sidebar ฝั่งซ้ายแบบ fixed สำหรับหน้า admin
20
+
21
+ ```tsx
22
+ import { StaffSidebar } from 'gov-layout';
23
+ import type { MenuItem } from 'gov-layout';
24
+
25
+ const menuItems: MenuItem[] = [
26
+ {
27
+ id: 'services',
28
+ title: 'งานบริการ',
29
+ icon: <FolderIcon />,
30
+ children: [
31
+ { id: 'water', title: 'ประปา', path: '/services/water' },
32
+ { id: 'tax', title: 'ภาษี', path: '/services/tax' },
33
+ ],
34
+ },
35
+ {
36
+ id: 'help',
37
+ title: 'ช่วยเหลือ',
38
+ icon: <HelpIcon />,
39
+ path: '/help',
40
+ dividerAfter: true,
41
+ },
42
+ ];
43
+
44
+ const bottomMenu: MenuItem[] = [
45
+ { id: 'settings', title: 'ตั้งค่าระบบ', icon: <SettingsIcon />, path: '/settings' },
46
+ ];
47
+
48
+ <StaffSidebar
49
+ orgLogo="/logo.png"
50
+ orgName="เทศบาลตำบลหลักเมือง"
51
+ orgSubtitle="จังหวัดราชบุรี"
52
+ menuItems={menuItems}
53
+ bottomMenuItems={bottomMenu}
54
+ user={{ firstName: 'Kaimuk', lastName: 'Jakprim' }}
55
+ roleLabel="เจ้าหน้าที่"
56
+ currentPath="/services/water"
57
+ onNavigate={(path) => router.push(path)}
58
+ onLogout={() => signOut()}
59
+ width="280px"
60
+ />
61
+ ```
62
+
63
+ **Features:**
64
+ - ✅ Dropdown submenu (พับ/กาง)
65
+ - ✅ Auto-expand เมื่อ child active
66
+ - ✅ Active item highlight
67
+ - ✅ Bottom menu (ตั้งค่าระบบ)
68
+ - ✅ User profile + logout ข้างล่าง
69
+
70
+ ---
71
+
72
+ ### 2. UserHeader (ผู้ใช้ทั่วไป)
73
+
74
+ Header ด้านบนพร้อม notification bell
75
+
76
+ ```tsx
77
+ import { UserHeader } from 'gov-layout';
78
+
79
+ const [isSidebarOpen, setIsSidebarOpen] = useState(false);
80
+
81
+ <UserHeader
82
+ user={{ firstName: 'Kaimuk', pictureUrl: '/avatar.jpg' }}
83
+ notifications={[
84
+ {
85
+ id: 1,
86
+ title: 'คำร้องได้รับการอนุมัติ',
87
+ description: 'คำร้องหมายเลข #1234',
88
+ date: '2 ชม. ที่แล้ว',
89
+ type: 'success',
90
+ isRead: false,
91
+ },
92
+ ]}
93
+ onToggleSidebar={() => setIsSidebarOpen(true)}
94
+ onMarkAllRead={() => markAllRead()}
95
+ onViewAll={() => router.push('/notifications')}
96
+ />
97
+ ```
98
+
99
+ ---
100
+
101
+ ### 3. UserSidebar (ผู้ใช้ทั่วไป)
102
+
103
+ Sidebar ฝั่งขวาแบบ slide-in
104
+
105
+ ```tsx
106
+ import { UserSidebar } from 'gov-layout';
107
+
108
+ <UserSidebar
109
+ isOpen={isSidebarOpen}
110
+ onClose={() => setIsSidebarOpen(false)}
111
+ user={{ firstName: 'Kaimuk', lastName: 'Jakprim', pictureUrl: '/avatar.jpg' }}
112
+ roleLabel="ผู้สูงอายุ"
113
+ menuItems={[
114
+ { id: 'profile', title: 'ข้อมูลส่วนตัว', icon: <UserIcon />, path: '/profile' },
115
+ { id: 'services', title: 'บริการหลัก', icon: <HomeIcon />, path: '/services' },
116
+ { id: 'settings', title: 'ตั้งค่าระบบ', icon: <SettingsIcon />, path: '/settings' },
117
+ ]}
118
+ onNavigate={(path) => router.push(path)}
119
+ onLogout={() => signOut()}
120
+ />
121
+ ```
122
+
123
+ ---
124
+
125
+ ## 🔧 Sub-Components
126
+
127
+ ใช้แยกกันได้ถ้าต้องการ customize
128
+
129
+ ```tsx
130
+ import {
131
+ SidebarHeader, // logo + ชื่อองค์กร
132
+ SidebarMenu, // เมนู dropdown
133
+ SidebarUserProfile // avatar + logout
134
+ } from 'gov-layout';
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 🎨 Styling
140
+
141
+ Components ใช้ **inline styles** + CSS variables จาก `gov-token-css`:
142
+
143
+ ```css
144
+ /* ใน globals.css */
145
+ @import "gov-token-css";
146
+ ```
147
+
148
+ ถ้าไม่ได้ import `gov-token-css` จะใช้สี fallback อัตโนมัติ
149
+
150
+ ---
151
+
152
+ ## 📐 Types
153
+
154
+ ```ts
155
+ interface MenuItem {
156
+ id: string;
157
+ title: string;
158
+ path?: string;
159
+ icon?: React.ReactNode;
160
+ children?: MenuItem[]; // submenu
161
+ dividerAfter?: boolean; // เส้นคั่น
162
+ }
163
+
164
+ interface User {
165
+ id?: string | number;
166
+ firstName?: string;
167
+ lastName?: string;
168
+ pictureUrl?: string;
169
+ role?: string;
170
+ }
171
+
172
+ interface NotificationItem {
173
+ id: string | number;
174
+ title: string;
175
+ description: string;
176
+ date: string;
177
+ type: 'info' | 'success' | 'warning' | 'error' | 'reminder';
178
+ isRead: boolean;
179
+ }
180
+ ```
181
+
182
+ ---
183
+
184
+ ## 📁 Layout Example
185
+
186
+ ```tsx
187
+ // Staff Layout (เจ้าหน้าที่)
188
+ export default function AdminLayout({ children }) {
189
+ return (
190
+ <div style={{ display: 'flex' }}>
191
+ <StaffSidebar ... />
192
+ <main style={{ marginLeft: '280px', flex: 1 }}>
193
+ {children}
194
+ </main>
195
+ </div>
196
+ );
197
+ }
198
+
199
+ // User Layout (ผู้ใช้ทั่วไป)
200
+ export default function UserLayout({ children }) {
201
+ const [open, setOpen] = useState(false);
202
+ return (
203
+ <>
204
+ <UserHeader onToggleSidebar={() => setOpen(true)} ... />
205
+ <UserSidebar isOpen={open} onClose={() => setOpen(false)} ... />
206
+ <main>{children}</main>
207
+ </>
208
+ );
209
+ }
210
+ ```
@@ -0,0 +1,104 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface User {
4
+ id?: string | number;
5
+ firstName?: string;
6
+ lastName?: string;
7
+ pictureUrl?: string;
8
+ role?: string;
9
+ }
10
+ interface MenuItem {
11
+ id: string;
12
+ title: string;
13
+ path?: string;
14
+ icon?: React.ReactNode;
15
+ children?: MenuItem[];
16
+ dividerAfter?: boolean;
17
+ }
18
+ interface StaffSidebarProps {
19
+ /** URL รูปตราองค์กร */
20
+ orgLogo?: string;
21
+ /** ชื่อองค์กร */
22
+ orgName: string;
23
+ /** ชื่อรอง เช่น จังหวัด */
24
+ orgSubtitle?: string;
25
+ /** เมนูหลัก */
26
+ menuItems: MenuItem[];
27
+ /** เมนูล่าง เช่น ตั้งค่าระบบ */
28
+ bottomMenuItems?: MenuItem[];
29
+ /** ข้อมูลผู้ใช้ */
30
+ user: User | null;
31
+ /** ป้ายแสดงตำแหน่ง เช่น "เจ้าหน้าที่" */
32
+ roleLabel: string;
33
+ /** callback เมื่อคลิกเมนู */
34
+ onNavigate: (path: string) => void;
35
+ /** callback เมื่อกดออกจากระบบ */
36
+ onLogout: () => void;
37
+ /** path ปัจจุบันเพื่อ highlight active menu */
38
+ currentPath?: string;
39
+ /** ความกว้าง sidebar */
40
+ width?: string;
41
+ /** className เพิ่มเติม */
42
+ className?: string;
43
+ }
44
+
45
+ declare function StaffSidebar({ orgLogo, orgName, orgSubtitle, menuItems, bottomMenuItems, user, roleLabel, onNavigate, onLogout, currentPath, width, className, }: StaffSidebarProps): react_jsx_runtime.JSX.Element;
46
+
47
+ interface SidebarHeaderProps {
48
+ orgLogo?: string;
49
+ orgName: string;
50
+ orgSubtitle?: string;
51
+ }
52
+ declare function SidebarHeader({ orgLogo, orgName, orgSubtitle }: SidebarHeaderProps): react_jsx_runtime.JSX.Element;
53
+
54
+ interface SidebarMenuProps {
55
+ menuItems: MenuItem[];
56
+ onItemClick: (path: string) => void;
57
+ currentPath?: string;
58
+ }
59
+ declare function SidebarMenu({ menuItems, onItemClick, currentPath }: SidebarMenuProps): react_jsx_runtime.JSX.Element;
60
+
61
+ interface SidebarUserProfileProps {
62
+ user: User | null;
63
+ roleLabel: string;
64
+ onLogout: () => void;
65
+ }
66
+ declare function SidebarUserProfile({ user, roleLabel, onLogout, }: SidebarUserProfileProps): react_jsx_runtime.JSX.Element | null;
67
+
68
+ interface NotificationItem {
69
+ id: string | number;
70
+ title: string;
71
+ description: string;
72
+ date: string;
73
+ type: 'info' | 'success' | 'warning' | 'error' | 'reminder';
74
+ isRead: boolean;
75
+ }
76
+ interface UserHeaderProps {
77
+ user?: {
78
+ firstName?: string;
79
+ lastName?: string;
80
+ pictureUrl?: string;
81
+ };
82
+ notifications?: NotificationItem[];
83
+ onToggleSidebar?: () => void;
84
+ /** Custom bell icon */
85
+ notificationBell?: React.ReactNode;
86
+ onMarkAllRead?: () => void;
87
+ onViewAll?: () => void;
88
+ className?: string;
89
+ }
90
+ declare function UserHeader({ user, notifications, onToggleSidebar, notificationBell, onMarkAllRead, onViewAll, className, }: UserHeaderProps): react_jsx_runtime.JSX.Element;
91
+
92
+ interface UserSidebarProps {
93
+ user: User | null;
94
+ roleLabel: string;
95
+ menuItems: MenuItem[];
96
+ onNavigate: (path: string) => void;
97
+ onLogout: () => void;
98
+ isOpen: boolean;
99
+ onClose: () => void;
100
+ roleColor?: string;
101
+ }
102
+ declare function UserSidebar({ user, roleLabel, menuItems, onNavigate, onLogout, isOpen, onClose, roleColor, }: UserSidebarProps): react_jsx_runtime.JSX.Element;
103
+
104
+ export { type MenuItem, type NotificationItem, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, type User, UserHeader, UserSidebar };
@@ -0,0 +1,104 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface User {
4
+ id?: string | number;
5
+ firstName?: string;
6
+ lastName?: string;
7
+ pictureUrl?: string;
8
+ role?: string;
9
+ }
10
+ interface MenuItem {
11
+ id: string;
12
+ title: string;
13
+ path?: string;
14
+ icon?: React.ReactNode;
15
+ children?: MenuItem[];
16
+ dividerAfter?: boolean;
17
+ }
18
+ interface StaffSidebarProps {
19
+ /** URL รูปตราองค์กร */
20
+ orgLogo?: string;
21
+ /** ชื่อองค์กร */
22
+ orgName: string;
23
+ /** ชื่อรอง เช่น จังหวัด */
24
+ orgSubtitle?: string;
25
+ /** เมนูหลัก */
26
+ menuItems: MenuItem[];
27
+ /** เมนูล่าง เช่น ตั้งค่าระบบ */
28
+ bottomMenuItems?: MenuItem[];
29
+ /** ข้อมูลผู้ใช้ */
30
+ user: User | null;
31
+ /** ป้ายแสดงตำแหน่ง เช่น "เจ้าหน้าที่" */
32
+ roleLabel: string;
33
+ /** callback เมื่อคลิกเมนู */
34
+ onNavigate: (path: string) => void;
35
+ /** callback เมื่อกดออกจากระบบ */
36
+ onLogout: () => void;
37
+ /** path ปัจจุบันเพื่อ highlight active menu */
38
+ currentPath?: string;
39
+ /** ความกว้าง sidebar */
40
+ width?: string;
41
+ /** className เพิ่มเติม */
42
+ className?: string;
43
+ }
44
+
45
+ declare function StaffSidebar({ orgLogo, orgName, orgSubtitle, menuItems, bottomMenuItems, user, roleLabel, onNavigate, onLogout, currentPath, width, className, }: StaffSidebarProps): react_jsx_runtime.JSX.Element;
46
+
47
+ interface SidebarHeaderProps {
48
+ orgLogo?: string;
49
+ orgName: string;
50
+ orgSubtitle?: string;
51
+ }
52
+ declare function SidebarHeader({ orgLogo, orgName, orgSubtitle }: SidebarHeaderProps): react_jsx_runtime.JSX.Element;
53
+
54
+ interface SidebarMenuProps {
55
+ menuItems: MenuItem[];
56
+ onItemClick: (path: string) => void;
57
+ currentPath?: string;
58
+ }
59
+ declare function SidebarMenu({ menuItems, onItemClick, currentPath }: SidebarMenuProps): react_jsx_runtime.JSX.Element;
60
+
61
+ interface SidebarUserProfileProps {
62
+ user: User | null;
63
+ roleLabel: string;
64
+ onLogout: () => void;
65
+ }
66
+ declare function SidebarUserProfile({ user, roleLabel, onLogout, }: SidebarUserProfileProps): react_jsx_runtime.JSX.Element | null;
67
+
68
+ interface NotificationItem {
69
+ id: string | number;
70
+ title: string;
71
+ description: string;
72
+ date: string;
73
+ type: 'info' | 'success' | 'warning' | 'error' | 'reminder';
74
+ isRead: boolean;
75
+ }
76
+ interface UserHeaderProps {
77
+ user?: {
78
+ firstName?: string;
79
+ lastName?: string;
80
+ pictureUrl?: string;
81
+ };
82
+ notifications?: NotificationItem[];
83
+ onToggleSidebar?: () => void;
84
+ /** Custom bell icon */
85
+ notificationBell?: React.ReactNode;
86
+ onMarkAllRead?: () => void;
87
+ onViewAll?: () => void;
88
+ className?: string;
89
+ }
90
+ declare function UserHeader({ user, notifications, onToggleSidebar, notificationBell, onMarkAllRead, onViewAll, className, }: UserHeaderProps): react_jsx_runtime.JSX.Element;
91
+
92
+ interface UserSidebarProps {
93
+ user: User | null;
94
+ roleLabel: string;
95
+ menuItems: MenuItem[];
96
+ onNavigate: (path: string) => void;
97
+ onLogout: () => void;
98
+ isOpen: boolean;
99
+ onClose: () => void;
100
+ roleColor?: string;
101
+ }
102
+ declare function UserSidebar({ user, roleLabel, menuItems, onNavigate, onLogout, isOpen, onClose, roleColor, }: UserSidebarProps): react_jsx_runtime.JSX.Element;
103
+
104
+ export { type MenuItem, type NotificationItem, SidebarHeader, SidebarMenu, SidebarUserProfile, StaffSidebar, type StaffSidebarProps, type User, UserHeader, UserSidebar };