@goat-bravos/intern-hub-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.
Files changed (97) hide show
  1. package/.editorconfig +17 -0
  2. package/.vscode/extensions.json +4 -0
  3. package/.vscode/launch.json +20 -0
  4. package/.vscode/mcp.json +9 -0
  5. package/.vscode/tasks.json +42 -0
  6. package/README.md +267 -0
  7. package/angular.json +131 -0
  8. package/ng-package.json +7 -0
  9. package/package.json +46 -0
  10. package/projects/layout-templates/README.md +63 -0
  11. package/projects/layout-templates/ng-package.json +7 -0
  12. package/projects/layout-templates/package.json +12 -0
  13. package/projects/layout-templates/src/lib/layout-templates.spec.ts +23 -0
  14. package/projects/layout-templates/src/lib/layout-templates.ts +15 -0
  15. package/projects/layout-templates/src/public-api.ts +5 -0
  16. package/projects/layout-templates/tsconfig.lib.json +17 -0
  17. package/projects/layout-templates/tsconfig.lib.prod.json +11 -0
  18. package/projects/layout-templates/tsconfig.spec.json +15 -0
  19. package/projects/ui-components/README.md +63 -0
  20. package/projects/ui-components/ng-package.json +7 -0
  21. package/projects/ui-components/package.json +12 -0
  22. package/projects/ui-components/src/lib/ui-components.spec.ts +23 -0
  23. package/projects/ui-components/src/lib/ui-components.ts +15 -0
  24. package/projects/ui-components/src/public-api.ts +5 -0
  25. package/projects/ui-components/tsconfig.lib.json +17 -0
  26. package/projects/ui-components/tsconfig.lib.prod.json +11 -0
  27. package/projects/ui-components/tsconfig.spec.json +15 -0
  28. package/public/B/341/273/231 icon message (1).svg" +87 -0
  29. package/public/B/341/273/231 icon message (2).svg" +104 -0
  30. package/public/B/341/273/231 icon message.svg" +98 -0
  31. package/public/FPT-IS-Logo.png +0 -0
  32. package/public/FPT_IS_Logo.svg +12 -0
  33. package/public/favicon.ico +0 -0
  34. package/public/federation.manifest.json +8 -0
  35. package/src/app/app.config.ts +22 -0
  36. package/src/app/app.html +1 -0
  37. package/src/app/app.routes.ts +24 -0
  38. package/src/app/app.scss +0 -0
  39. package/src/app/app.spec.ts +23 -0
  40. package/src/app/app.ts +19 -0
  41. package/src/index.html +15 -0
  42. package/src/libs/layouts/header/header.component.html +27 -0
  43. package/src/libs/layouts/header/header.component.scss +96 -0
  44. package/src/libs/layouts/header/header.component.ts +13 -0
  45. package/src/libs/layouts/main-layout/main-layout.component.html +15 -0
  46. package/src/libs/layouts/main-layout/main-layout.component.scss +35 -0
  47. package/src/libs/layouts/main-layout/main-layout.component.ts +17 -0
  48. package/src/libs/layouts/main-layout-test/main-layout-test.component.html +296 -0
  49. package/src/libs/layouts/main-layout-test/main-layout-test.component.scss +94 -0
  50. package/src/libs/layouts/main-layout-test/main-layout-test.component.ts +121 -0
  51. package/src/libs/layouts/sidebar/sidebar.component.html +7 -0
  52. package/src/libs/layouts/sidebar/sidebar.component.scss +38 -0
  53. package/src/libs/layouts/sidebar/sidebar.component.ts +19 -0
  54. package/src/libs/shared/components/approval/approval-list/approval-list.component.html +19 -0
  55. package/src/libs/shared/components/approval/approval-list/approval-list.component.scss +24 -0
  56. package/src/libs/shared/components/approval/approval-list/approval-list.component.ts +19 -0
  57. package/src/libs/shared/components/approval/approval-list-item/approval-list-item.component.html +21 -0
  58. package/src/libs/shared/components/approval/approval-list-item/approval-list-item.component.scss +28 -0
  59. package/src/libs/shared/components/approval/approval-list-item/approval-list-item.component.ts +20 -0
  60. package/src/libs/shared/components/approval/approval-list-item/approval-list-item.model.ts +8 -0
  61. package/src/libs/shared/components/button/button-container/button-container.component.html +20 -0
  62. package/src/libs/shared/components/button/button-container/button-container.component.scss +49 -0
  63. package/src/libs/shared/components/button/button-container/button-container.component.ts +38 -0
  64. package/src/libs/shared/components/button/button-container/button-container.model.ts +58 -0
  65. package/src/libs/shared/components/button/label-button/label-button.component.html +11 -0
  66. package/src/libs/shared/components/button/label-button/label-button.component.scss +13 -0
  67. package/src/libs/shared/components/button/label-button/label-button.component.ts +18 -0
  68. package/src/libs/shared/components/functional-label/functional-label.component.html +4 -0
  69. package/src/libs/shared/components/functional-label/functional-label.component.scss +58 -0
  70. package/src/libs/shared/components/functional-label/functional-label.component.ts +15 -0
  71. package/src/libs/shared/components/input/input-calendar/input-calendar.component.html +52 -0
  72. package/src/libs/shared/components/input/input-calendar/input-calendar.component.scss +98 -0
  73. package/src/libs/shared/components/input/input-calendar/input-calendar.component.ts +102 -0
  74. package/src/libs/shared/components/input/input-label/input-label.component.html +0 -0
  75. package/src/libs/shared/components/input/input-label/input-label.component.scss +0 -0
  76. package/src/libs/shared/components/input/input-label/input-label.component.ts +0 -0
  77. package/src/libs/shared/components/input/input-stepper/input-stepper.component.html +62 -0
  78. package/src/libs/shared/components/input/input-stepper/input-stepper.component.scss +211 -0
  79. package/src/libs/shared/components/input/input-stepper/input-stepper.component.ts +73 -0
  80. package/src/libs/shared/components/input/input-text/input-text.component.html +40 -0
  81. package/src/libs/shared/components/input/input-text/input-text.component.scss +143 -0
  82. package/src/libs/shared/components/input/input-text/input-text.component.ts +63 -0
  83. package/src/libs/shared/components/pop-up/pop-up-confirm/pop-up-confirm.component.html +15 -0
  84. package/src/libs/shared/components/pop-up/pop-up-confirm/pop-up-confirm.component.scss +70 -0
  85. package/src/libs/shared/components/pop-up/pop-up-confirm/pop-up-confirm.component.ts +29 -0
  86. package/src/libs/shared/components/table/table-body/table-body.component.html +18 -0
  87. package/src/libs/shared/components/table/table-body/table-body.component.scss +6 -0
  88. package/src/libs/shared/components/table/table-body/table-body.component.ts +17 -0
  89. package/src/libs/shared/components/table/table-header/table-header.component.html +27 -0
  90. package/src/libs/shared/components/table/table-header/table-header.component.scss +91 -0
  91. package/src/libs/shared/components/table/table-header/table-header.component.ts +25 -0
  92. package/src/main.ts +6 -0
  93. package/src/public-api.ts +22 -0
  94. package/src/styles.scss +27 -0
  95. package/tsconfig.app.json +15 -0
  96. package/tsconfig.json +53 -0
  97. package/tsconfig.spec.json +15 -0
@@ -0,0 +1,24 @@
1
+ import { Routes } from '@angular/router';
2
+
3
+ import { MainLayoutComponent } from '../libs/layouts/main-layout/main-layout.component';
4
+ import { MainLayoutTestComponent } from '../libs/layouts/main-layout-test/main-layout-test.component';
5
+ export const routes: Routes = [
6
+ {
7
+ path: '',
8
+ component: MainLayoutComponent,
9
+ data: {
10
+ sidebarItems: [
11
+ { icon: 'dsi-home-01-line', content: 'Trang Chủ' },
12
+ { icon: 'dsi-mail-01-line', content: 'Hòm Thư Góp Ý' },
13
+ { icon: 'dsi-map-01-line', content: 'Lộ Trình Đào Tạo' },
14
+ { icon: 'dsi-file-01-line', content: 'Tài Liệu' },
15
+ ],
16
+ },
17
+ children: [
18
+ {
19
+ path: '',
20
+ component: MainLayoutTestComponent,
21
+ },
22
+ ],
23
+ },
24
+ ];
File without changes
@@ -0,0 +1,23 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { App } from './app';
3
+
4
+ describe('App', () => {
5
+ beforeEach(async () => {
6
+ await TestBed.configureTestingModule({
7
+ imports: [App],
8
+ }).compileComponents();
9
+ });
10
+
11
+ it('should create the app', () => {
12
+ const fixture = TestBed.createComponent(App);
13
+ const app = fixture.componentInstance;
14
+ expect(app).toBeTruthy();
15
+ });
16
+
17
+ it('should render title', async () => {
18
+ const fixture = TestBed.createComponent(App);
19
+ await fixture.whenStable();
20
+ const compiled = fixture.nativeElement as HTMLElement;
21
+ expect(compiled.querySelector('h1')?.textContent).toContain('Hello, intern-hub-layout');
22
+ });
23
+ });
package/src/app/app.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { Component, inject, signal, OnInit } from '@angular/core';
2
+ import { RouterOutlet } from '@angular/router';
3
+ import { DynamicDsService } from 'dynamic-ds';
4
+
5
+ @Component({
6
+ selector: 'app-root',
7
+ standalone: true,
8
+ imports: [RouterOutlet],
9
+ templateUrl: './app.html',
10
+ })
11
+ export class App implements OnInit {
12
+ protected readonly title = signal('shell-app');
13
+
14
+ private readonly themeService = inject(DynamicDsService);
15
+
16
+ ngOnInit() {
17
+ this.themeService.initializeTheme().subscribe();
18
+ }
19
+ }
package/src/index.html ADDED
@@ -0,0 +1,15 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>ShellApp</title>
6
+ <base href="/" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
8
+ <link rel="icon" type="image/x-icon" href="FPT_IS_Logo.svg" />
9
+ <link rel="preconnect" href="https://rsms.me/" />
10
+ <link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
11
+ </head>
12
+ <body>
13
+ <app-root></app-root>
14
+ </body>
15
+ </html>
@@ -0,0 +1,27 @@
1
+ <header class="app-header">
2
+ <div class="header-left">
3
+ <img class="logo" src="FPT-IS-Logo.png" alt="FPT IS Logo" />
4
+ </div>
5
+
6
+ <div class="header-right">
7
+ <button class="header-btn" aria-label="Help">
8
+ <span class="icon">?</span>
9
+ </button>
10
+
11
+ <button class="header-btn notify-btn" aria-label="Notifications">
12
+ <span class="icon">🔔</span>
13
+ </button>
14
+
15
+ <button class="header-btn" aria-label="Settings">
16
+ <span class="icon">⚙️</span>
17
+ </button>
18
+
19
+ <div class="header-user">
20
+ <button class="user-btn">
21
+ <img class="avatar" src="FPT-IS-Logo.png" alt="User avatar" />
22
+ <span class="user-name">User Name</span>
23
+ <span class="caret">▾</span>
24
+ </button>
25
+ </div>
26
+ </div>
27
+ </header>
@@ -0,0 +1,96 @@
1
+ // Header Component - System Design Format
2
+
3
+ .app-header {
4
+ height: 70px;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ padding: 16px 8px;
9
+ width: 100%;
10
+ }
11
+
12
+ .header-left {
13
+ display: flex;
14
+ align-items: center;
15
+ }
16
+
17
+ .logo {
18
+ height: 46px;
19
+ width: 93px;
20
+ object-fit: contain;
21
+ }
22
+
23
+ .header-right {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 8px;
27
+ }
28
+
29
+ // Icon Button
30
+ .header-btn {
31
+ position: relative;
32
+ width: 36px;
33
+ height: 36px;
34
+
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+
39
+ background: transparent;
40
+ border-radius: var(--radius-full);
41
+ border: none;
42
+
43
+ cursor: pointer;
44
+ transition: background-color 0.2s ease;
45
+ }
46
+
47
+ .header-btn:hover {
48
+ background-color: var(--neutral-color-100);
49
+ }
50
+
51
+ .icon {
52
+ font-size: var(--font-lg);
53
+ }
54
+
55
+ // User Section
56
+ .header-user {
57
+ margin-left: 8px;
58
+ }
59
+
60
+ .user-btn {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 8px;
64
+
65
+ padding: 4px 8px;
66
+
67
+ background: transparent;
68
+ border: none;
69
+ border-radius: var(--radius-full);
70
+
71
+ cursor: pointer;
72
+ transition: background-color 0.2s ease;
73
+ }
74
+
75
+ .user-btn:hover {
76
+ background-color: var(--neutral-color-100);
77
+ }
78
+
79
+ .avatar {
80
+ width: 28px;
81
+ height: 28px;
82
+ border-radius: var(--radius-full);
83
+ object-fit: cover;
84
+ }
85
+
86
+ .user-name {
87
+ font-size: var(--font-sm);
88
+ font-weight: 500;
89
+ color: var(--neutral-color-875);
90
+ white-space: nowrap;
91
+ }
92
+
93
+ .caret {
94
+ font-size: var(--font-xs);
95
+ color: var(--neutral-color-600);
96
+ }
@@ -0,0 +1,13 @@
1
+ import { Component } from "@angular/core";
2
+
3
+ @Component({
4
+ selector: 'app-header-component',
5
+ standalone: true,
6
+
7
+ templateUrl: './header.component.html',
8
+ styleUrls: ['./header.component.scss']
9
+ })
10
+ export class HeaderComponent {
11
+
12
+
13
+ }
@@ -0,0 +1,15 @@
1
+ <div class="web-container">
2
+ <div class="main-layout">
3
+ <app-header-component></app-header-component>
4
+
5
+ <div class="layout-body">
6
+ <div class="layout-body-sidebar">
7
+ <app-sidebar [menuItems]="sidebarItems"></app-sidebar>
8
+ </div>
9
+
10
+ <div class="layout-body-content">
11
+ <router-outlet />
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
@@ -0,0 +1,35 @@
1
+ // Main Layout Component - System Design Format
2
+
3
+ .web-container {
4
+ display: flex;
5
+ justify-content: center;
6
+ align-items: center;
7
+ background-color: var(--brand-100);
8
+ }
9
+
10
+ .main-layout {
11
+ background-color: var(--brand-100);
12
+ min-height: 100vh; /* Grow with content */
13
+ display: flex;
14
+ flex-direction: column;
15
+ padding: 4px;
16
+ max-width: 1370px;
17
+ min-width: 1370px;
18
+ width: 1370px;
19
+ }
20
+
21
+ .layout-body {
22
+ padding: 16px 8px;
23
+ margin: 0;
24
+ display: flex;
25
+ height: 100%;
26
+ justify-content: space-between;
27
+ }
28
+
29
+ .layout-body-content {
30
+ flex: 1;
31
+ }
32
+
33
+ .layout-body-sidebar {
34
+ margin-right: 20px;
35
+ }
@@ -0,0 +1,17 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { RouterOutlet } from '@angular/router';
4
+
5
+ import { HeaderComponent } from '../header/header.component';
6
+ import { SidebarComponent, SidebarItem } from '../sidebar/sidebar.component';
7
+
8
+ @Component({
9
+ selector: 'app-main-layout',
10
+ standalone: true,
11
+ imports: [CommonModule, RouterOutlet, HeaderComponent, SidebarComponent],
12
+ templateUrl: './main-layout.component.html',
13
+ styleUrls: ['./main-layout.component.scss'],
14
+ })
15
+ export class MainLayoutComponent {
16
+ @Input() sidebarItems: SidebarItem[] = [];
17
+ }
@@ -0,0 +1,296 @@
1
+ <ng-template #textRight let-content>
2
+ <p class="text-gray-700">{{ content }}</p>
3
+ </ng-template>
4
+
5
+ <ng-template #buttonRight let-onClick="onClick">
6
+ <button class="px-4 py-2 bg-black text-white rounded hover:bg-gray-800" (click)="onClick()">
7
+ Xem chi tiết
8
+ </button>
9
+ </ng-template>
10
+
11
+ <!-- DEMO BUTTON AREA -->
12
+ <div class="demo-buttons">
13
+ <!-- Row 1: Brand buttons -->
14
+ <app-button-container
15
+ size="xs"
16
+ content="XS"
17
+ backgroundColor="var(--brand-600)"
18
+ color="#fff"
19
+ (buttonClick)="onButtonClick('XS Brand')"
20
+ ></app-button-container>
21
+ <app-button-container
22
+ size="sm"
23
+ content="SM Button"
24
+ leftIcon="◀"
25
+ rightIcon="▶"
26
+ backgroundColor="var(--brand-600)"
27
+ color="#fff"
28
+ (buttonClick)="onButtonClick('SM Brand')"
29
+ ></app-button-container>
30
+ <app-button-container
31
+ size="md"
32
+ content="MD Button"
33
+ leftIcon="◀"
34
+ rightIcon="▶"
35
+ backgroundColor="var(--brand-600)"
36
+ color="#fff"
37
+ (buttonClick)="onButtonClick('MD Brand')"
38
+ ></app-button-container>
39
+ <app-button-container
40
+ size="lg"
41
+ content="LG Button"
42
+ leftIcon="◀"
43
+ rightIcon="▶"
44
+ backgroundColor="var(--brand-600)"
45
+ color="#fff"
46
+ (buttonClick)="onButtonClick('LG Brand')"
47
+ ></app-button-container>
48
+ </div>
49
+
50
+ <div class="demo-buttons">
51
+ <!-- Row 2: Primary buttons -->
52
+ <app-button-container
53
+ size="xs"
54
+ content="XS"
55
+ backgroundColor="var(--primary-600)"
56
+ color="#fff"
57
+ (buttonClick)="onButtonClick('XS Primary')"
58
+ ></app-button-container>
59
+ <app-button-container
60
+ size="sm"
61
+ content="SM Button"
62
+ leftIcon="★"
63
+ rightIcon="★"
64
+ backgroundColor="var(--primary-600)"
65
+ color="#fff"
66
+ (buttonClick)="onButtonClick('SM Primary')"
67
+ ></app-button-container>
68
+ <app-button-container
69
+ size="md"
70
+ content="MD Button"
71
+ leftIcon="★"
72
+ rightIcon="★"
73
+ backgroundColor="var(--primary-600)"
74
+ color="#fff"
75
+ (buttonClick)="onButtonClick('MD Primary')"
76
+ ></app-button-container>
77
+ <app-button-container
78
+ size="lg"
79
+ content="LG Button"
80
+ leftIcon="★"
81
+ rightIcon="★"
82
+ backgroundColor="var(--primary-600)"
83
+ color="#fff"
84
+ (buttonClick)="onButtonClick('LG Primary')"
85
+ ></app-button-container>
86
+ </div>
87
+
88
+ <!-- APPROVAL LIST DEMO -->
89
+ <div class="demo-approval-list">
90
+ <app-approval-list
91
+ [rows]="approvalRows"
92
+ headerContentLeft="Thao tác"
93
+ headerContentRight="Danh sách chờ duyệt"
94
+ width="600px"
95
+ >
96
+ </app-approval-list>
97
+ </div>
98
+
99
+ <!-- INPUT TEXT DEMO SECTION -->
100
+ <div class="demo-section">
101
+ <h3 class="demo-section-title">INPUT TEXT</h3>
102
+ <div class="input-text-demo-grid">
103
+ <!-- Row 1: Basic inputs -->
104
+ <app-input-text
105
+ headerInput="Input Label"
106
+ placeholder="Placeholder..."
107
+ [required]="true"
108
+ width="100%"
109
+ icon="dsi dsi-anchor-line dsi-theme-red-600"
110
+ ></app-input-text>
111
+
112
+ <app-input-text
113
+ headerInput="Input Label"
114
+ placeholder="Placeholder..."
115
+ [required]="true"
116
+ width="100%"
117
+ ></app-input-text>
118
+
119
+ <app-input-text placeholder="Placeholder..." width="100%"></app-input-text>
120
+
121
+ <app-input-text placeholder="Placeholder..." width="100%" [readonly]="true"></app-input-text>
122
+
123
+ <!-- Row 2: With helper text and character limit -->
124
+ <app-input-text
125
+ headerInput="Input Label"
126
+ placeholder="Placeholder..."
127
+ [required]="true"
128
+ [maxLength]="500"
129
+ [showLimit]="true"
130
+ width="100%"
131
+ ></app-input-text>
132
+
133
+ <app-input-text
134
+ headerInput="Input Label"
135
+ placeholder="Placeholder..."
136
+ [required]="true"
137
+ [maxLength]="500"
138
+ [showLimit]="true"
139
+ width="100%"
140
+ ></app-input-text>
141
+
142
+ <app-input-text
143
+ placeholder="Placeholder..."
144
+ [maxLength]="500"
145
+ [showLimit]="true"
146
+ width="100%"
147
+ ></app-input-text>
148
+
149
+ <app-input-text
150
+ placeholder="Placeholder..."
151
+ [maxLength]="500"
152
+ [showLimit]="true"
153
+ width="100%"
154
+ [readonly]="true"
155
+ ></app-input-text>
156
+ </div>
157
+ </div>
158
+
159
+ <!-- PASSWORD DEMO SECTION -->
160
+ <div class="demo-section">
161
+ <h3 class="demo-section-title">PASSWORD INPUT</h3>
162
+ <div class="input-text-demo-grid">
163
+ <app-input-text
164
+ headerInput="Mật khẩu"
165
+ placeholder="Nhập mật khẩu..."
166
+ [typeInput]="passwordType"
167
+ [icon]="passwordIcon"
168
+ (iconClick)="togglePassword()"
169
+ [required]="true"
170
+ width="250px"
171
+ ></app-input-text>
172
+
173
+ <app-input-text
174
+ headerInput="Tìm kiếm"
175
+ placeholder="Tìm kiếm theo tên..."
176
+ icon="fa-solid fa-magnifying-glass"
177
+ width="250px"
178
+ ></app-input-text>
179
+ </div>
180
+ </div>
181
+
182
+ <!-- CALENDAR DEMO SECTION -->
183
+ <div class="demo-section">
184
+ <h3 class="demo-section-title">CALENDAR INPUT</h3>
185
+ <div class="input-text-demo-grid">
186
+ <app-input-calendar
187
+ headerInput="Ngày sinh"
188
+ placeholder="dd/mm/yyyy"
189
+ [required]="true"
190
+ ></app-input-calendar>
191
+
192
+ <app-input-calendar
193
+ headerInput="Date Picker"
194
+ placeholder="dd/mm/yyyy"
195
+ [required]="true"
196
+ ></app-input-calendar>
197
+ </div>
198
+ </div>
199
+
200
+ <!-- STEPPER DEMO SECTION -->
201
+ <div class="demo-section">
202
+ <h3 class="demo-section-title">INPUT STEPPER</h3>
203
+ <div class="stepper-demo-grid">
204
+ <!-- Default State -->
205
+ <app-input-stepper
206
+ headerInput="Input Label"
207
+ helperText="Placeholder of hint text to help"
208
+ [min]="0"
209
+ [max]="100"
210
+ [step]="1"
211
+ [value]="0"
212
+ [required]="true"
213
+ width="250px"
214
+ ></app-input-stepper>
215
+
216
+ <!-- Negative State -->
217
+ <app-input-stepper
218
+ headerInput="Input Label"
219
+ helperText="Placeholder of hint text to help"
220
+ state="negative"
221
+ [min]="0"
222
+ [max]="100"
223
+ [step]="1"
224
+ [value]="0"
225
+ [required]="true"
226
+ width="250px"
227
+ ></app-input-stepper>
228
+
229
+ <!-- Positive State -->
230
+ <app-input-stepper
231
+ headerInput="Input Label"
232
+ helperText="Placeholder of hint text to help"
233
+ state="positive"
234
+ [min]="0"
235
+ [max]="100"
236
+ [step]="1"
237
+ [value]="0"
238
+ [required]="true"
239
+ width="250px"
240
+ ></app-input-stepper>
241
+
242
+ <!-- Disabled State -->
243
+ <app-input-stepper
244
+ headerInput="Input Label"
245
+ helperText="Placeholder of hint text to help"
246
+ [disabled]="true"
247
+ [min]="0"
248
+ [max]="100"
249
+ [step]="1"
250
+ [value]="0"
251
+ [required]="true"
252
+ width="250px"
253
+ ></app-input-stepper>
254
+ </div>
255
+ </div>
256
+
257
+ <!-- TABLE DEMO SECTION -->
258
+ <div class="demo-section">
259
+ <h3 class="demo-section-title">TABLE</h3>
260
+ <ng-template #statusTemplate let-status>
261
+ <app-button-container
262
+ [content]="status"
263
+ [backgroundColor]="status === 'Active' ? 'var(--brand-600)' : 'var(--neutral-color-100)'"
264
+ [color]="status === 'Active' ? 'var(--neutral-color-100)' : 'var(--neutral-color-600)'"
265
+ borderColor="transparent"
266
+ ></app-button-container>
267
+ </ng-template>
268
+
269
+ <table>
270
+ <thead>
271
+ <tr app-table-header [columns]="columns" [backgroundColor]="tableBackgroundColor"></tr>
272
+ </thead>
273
+
274
+ <tbody
275
+ app-table-body
276
+ [rows]="rows"
277
+ [columns]="columns"
278
+ [columnTemplates]="{ status: statusTemplate }"
279
+ ></tbody>
280
+ </table>
281
+ </div>
282
+
283
+ <!-- ROUTER CONTENT (keep it for children if any, though likely unused now) -->
284
+ <router-outlet />
285
+
286
+ @if (showPopup) {
287
+ <app-pop-up-confirm
288
+ imgUrl="/Bộ icon message (1).svg"
289
+ title="Xác nhận hành động"
290
+ content="Bạn có chắc chắn muốn thực hiện hành động này không?"
291
+ colorButton="var(--brand-600)"
292
+ (confirmClick)="onPopupConfirm()"
293
+ (cancelClick)="onPopupCancel()"
294
+ >
295
+ </app-pop-up-confirm>
296
+ }
@@ -0,0 +1,94 @@
1
+ .web-container {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: flex-start;
5
+ background-color: var(--brand-100);
6
+ min-height: 100vh;
7
+ width: 100%;
8
+ }
9
+
10
+ .main-layout {
11
+ background-color: var(--brand-100);
12
+ min-height: 100vh;
13
+ display: flex;
14
+ flex-direction: column;
15
+ padding: 4px;
16
+ width: 100%;
17
+ max-width: 1370px;
18
+ margin: 0 auto;
19
+ }
20
+
21
+ .main-layout-content {
22
+ background-color: var(--brand-900);
23
+ }
24
+
25
+ .layout-body {
26
+ padding: 16px 8px;
27
+ margin: 0;
28
+ display: flex;
29
+ flex: 1;
30
+ width: 100%;
31
+ justify-content: flex-start;
32
+ }
33
+
34
+ .layout-body-sidebar {
35
+ flex-shrink: 0;
36
+ width: auto;
37
+ min-width: 56px;
38
+ }
39
+
40
+ .demo-buttons {
41
+ display: flex;
42
+ gap: 16px;
43
+ flex-wrap: wrap;
44
+ align-items: center;
45
+
46
+ & + .demo-buttons {
47
+ margin-top: 16px;
48
+ }
49
+ }
50
+
51
+ .layout-body-content {
52
+ flex: 1;
53
+ min-width: 0;
54
+ overflow: hidden;
55
+ margin-left: 12px;
56
+ }
57
+
58
+ .stepper-demo-grid {
59
+ display: grid;
60
+ grid-template-columns: repeat(2, 1fr);
61
+ gap: 24px;
62
+ padding: 24px;
63
+ background-color: var(--neutral-color-10);
64
+ border-radius: var(--radius-md);
65
+ }
66
+
67
+ .demo-section {
68
+ margin-top: 24px;
69
+ padding: 24px;
70
+ background-color: var(--neutral-color-10);
71
+ border-radius: var(--radius-md);
72
+ border: 2px dashed var(--neutral-color-200);
73
+ }
74
+
75
+ .demo-section-title {
76
+ font-size: var(--font-sm);
77
+ font-weight: 600;
78
+ color: var(--neutral-color-600);
79
+ margin: 0 0 16px 0;
80
+ text-transform: uppercase;
81
+ letter-spacing: 0.5px;
82
+ }
83
+
84
+ .input-text-demo-grid {
85
+ display: grid;
86
+ grid-template-columns: repeat(4, 1fr);
87
+ gap: 24px;
88
+ }
89
+
90
+ table {
91
+ width: 100%;
92
+ border-collapse: collapse;
93
+ table-layout: fixed;
94
+ }