@duyanhdev/mvp-ifs-ui-kit 21.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 (170) hide show
  1. package/.editorconfig +16 -0
  2. package/.gitmodules +3 -0
  3. package/.postcssrc.json +5 -0
  4. package/.prettierignore +14 -0
  5. package/.prettierrc.json +29 -0
  6. package/LICENSE.md +21 -0
  7. package/README.md +59 -0
  8. package/angular.json +98 -0
  9. package/eslint.config.js +89 -0
  10. package/package.json +59 -0
  11. package/public/demo/images/flag/flag_placeholder.png +0 -0
  12. package/public/demo/images/footer-image.gif +0 -0
  13. package/public/demo/images/galleria/galleria1.jpg +0 -0
  14. package/public/demo/images/galleria/galleria10.jpg +0 -0
  15. package/public/demo/images/galleria/galleria10s.jpg +0 -0
  16. package/public/demo/images/galleria/galleria11.jpg +0 -0
  17. package/public/demo/images/galleria/galleria11s.jpg +0 -0
  18. package/public/demo/images/galleria/galleria12.jpg +0 -0
  19. package/public/demo/images/galleria/galleria12s.jpg +0 -0
  20. package/public/demo/images/galleria/galleria13.jpg +0 -0
  21. package/public/demo/images/galleria/galleria13s.jpg +0 -0
  22. package/public/demo/images/galleria/galleria14.jpg +0 -0
  23. package/public/demo/images/galleria/galleria14s.jpg +0 -0
  24. package/public/demo/images/galleria/galleria15.jpg +0 -0
  25. package/public/demo/images/galleria/galleria15s.jpg +0 -0
  26. package/public/demo/images/galleria/galleria1s.jpg +0 -0
  27. package/public/demo/images/galleria/galleria2.jpg +0 -0
  28. package/public/demo/images/galleria/galleria2s.jpg +0 -0
  29. package/public/demo/images/galleria/galleria3.jpg +0 -0
  30. package/public/demo/images/galleria/galleria3s.jpg +0 -0
  31. package/public/demo/images/galleria/galleria4.jpg +0 -0
  32. package/public/demo/images/galleria/galleria4s.jpg +0 -0
  33. package/public/demo/images/galleria/galleria5.jpg +0 -0
  34. package/public/demo/images/galleria/galleria5s.jpg +0 -0
  35. package/public/demo/images/galleria/galleria6.jpg +0 -0
  36. package/public/demo/images/galleria/galleria6s.jpg +0 -0
  37. package/public/demo/images/galleria/galleria7.jpg +0 -0
  38. package/public/demo/images/galleria/galleria7s.jpg +0 -0
  39. package/public/demo/images/galleria/galleria8.jpg +0 -0
  40. package/public/demo/images/galleria/galleria8s.jpg +0 -0
  41. package/public/demo/images/galleria/galleria9.jpg +0 -0
  42. package/public/demo/images/galleria/galleria9s.jpg +0 -0
  43. package/public/demo/images/product/bamboo-watch.jpg +0 -0
  44. package/public/demo/images/product/black-watch.jpg +0 -0
  45. package/public/demo/images/product/blue-band.jpg +0 -0
  46. package/public/demo/images/product/blue-t-shirt.jpg +0 -0
  47. package/public/demo/images/product/bracelet.jpg +0 -0
  48. package/public/demo/images/product/brown-purse.jpg +0 -0
  49. package/public/demo/images/product/chakra-bracelet.jpg +0 -0
  50. package/public/demo/images/product/galaxy-earrings.jpg +0 -0
  51. package/public/demo/images/product/game-controller.jpg +0 -0
  52. package/public/demo/images/product/gaming-set.jpg +0 -0
  53. package/public/demo/images/product/gold-phone-case.jpg +0 -0
  54. package/public/demo/images/product/green-earbuds.jpg +0 -0
  55. package/public/demo/images/product/green-t-shirt.jpg +0 -0
  56. package/public/demo/images/product/grey-t-shirt.jpg +0 -0
  57. package/public/demo/images/product/headphones.jpg +0 -0
  58. package/public/demo/images/product/light-green-t-shirt.jpg +0 -0
  59. package/public/demo/images/product/lime-band.jpg +0 -0
  60. package/public/demo/images/product/mini-speakers.jpg +0 -0
  61. package/public/demo/images/product/painted-phone-case.jpg +0 -0
  62. package/public/demo/images/product/pink-band.jpg +0 -0
  63. package/public/demo/images/product/pink-purse.jpg +0 -0
  64. package/public/demo/images/product/product-placeholder.svg +10 -0
  65. package/public/demo/images/product/purple-band.jpg +0 -0
  66. package/public/demo/images/product/purple-gemstone-necklace.jpg +0 -0
  67. package/public/demo/images/product/purple-t-shirt.jpg +0 -0
  68. package/public/demo/images/product/shoes.jpg +0 -0
  69. package/public/demo/images/product/sneakers.jpg +0 -0
  70. package/public/demo/images/product/teal-t-shirt.jpg +0 -0
  71. package/public/demo/images/product/yellow-earbuds.jpg +0 -0
  72. package/public/demo/images/product/yoga-mat.jpg +0 -0
  73. package/public/demo/images/product/yoga-set.jpg +0 -0
  74. package/src/app/layout/component/configurator/app.configurator.html +48 -0
  75. package/src/app/layout/component/configurator/app.configurator.ts +396 -0
  76. package/src/app/layout/component/floatingconfigurator/app.floatingconfigurator.ts +31 -0
  77. package/src/app/layout/component/footer/app.footer.scss +52 -0
  78. package/src/app/layout/component/footer/app.footer.ts +26 -0
  79. package/src/app/layout/component/layout/app.layout.ts +50 -0
  80. package/src/app/layout/component/menu/app.menu.html +7 -0
  81. package/src/app/layout/component/menu/app.menu.scss +13 -0
  82. package/src/app/layout/component/menu/app.menu.ts +90 -0
  83. package/src/app/layout/component/menuitem/app.menuitem.html +56 -0
  84. package/src/app/layout/component/menuitem/app.menuitem.scss +218 -0
  85. package/src/app/layout/component/menuitem/app.menuitem.ts +126 -0
  86. package/src/app/layout/component/sidebar/app.sidebar.html +3 -0
  87. package/src/app/layout/component/sidebar/app.sidebar.scss +0 -0
  88. package/src/app/layout/component/sidebar/app.sidebar.ts +106 -0
  89. package/src/app/layout/component/topbar/app.topbar.html +190 -0
  90. package/src/app/layout/component/topbar/app.topbar.scss +8 -0
  91. package/src/app/layout/component/topbar/app.topbar.ts +68 -0
  92. package/src/app/layout/service/layout.service.ts +117 -0
  93. package/src/app/pages/auth/access.ts +32 -0
  94. package/src/app/pages/auth/auth.routes.ts +10 -0
  95. package/src/app/pages/auth/error.ts +32 -0
  96. package/src/app/pages/auth/login.ts +71 -0
  97. package/src/app/pages/crud/crud.ts +387 -0
  98. package/src/app/pages/dashboard/dashboard.css +778 -0
  99. package/src/app/pages/dashboard/dashboard.html +191 -0
  100. package/src/app/pages/dashboard/dashboard.ts +348 -0
  101. package/src/app/pages/documentation/documentation.ts +73 -0
  102. package/src/app/pages/empty/empty.ts +11 -0
  103. package/src/app/pages/landing/components/featureswidget.ts +139 -0
  104. package/src/app/pages/landing/components/footerwidget.ts +73 -0
  105. package/src/app/pages/landing/components/herowidget.ts +25 -0
  106. package/src/app/pages/landing/components/highlightswidget.ts +46 -0
  107. package/src/app/pages/landing/components/pricingwidget.ts +119 -0
  108. package/src/app/pages/landing/components/topbarwidget.component.ts +68 -0
  109. package/src/app/pages/landing/landing.ts +31 -0
  110. package/src/app/pages/notfound/notfound.ts +68 -0
  111. package/src/app/pages/pages.routes.ts +17 -0
  112. package/src/app/pages/profile/profile.html +57 -0
  113. package/src/app/pages/profile/profile.scss +145 -0
  114. package/src/app/pages/profile/profile.ts +19 -0
  115. package/src/app/pages/service/country.service.ts +255 -0
  116. package/src/app/pages/service/customer.service.ts +9057 -0
  117. package/src/app/pages/service/icon.service.ts +23 -0
  118. package/src/app/pages/service/node.service.ts +816 -0
  119. package/src/app/pages/service/photo.service.ts +103 -0
  120. package/src/app/pages/service/product.service.ts +1322 -0
  121. package/src/app/pages/tickets/tickets-create/tickets-create.html +140 -0
  122. package/src/app/pages/tickets/tickets-create/tickets-create.scss +617 -0
  123. package/src/app/pages/tickets/tickets-create/tickets-create.ts +104 -0
  124. package/src/app/pages/tickets/tickets-list/ticket-list.html +150 -0
  125. package/src/app/pages/tickets/tickets-list/ticket-list.scss +392 -0
  126. package/src/app/pages/tickets/tickets-list/ticket-list.ts +178 -0
  127. package/src/app/pages/uikit/buttondemo.ts +254 -0
  128. package/src/app/pages/uikit/chartdemo.ts +290 -0
  129. package/src/app/pages/uikit/filedemo.ts +52 -0
  130. package/src/app/pages/uikit/formlayoutdemo.ts +129 -0
  131. package/src/app/pages/uikit/inputdemo.ts +339 -0
  132. package/src/app/pages/uikit/listdemo.ts +217 -0
  133. package/src/app/pages/uikit/mediademo.ts +1021 -0
  134. package/src/app/pages/uikit/menudemo.ts +540 -0
  135. package/src/app/pages/uikit/messagesdemo.ts +101 -0
  136. package/src/app/pages/uikit/miscdemo.ts +192 -0
  137. package/src/app/pages/uikit/overlaydemo.ts +235 -0
  138. package/src/app/pages/uikit/panelsdemo.ts +235 -0
  139. package/src/app/pages/uikit/tabledemo.ts +568 -0
  140. package/src/app/pages/uikit/timelinedemo.ts +141 -0
  141. package/src/app/pages/uikit/treedemo.ts +75 -0
  142. package/src/app/pages/uikit/uikit.routes.ts +35 -0
  143. package/src/app.component.ts +22 -0
  144. package/src/app.config.ts +23 -0
  145. package/src/app.routes.ts +23 -0
  146. package/src/assets/demo/code.scss +17 -0
  147. package/src/assets/demo/demo.scss +2 -0
  148. package/src/assets/demo/flags/flags.css +984 -0
  149. package/src/assets/layout/_core.scss +24 -0
  150. package/src/assets/layout/_footer.scss +8 -0
  151. package/src/assets/layout/_main.scss +21 -0
  152. package/src/assets/layout/_menu.scss +159 -0
  153. package/src/assets/layout/_mixins.scss +15 -0
  154. package/src/assets/layout/_preloading.scss +47 -0
  155. package/src/assets/layout/_responsive.scss +111 -0
  156. package/src/assets/layout/_topbar.scss +201 -0
  157. package/src/assets/layout/_typography.scss +68 -0
  158. package/src/assets/layout/_utils.scss +25 -0
  159. package/src/assets/layout/layout.scss +13 -0
  160. package/src/assets/layout/variables/_common.scss +21 -0
  161. package/src/assets/layout/variables/_dark.scss +5 -0
  162. package/src/assets/layout/variables/_light.scss +5 -0
  163. package/src/assets/styles.scss +4 -0
  164. package/src/assets/tailwind.css +32 -0
  165. package/src/index.html +15 -0
  166. package/src/main.ts +5 -0
  167. package/tsconfig.app.json +15 -0
  168. package/tsconfig.json +33 -0
  169. package/tsconfig.spec.json +15 -0
  170. package/vercel.json +9 -0
@@ -0,0 +1,1021 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, OnInit } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { ButtonModule } from 'primeng/button';
5
+ import { InputTextModule } from 'primeng/inputtext';
6
+ import { SelectModule } from 'primeng/select';
7
+ import { DatePickerModule } from 'primeng/datepicker';
8
+ import { TextareaModule } from 'primeng/textarea';
9
+ import { CheckboxModule } from 'primeng/checkbox';
10
+
11
+ interface City {
12
+ name: string;
13
+ code: string;
14
+ }
15
+ interface Code {
16
+ name: string;
17
+ code: string;
18
+ }
19
+
20
+ @Component({
21
+ selector: 'app-media-demo',
22
+ standalone: true,
23
+ imports: [CommonModule, FormsModule, ButtonModule, InputTextModule, SelectModule, DatePickerModule, TextareaModule, CheckboxModule],
24
+ styles: `
25
+ /* ══════════════════════════════════
26
+ LIGHT MODE TOKENS
27
+ ══════════════════════════════════ */
28
+ :host {
29
+ --blue-dark: #1e3a8a;
30
+ --blue-main: #2563eb;
31
+ --blue-mid: #3b82f6;
32
+ --blue-light: #93c5fd;
33
+ --blue-soft: #eff6ff;
34
+ --blue-ring: rgba(37, 99, 235, 0.14);
35
+
36
+ --bg-page: #f1f5f9;
37
+ --bg-body: #ffffff;
38
+ --bg-field: #ffffff;
39
+ --bg-card: #ffffff;
40
+ --bg-card-hover: #f8faff;
41
+
42
+ --border-color: #e5e7eb;
43
+ --border-input: #d1d5db;
44
+
45
+ --text-primary: #111827;
46
+ --text-label: #6b7280;
47
+ --text-item: #374151;
48
+ --text-placeholder: #9ca3af;
49
+
50
+ --divider: linear-gradient(90deg, #bfdbfe, transparent);
51
+ --shadow-body: 0 8px 32px rgba(0, 0, 0, 0.07);
52
+ }
53
+
54
+ /* ══════════════════════════════════
55
+ DARK MODE TOKENS
56
+ ══════════════════════════════════ */
57
+ :host-context(.app-dark) {
58
+ --blue-dark: #1d4ed8;
59
+ --blue-main: #3b82f6;
60
+ --blue-mid: #60a5fa;
61
+ --blue-light: #93c5fd;
62
+ --blue-soft: rgba(59, 130, 246, 0.12);
63
+ --blue-ring: rgba(59, 130, 246, 0.2);
64
+
65
+ --bg-page: #0f172a;
66
+ --bg-body: #1e293b;
67
+ --bg-field: #0f172a;
68
+ --bg-card: #1e293b;
69
+ --bg-card-hover: #263548;
70
+
71
+ --border-color: #334155;
72
+ --border-input: #334155;
73
+
74
+ --text-primary: #f1f5f9;
75
+ --text-label: #94a3b8;
76
+ --text-item: #cbd5e1;
77
+ --text-placeholder: #475569;
78
+
79
+ --divider: linear-gradient(90deg, rgba(59, 130, 246, 0.3), transparent);
80
+ --shadow-body: 0 8px 32px rgba(0, 0, 0, 0.4);
81
+ }
82
+
83
+ /* ══════════════════════════════════
84
+ LAYOUT
85
+ ══════════════════════════════════ */
86
+ .page-wrapper {
87
+ max-width: 1200px;
88
+ margin: 0 auto;
89
+ padding: 32px 16px 64px;
90
+ background: var(--bg-page);
91
+ min-height: 100vh;
92
+ transition: background 0.3s;
93
+ }
94
+
95
+ /* ── Header ── */
96
+ .form-header {
97
+ background: linear-gradient(135deg, var(--blue-dark) 0%, var(--blue-main) 55%, var(--blue-mid) 100%);
98
+ border-radius: 20px 20px 0 0;
99
+ padding: 32px 40px;
100
+ position: relative;
101
+ overflow: hidden;
102
+ }
103
+ .form-header::before {
104
+ content: '';
105
+ position: absolute;
106
+ inset: 0;
107
+ background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff' fill-opacity='0.04'%3E%3Ccircle cx='30' cy='30' r='20'/%3E%3C/g%3E%3C/svg%3E");
108
+ }
109
+ .form-header h1 {
110
+ font-size: clamp(15px, 2.5vw, 21px);
111
+ font-weight: 800;
112
+ color: #fff;
113
+ text-align: center;
114
+ letter-spacing: 0.5px;
115
+ position: relative;
116
+ margin: 0;
117
+ }
118
+ .form-header p {
119
+ text-align: center;
120
+ color: rgba(255, 255, 255, 0.65);
121
+ font-size: 13px;
122
+ margin: 6px 0 0;
123
+ position: relative;
124
+ }
125
+
126
+ /* ── Body ── */
127
+ .form-body {
128
+ background: var(--bg-body);
129
+ border-radius: 0 0 20px 20px;
130
+ border: 1px solid var(--border-color);
131
+ border-top: none;
132
+ padding: 32px 40px 40px;
133
+ box-shadow: var(--shadow-body);
134
+ transition:
135
+ background 0.3s,
136
+ border-color 0.3s;
137
+ }
138
+
139
+ /* ── Section title ── */
140
+ .section-title {
141
+ display: flex;
142
+ align-items: center;
143
+ gap: 12px;
144
+ margin-bottom: 16px;
145
+ margin-top: 28px;
146
+ &:first-child {
147
+ margin-top: 0;
148
+ }
149
+ }
150
+ .section-num {
151
+ width: 32px;
152
+ height: 32px;
153
+ border-radius: 50%;
154
+ background: linear-gradient(135deg, var(--blue-dark), var(--blue-main));
155
+ color: #fff;
156
+ font-size: 13px;
157
+ font-weight: 700;
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: center;
161
+ flex-shrink: 0;
162
+ box-shadow: 0 4px 12px var(--blue-ring);
163
+ }
164
+ .section-name {
165
+ font-size: 14px;
166
+ font-weight: 700;
167
+ color: var(--text-primary);
168
+ letter-spacing: 0.4px;
169
+ text-transform: uppercase;
170
+ }
171
+ .section-divider {
172
+ height: 1px;
173
+ background: var(--divider);
174
+ margin-bottom: 20px;
175
+ }
176
+
177
+ /* ── Fields ── */
178
+ .field-group {
179
+ display: grid;
180
+ grid-template-columns: 1fr 1fr;
181
+ gap: 18px;
182
+ margin-bottom: 8px;
183
+ }
184
+ .field {
185
+ display: flex;
186
+ flex-direction: column;
187
+ gap: 6px;
188
+ }
189
+ .field label {
190
+ font-size: 11px;
191
+ font-weight: 700;
192
+ color: var(--text-label);
193
+ text-transform: uppercase;
194
+ letter-spacing: 0.7px;
195
+ }
196
+
197
+ :host ::ng-deep {
198
+ /* ── Input ── */
199
+ .p-inputtext {
200
+ background: var(--bg-field) !important;
201
+ color: var(--text-primary) !important;
202
+ border-color: var(--border-input) !important;
203
+ border-radius: 10px !important;
204
+ font-size: 13.5px !important;
205
+ padding: 10px 14px !important;
206
+ width: 100% !important;
207
+ transition:
208
+ border-color 0.2s,
209
+ box-shadow 0.2s,
210
+ background 0.3s !important;
211
+
212
+ &:hover {
213
+ border-color: var(--blue-light) !important;
214
+ }
215
+ &:focus {
216
+ border-color: var(--blue-main) !important;
217
+ box-shadow: 0 0 0 3px var(--blue-ring) !important;
218
+ }
219
+ &::placeholder {
220
+ color: var(--text-placeholder) !important;
221
+ }
222
+ }
223
+
224
+ /* ── Select ── */
225
+ .p-select {
226
+ background: var(--bg-field) !important;
227
+ border-color: var(--border-input) !important;
228
+ border-radius: 10px !important;
229
+ width: 100% !important;
230
+ transition:
231
+ border-color 0.2s,
232
+ background 0.3s !important;
233
+
234
+ &:hover {
235
+ border-color: var(--blue-light) !important;
236
+ }
237
+ &.p-focus {
238
+ border-color: var(--blue-main) !important;
239
+ box-shadow: 0 0 0 3px var(--blue-ring) !important;
240
+ }
241
+
242
+ .p-select-label {
243
+ color: var(--text-primary) !important;
244
+ &.p-placeholder {
245
+ color: var(--text-placeholder) !important;
246
+ }
247
+ }
248
+ .p-select-dropdown {
249
+ color: var(--text-label) !important;
250
+ }
251
+ }
252
+
253
+ /* Select panel dropdown */
254
+ .p-select-overlay {
255
+ background: var(--bg-body) !important;
256
+ border-color: var(--border-color) !important;
257
+ border-radius: 12px !important;
258
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15) !important;
259
+
260
+ .p-select-option {
261
+ color: var(--text-item) !important;
262
+ &:hover,
263
+ &.p-focus {
264
+ background: var(--blue-soft) !important;
265
+ color: var(--blue-main) !important;
266
+ }
267
+ &.p-select-option-selected {
268
+ background: var(--blue-soft) !important;
269
+ color: var(--blue-main) !important;
270
+ font-weight: 600 !important;
271
+ }
272
+ }
273
+ }
274
+
275
+ /* ── Datepicker ── */
276
+ input.p-datepicker-input {
277
+ background: var(--bg-field) !important;
278
+ color: var(--text-primary) !important;
279
+ border-color: var(--border-input) !important;
280
+ border-radius: 10px !important;
281
+ width: 100% !important;
282
+ &:focus {
283
+ border-color: var(--blue-main) !important;
284
+ box-shadow: 0 0 0 3px var(--blue-ring) !important;
285
+ }
286
+ &::placeholder {
287
+ color: var(--text-placeholder) !important;
288
+ }
289
+ }
290
+ .p-datepicker-panel {
291
+ background: var(--bg-body) !important;
292
+ border-color: var(--border-color) !important;
293
+ border-radius: 12px !important;
294
+
295
+ .p-datepicker-header {
296
+ background: var(--bg-body) !important;
297
+ color: var(--text-primary) !important;
298
+ border-color: var(--border-color) !important;
299
+ }
300
+ .p-datepicker-day-view .p-datepicker-day-cell span {
301
+ color: var(--text-item) !important;
302
+ &:hover {
303
+ background: var(--blue-soft) !important;
304
+ }
305
+ }
306
+ .p-datepicker-day-cell.p-datepicker-today span {
307
+ background: var(--blue-soft) !important;
308
+ color: var(--blue-main) !important;
309
+ font-weight: 700 !important;
310
+ }
311
+ .p-datepicker-day-cell.p-datepicker-selected span {
312
+ background: var(--blue-main) !important;
313
+ color: #fff !important;
314
+ }
315
+ }
316
+
317
+ /* ── Textarea ── */
318
+ .p-textarea {
319
+ background: var(--bg-field) !important;
320
+ color: var(--text-primary) !important;
321
+ border-color: var(--border-input) !important;
322
+ border-radius: 10px !important;
323
+ width: 100% !important;
324
+ font-size: 13.5px !important;
325
+ resize: vertical !important;
326
+ transition:
327
+ border-color 0.2s,
328
+ background 0.3s !important;
329
+
330
+ &:focus {
331
+ border-color: var(--blue-main) !important;
332
+ box-shadow: 0 0 0 3px var(--blue-ring) !important;
333
+ }
334
+ &::placeholder {
335
+ color: var(--text-placeholder) !important;
336
+ }
337
+ }
338
+
339
+ /* ── Button ── */
340
+ .p-button:not(.p-button-outlined) {
341
+ background: var(--blue-main) !important;
342
+ border-color: var(--blue-main) !important;
343
+ color: #fff !important;
344
+ &:hover {
345
+ background: var(--blue-dark) !important;
346
+ border-color: var(--blue-dark) !important;
347
+ }
348
+ }
349
+ .p-button-outlined {
350
+ background: transparent !important;
351
+ color: var(--blue-main) !important;
352
+ border-color: var(--blue-main) !important;
353
+ &:hover {
354
+ background: var(--blue-soft) !important;
355
+ }
356
+ }
357
+
358
+ /* ── Checkbox ── */
359
+ .p-checkbox .p-checkbox-box {
360
+ background: var(--bg-field) !important;
361
+ border-color: var(--border-input) !important;
362
+ transition:
363
+ background 0.2s,
364
+ border-color 0.2s !important;
365
+ }
366
+ .p-checkbox:not(.p-checkbox-checked):hover .p-checkbox-box {
367
+ border-color: var(--blue-light) !important;
368
+ }
369
+ .p-checkbox.p-checkbox-checked .p-checkbox-box {
370
+ background: var(--blue-main) !important;
371
+ border-color: var(--blue-main) !important;
372
+ }
373
+ }
374
+
375
+ /* ── Purchase cards ── */
376
+ .purchase-grid {
377
+ display: grid;
378
+ grid-template-columns: repeat(4, 1fr);
379
+ gap: 14px;
380
+ margin-bottom: 8px;
381
+ }
382
+ .purchase-card {
383
+ border: 1.5px solid var(--border-color);
384
+ border-radius: 14px;
385
+ overflow: hidden;
386
+ display: flex;
387
+ flex-direction: column;
388
+ background: var(--bg-card);
389
+ transition:
390
+ border-color 0.2s,
391
+ box-shadow 0.2s,
392
+ background 0.3s;
393
+
394
+ &:hover {
395
+ border-color: var(--blue-light);
396
+ box-shadow: 0 4px 16px var(--blue-ring);
397
+ background: var(--bg-card-hover);
398
+ }
399
+ }
400
+ .purchase-header {
401
+ display: flex;
402
+ align-items: center;
403
+ gap: 10px;
404
+ padding: 11px 14px;
405
+ background: linear-gradient(135deg, var(--blue-dark) 0%, var(--blue-main) 55%, var(--blue-mid) 100%);
406
+ flex-shrink: 0;
407
+ }
408
+ .purchase-num {
409
+ width: 22px;
410
+ height: 22px;
411
+ background: rgba(255, 255, 255, 0.2);
412
+ border: 1.5px solid rgba(255, 255, 255, 0.35);
413
+ border-radius: 50%;
414
+ color: #fff;
415
+ font-size: 11px;
416
+ font-weight: 700;
417
+ display: flex;
418
+ align-items: center;
419
+ justify-content: center;
420
+ flex-shrink: 0;
421
+ }
422
+ .purchase-title {
423
+ font-size: 11.5px;
424
+ font-weight: 700;
425
+ color: #fff;
426
+ text-transform: uppercase;
427
+ letter-spacing: 0.4px;
428
+ margin: 0;
429
+ line-height: 1.3;
430
+ }
431
+ .purchase-body {
432
+ padding: 10px 12px;
433
+ display: flex;
434
+ flex-direction: column;
435
+ gap: 6px;
436
+ background: var(--bg-card);
437
+ flex: 1;
438
+ transition: background 0.3s;
439
+ }
440
+ .check-item {
441
+ display: flex;
442
+ align-items: flex-start;
443
+ gap: 9px;
444
+ padding: 7px 9px;
445
+ border-radius: 8px;
446
+ cursor: pointer;
447
+ transition: background 0.15s;
448
+
449
+ &:hover {
450
+ background: var(--blue-soft);
451
+ }
452
+
453
+ label {
454
+ font-size: 12.5px;
455
+ color: var(--text-item);
456
+ cursor: pointer;
457
+ line-height: 1.45;
458
+ margin: 0;
459
+ transition: color 0.15s;
460
+ }
461
+ &:has(.p-checkbox-checked) {
462
+ background: var(--blue-soft);
463
+ label {
464
+ color: var(--blue-main);
465
+ font-weight: 600;
466
+ }
467
+ }
468
+ }
469
+
470
+ /* ── Footer ── */
471
+ .form-footer {
472
+ display: flex;
473
+ justify-content: flex-end;
474
+ gap: 12px;
475
+ margin-top: 28px;
476
+ padding-top: 22px;
477
+ border-top: 1px solid var(--border-color);
478
+ }
479
+
480
+ /* ── Responsive ── */
481
+ @media (max-width: 900px) {
482
+ .purchase-grid {
483
+ grid-template-columns: repeat(2, 1fr);
484
+ }
485
+ }
486
+ @media (max-width: 640px) {
487
+ .field-group {
488
+ grid-template-columns: 1fr;
489
+ }
490
+ .purchase-grid {
491
+ grid-template-columns: 1fr;
492
+ }
493
+ .form-body {
494
+ padding: 20px;
495
+ }
496
+ .form-header {
497
+ padding: 24px 20px;
498
+ }
499
+ }
500
+ `,
501
+ template: `
502
+ <div class="page-wrapper">
503
+ <!-- Header -->
504
+ <div class="form-header">
505
+ <h1>Mẫu Form Ghi Nhận Lỗi Trong Công Việc Mua Hàng</h1>
506
+ <p>Vui lòng điền đầy đủ thông tin bên dưới</p>
507
+ </div>
508
+
509
+ <!-- Body -->
510
+ <div class="form-body">
511
+ <!-- Section 1 -->
512
+ <div class="section-title">
513
+ <div class="section-num">1</div>
514
+ <span class="section-name">Thông Tin Chung</span>
515
+ </div>
516
+ <div class="section-divider"></div>
517
+ <div class="field-group">
518
+ <div class="field">
519
+ <label>Người lập</label>
520
+ <input pInputText [(ngModel)]="form.nguoiLap" placeholder="Họ và tên người lập" />
521
+ </div>
522
+ <div class="field">
523
+ <label>Nhóm</label>
524
+ <p-select [options]="cities" [(ngModel)]="form.nhom" optionLabel="name" placeholder="Chọn nhóm" />
525
+ </div>
526
+ <div class="field">
527
+ <label>Vị trí / Chức danh</label>
528
+ <input pInputText [(ngModel)]="form.viTri" placeholder="Vd: Nhân viên mua hàng" />
529
+ </div>
530
+ <div class="field">
531
+ <label>Nhà cung cấp</label>
532
+ <p-select [options]="supplier" [(ngModel)]="form.nhaCungCap" optionLabel="name" placeholder="Chọn nhà cung cấp" />
533
+ </div>
534
+ <div class="field">
535
+ <label>Mã hàng</label>
536
+ <p-select [options]="productCode" [(ngModel)]="form.maHang" optionLabel="name" placeholder="Chọn mã hàng" />
537
+ </div>
538
+ <div class="field">
539
+ <label>Ngày phát sinh</label>
540
+ <p-datepicker [(ngModel)]="form.ngayPhatSinh" placeholder="dd/mm/yyyy" dateFormat="dd/mm/yy" [showIcon]="true" />
541
+ </div>
542
+ <div class="field">
543
+ <label>Tên lỗi</label>
544
+ <p-select [options]="cities" [(ngModel)]="form.tenLoi" optionLabel="name" placeholder="Chọn lỗi" />
545
+ </div>
546
+ <div class="field">
547
+ <label>Bộ phận liên quan</label>
548
+ <p-select [options]="cities" [(ngModel)]="form.boPhan" optionLabel="name" placeholder="Chọn bộ phận" />
549
+ </div>
550
+ </div>
551
+
552
+ <!-- Section 2 -->
553
+ <div class="section-title">
554
+ <div class="section-num">2</div>
555
+ <span class="section-name">Giai Đoạn Phát Sinh & Lỗi Phát Sinh</span>
556
+ </div>
557
+ <div class="section-divider"></div>
558
+ <div class="purchase-grid">
559
+ @for (group of purchaseGroups; track group.num) {
560
+ <div class="purchase-card">
561
+ <div class="purchase-header">
562
+ <span class="purchase-num">{{ group.num }}</span>
563
+ <p class="purchase-title">{{ group.title }}</p>
564
+ </div>
565
+ <div class="purchase-body">
566
+ @for (item of group.items; track item.id) {
567
+ <div class="check-item">
568
+ <p-checkbox [inputId]="item.id" [name]="'group' + group.num" [value]="item.value" [(ngModel)]="selected" />
569
+ <label [for]="item.id">{{ item.label }}</label>
570
+ </div>
571
+ }
572
+ </div>
573
+ </div>
574
+ }
575
+ </div>
576
+
577
+ <!-- Section 3 -->
578
+ <div class="section-title">
579
+ <div class="section-num">3</div>
580
+ <span class="section-name">Mô Tả Chi Tiết Lỗi</span>
581
+ </div>
582
+ <div class="section-divider"></div>
583
+ <div class="field">
584
+ <label>Nội dung mô tả</label>
585
+ <textarea pTextarea [(ngModel)]="form.moTa" rows="4" placeholder="Mô tả chi tiết tình huống xảy ra lỗi…"> </textarea>
586
+ </div>
587
+
588
+ <!-- Section 4 -->
589
+ <div class="section-title">
590
+ <div class="section-num">4</div>
591
+ <span class="section-name">Phân loại NGUYÊN NHÂN (Fishbone 6M)</span>
592
+ </div>
593
+ <div class="section-divider"></div>
594
+ <div class="purchase-grid">
595
+ @for (group of reason; track group.num) {
596
+ <div class="purchase-card">
597
+ <div class="check-item">
598
+ <p-checkbox [inputId]="'group' + group.num" [name]="'group' + group.num" [value]="group.title" [(ngModel)]="selected" />
599
+ <label [for]="group.num">{{ group.title }}</label>
600
+ </div>
601
+ </div>
602
+ }
603
+ </div>
604
+
605
+ <!-- Section 5 -->
606
+ <div class="section-title">
607
+ <div class="section-num">5</div>
608
+ <span class="section-name">Ảnh hưởng/Hậu quả</span>
609
+ </div>
610
+ <div class="section-divider"></div>
611
+ <div class="purchase-grid">
612
+ @for (group of reason; track group.num) {
613
+ <div class="purchase-card">
614
+ <div class="check-item">
615
+ <p-checkbox [inputId]="'group' + group.num" [name]="'group' + group.num" [value]="group.title" [(ngModel)]="selected" />
616
+ <label [for]="group.num">{{ group.title }}</label>
617
+ </div>
618
+ </div>
619
+ }
620
+ </div>
621
+
622
+ <!-- Section 6 -->
623
+ <div class="section-title">
624
+ <div class="section-num">6</div>
625
+ <span class="section-name">Cách xử lý khi lỗi đã xảy ra</span>
626
+ </div>
627
+ <div class="section-divider"></div>
628
+ <div class="field">
629
+ <label>Nội dung mô tả</label>
630
+ <textarea pTextarea [(ngModel)]="form.moTa" rows="4" placeholder="Mô tả chi tiết tình huống xảy ra lỗi…"> </textarea>
631
+
632
+ <div class="mt-2 flex ">
633
+ <span class="text-black font-bold text-xl border-b-2 border-black dark:border-white">Xác nhận của cấp trên:</span>
634
+
635
+ @for (option of option; track option.value) {
636
+ <div class="purchase-card">
637
+ <div class="check-item">
638
+ <p-checkbox [inputId]="'option' + option.value" [name]="'option' + option.value" [value]="option.name" [(ngModel)]="selected" />
639
+ <label [for]="option.value">{{ option.name }}</label>
640
+ </div>
641
+ </div>
642
+ }
643
+ </div>
644
+ </div>
645
+
646
+ <!-- Section 7 -->
647
+ <div class="section-title">
648
+ <div class="section-num">7</div>
649
+ <span class="section-name">Đối sách</span>
650
+ </div>
651
+ <div class="section-divider"></div>
652
+ <div class="field">
653
+ <label>Nội dung mô tả</label>
654
+ <textarea pTextarea [(ngModel)]="form.moTa" rows="4" placeholder="Mô tả chi tiết tình huống xảy ra lỗi…"> </textarea>
655
+ <div class="mt-2 flex ">
656
+ <span class="text-black font-bold text-xl border-b-2 border-black dark:border-white">Xác nhận của cấp trên:</span>
657
+
658
+ @for (option of option; track option.value) {
659
+ <div class="purchase-card">
660
+ <div class="check-item">
661
+ <p-checkbox [inputId]="'option' + option.value" [name]="'option' + option.value" [value]="option.name" [(ngModel)]="selected" />
662
+ <label [for]="option.value">{{ option.name }}</label>
663
+ </div>
664
+ </div>
665
+ }
666
+ </div>
667
+ </div>
668
+
669
+ <!-- Section 8 -->
670
+ <div class="section-title">
671
+ <div class="section-num">8</div>
672
+ <span class="section-name"> Quy trình - quy định - biểu mẫu (tham khảo)</span>
673
+ </div>
674
+ <div class="section-divider"></div>
675
+ <div class="purchase-grid">
676
+ <div class="purchase-card">
677
+ <div class="purchase-header flex items-center">
678
+ <span class="purchase-num">1</span>
679
+ <p class="purchase-title">Tên quy trình - quy định</p>
680
+ </div>
681
+ <div class="flex flex-col gap-3">
682
+ <div *ngFor="let item of items; let i = index; trackBy: trackByIndex" class="flex items-center gap-2">
683
+ <input pInputText [(ngModel)]="items[i]" [name]="'item_' + i" placeholder="Nhập giá trị..." class="flex-1" />
684
+
685
+ <!-- Nút xóa — chỉ hiện khi có hơn 1 ô -->
686
+ <button
687
+ *ngIf="items.length > 1"
688
+ type="button"
689
+ (click)="removeItem(i)"
690
+ class="w-8 h-8 flex items-center justify-center
691
+ rounded-lg border border-black/15 text-gray-400
692
+ hover:bg-red-50 hover:border-red-300 hover:text-red-500
693
+ transition-all"
694
+ >
695
+ <i class="pi pi-minus text-xs"></i>
696
+ </button>
697
+ </div>
698
+
699
+ <!-- Nút thêm -->
700
+ <button
701
+ type="button"
702
+ (click)="addItem()"
703
+ class="flex items-center gap-2 px-4 py-2 w-fit
704
+ rounded-lg border border-dashed border-black/20
705
+ text-sm text-gray-400 font-medium
706
+ hover:border-black/40 hover:text-black
707
+ transition-all dark:border-white/20
708
+ dark:hover:border-white/50 dark:hover:text-white"
709
+ >
710
+ <i class="pi pi-plus text-xs"></i>
711
+ Thêm dòng
712
+ </button>
713
+ </div>
714
+ </div>
715
+ <div class="purchase-card">
716
+ <div class="purchase-header">
717
+ <span class="purchase-num">2</span>
718
+ <p class="purchase-title">Hiện trạng</p>
719
+ </div>
720
+ <div class="flex flex-col gap-3">
721
+ <div *ngFor="let item of items; let i = index; trackBy: trackByIndex" class="flex items-center gap-2">
722
+ <input pInputText [(ngModel)]="items[i]" [name]="'item_' + i" placeholder="Nhập giá trị..." class="flex-1" />
723
+
724
+ <!-- Nút xóa — chỉ hiện khi có hơn 1 ô -->
725
+ <button
726
+ *ngIf="items.length > 1"
727
+ type="button"
728
+ (click)="removeItem(i)"
729
+ class="w-8 h-8 flex items-center justify-center
730
+ rounded-lg border border-black/15 text-gray-400
731
+ hover:bg-red-50 hover:border-red-300 hover:text-red-500
732
+ transition-all"
733
+ >
734
+ <i class="pi pi-minus text-xs"></i>
735
+ </button>
736
+ </div>
737
+
738
+ <!-- Nút thêm -->
739
+ <button
740
+ type="button"
741
+ (click)="addItem()"
742
+ class="flex items-center gap-2 px-4 py-2 w-fit
743
+ rounded-lg border border-dashed border-black/20
744
+ text-sm text-gray-400 font-medium
745
+ hover:border-black/40 hover:text-black
746
+ transition-all dark:border-white/20
747
+ dark:hover:border-white/50 dark:hover:text-white"
748
+ >
749
+ <i class="pi pi-plus text-xs"></i>
750
+ Thêm dòng
751
+ </button>
752
+ </div>
753
+ </div>
754
+ <div class="purchase-card">
755
+ <div class="purchase-header">
756
+ <span class="purchase-num">3</span>
757
+ <p class="purchase-title">Mô tả ngắn</p>
758
+ </div>
759
+ <div class="flex flex-col gap-3">
760
+ <div *ngFor="let item of items; let i = index; trackBy: trackByIndex" class="flex items-center gap-2">
761
+ <input pInputText [(ngModel)]="items[i]" [name]="'item_' + i" placeholder="Nhập giá trị..." class="flex-1" />
762
+
763
+ <!-- Nút xóa — chỉ hiện khi có hơn 1 ô -->
764
+ <button
765
+ *ngIf="items.length > 1"
766
+ type="button"
767
+ (click)="removeItem(i)"
768
+ class="w-8 h-8 flex items-center justify-center
769
+ rounded-lg border border-black/15 text-gray-400
770
+ hover:bg-red-50 hover:border-red-300 hover:text-red-500
771
+ transition-all"
772
+ >
773
+ <i class="pi pi-minus text-xs"></i>
774
+ </button>
775
+ </div>
776
+
777
+ <!-- Nút thêm -->
778
+ <button
779
+ type="button"
780
+ (click)="addItem()"
781
+ class="flex items-center gap-2 px-4 py-2 w-fit
782
+ rounded-lg border border-dashed border-black/20
783
+ text-sm text-gray-400 font-medium
784
+ hover:border-black/40 hover:text-black
785
+ transition-all dark:border-white/20
786
+ dark:hover:border-white/50 dark:hover:text-white"
787
+ >
788
+ <i class="pi pi-plus text-xs"></i>
789
+ Thêm dòng
790
+ </button>
791
+ </div>
792
+ </div>
793
+ <div class="purchase-card">
794
+ <div class="purchase-header">
795
+ <span class="purchase-num">4</span>
796
+ <p class="purchase-title">Hành động đề xuất</p>
797
+ </div>
798
+ <div class="flex flex-col gap-3">
799
+ <div *ngFor="let item of items; let i = index; trackBy: trackByIndex" class="flex items-center gap-2">
800
+ <input pInputText [(ngModel)]="items[i]" [name]="'item_' + i" placeholder="Nhập giá trị..." class="flex-1" />
801
+
802
+ <!-- Nút xóa — chỉ hiện khi có hơn 1 ô -->
803
+ <button
804
+ *ngIf="items.length > 1"
805
+ type="button"
806
+ (click)="removeItem(i)"
807
+ class="w-8 h-8 flex items-center justify-center
808
+ rounded-lg border border-black/15 text-gray-400
809
+ hover:bg-red-50 hover:border-red-300 hover:text-red-500
810
+ transition-all"
811
+ >
812
+ <i class="pi pi-minus text-xs"></i>
813
+ </button>
814
+ </div>
815
+
816
+ <!-- Nút thêm -->
817
+ <button
818
+ type="button"
819
+ (click)="addItem()"
820
+ class="flex items-center gap-2 px-4 py-2 w-fit
821
+ rounded-lg border border-dashed border-black/20
822
+ text-sm text-gray-400 font-medium
823
+ hover:border-black/40 hover:text-black
824
+ transition-all dark:border-white/20
825
+ dark:hover:border-white/50 dark:hover:text-white"
826
+ >
827
+ <i class="pi pi-plus text-xs"></i>
828
+ Thêm dòng
829
+ </button>
830
+ </div>
831
+ </div>
832
+ </div>
833
+
834
+ <!-- Footer -->
835
+ <div class="form-footer">
836
+ <p-button label="Hủy" severity="secondary" outlined />
837
+ <p-button label="Gửi Form" icon="pi pi-send" iconPos="right" (click)="submitForm()" />
838
+ </div>
839
+ </div>
840
+ </div>
841
+ `
842
+ })
843
+ export class MediaDemo implements OnInit {
844
+ cities: City[] = [];
845
+ productCode: Code[] = [];
846
+ supplier: any[] = [];
847
+ selected: string[] = [];
848
+ items: string[] = [''];
849
+ form = {
850
+ nguoiLap: '',
851
+ nhom: '',
852
+ viTri: '',
853
+ nhaCungCap: '',
854
+ maHang: '',
855
+ ngayPhatSinh: null,
856
+ tenLoi: '',
857
+ boPhan: '',
858
+ moTa: ''
859
+ };
860
+
861
+ purchaseGroups = [
862
+ {
863
+ num: 1,
864
+ title: 'Yêu cầu mua hàng',
865
+ items: [
866
+ { id: 'y1', value: 'ban-ve', label: 'Bản vẽ/thông số không rõ ràng' },
867
+ { id: 'y2', value: 'tieu-chuan', label: 'Thiếu tiêu chuẩn kiểm tra' },
868
+ { id: 'y3', value: 'sai-ma', label: 'Sai mã / tên sản phẩm' }
869
+ ]
870
+ },
871
+ {
872
+ num: 2,
873
+ title: 'Lập PR / Duyệt PR',
874
+ items: [
875
+ { id: 'p1', value: 'pr-trung', label: 'PR tạo trùng' },
876
+ { id: 'p2', value: 'pr-thieu', label: 'Thiếu thông tin PR' },
877
+ { id: 'p3', value: 'pr-sai-gia', label: 'Sai đơn giá trên PR' }
878
+ ]
879
+ },
880
+ {
881
+ num: 3,
882
+ title: 'Tìm kiếm NCC',
883
+ items: [
884
+ { id: 'n1', value: 'ncc-nang-luc', label: 'NCC không đủ năng lực' },
885
+ { id: 'n2', value: 'ncc-audit', label: 'NCC chưa được audit' },
886
+ { id: 'n3', value: 'ncc-iso', label: 'NCC không có ISO/IATF' }
887
+ ]
888
+ },
889
+ {
890
+ num: 4,
891
+ title: 'So sánh giá',
892
+ items: [
893
+ { id: 'g1', value: 'bao-gia', label: 'Báo giá không rõ điều kiện' },
894
+ { id: 'g2', value: 'sai-gia', label: 'Sai giá khi lên PO' },
895
+ { id: 'g3', value: 'gia-cu', label: 'Không cập nhật giá mới' },
896
+ { id: 'g4', value: 'phi-phat-sinh', label: 'Giá chưa bao gồm chi phí PS' }
897
+ ]
898
+ },
899
+ {
900
+ num: 5,
901
+ title: 'Lập PO / Duyệt PO',
902
+ items: [
903
+ { id: 'po1', value: 'po-sai-don-gia', label: 'Sai đơn giá trên PO' },
904
+ { id: 'po2', value: 'po-thieu-tt', label: 'Thiếu thông tin PO' },
905
+ { id: 'po3', value: 'po-trung', label: 'PO tạo trùng' },
906
+ { id: 'po4', value: 'po-sai-ncc', label: 'Sai thông tin NCC' }
907
+ ]
908
+ },
909
+ {
910
+ num: 6,
911
+ title: 'Thực hiện mua hàng',
912
+ items: [
913
+ { id: 'th1', value: 'th-tre-han', label: 'Trễ hạn giao hàng' },
914
+ { id: 'th2', value: 'th-sai-sl', label: 'Sai số lượng đặt hàng' },
915
+ { id: 'th3', value: 'th-khong-xn', label: 'Không xác nhận đơn hàng' },
916
+ { id: 'th4', value: 'th-sai-dc', label: 'Sai địa chỉ giao hàng' }
917
+ ]
918
+ },
919
+ {
920
+ num: 7,
921
+ title: 'Nhận hàng',
922
+ items: [
923
+ { id: 'nh1', value: 'nh-thieu', label: 'Thiếu hàng so với PO' },
924
+ { id: 'nh2', value: 'nh-hong', label: 'Hàng hỏng khi nhận' },
925
+ { id: 'nh3', value: 'nh-sai-qc', label: 'Không kiểm tra QC đầu vào' },
926
+ { id: 'nh4', value: 'nh-sai-ma', label: 'Sai mã hàng nhận về' }
927
+ ]
928
+ },
929
+ {
930
+ num: 8,
931
+ title: 'Thanh toán',
932
+ items: [
933
+ { id: 'tt1', value: 'tt-sai-so', label: 'Sai số tiền thanh toán' },
934
+ { id: 'tt2', value: 'tt-tre', label: 'Thanh toán trễ hạn' },
935
+ { id: 'tt3', value: 'tt-thieu-hs', label: 'Thiếu hồ sơ thanh toán' },
936
+ { id: 'tt4', value: 'tt-sai-tk', label: 'Sai tài khoản thụ hưởng' }
937
+ ]
938
+ }
939
+ ];
940
+
941
+ reason = [
942
+ {
943
+ num: 1,
944
+ title: 'Con người (MAN)'
945
+ },
946
+ {
947
+ num: 2,
948
+ title: 'Lập PR / Duyệt PR'
949
+ },
950
+ {
951
+ num: 3,
952
+ title: 'Tìm kiếm NCC'
953
+ },
954
+ {
955
+ num: 4,
956
+ title: 'So sánh giá'
957
+ },
958
+ {
959
+ num: 5,
960
+ title: 'Lập PO / Duyệt PO'
961
+ },
962
+ {
963
+ num: 6,
964
+ title: 'Thực hiện mua hàng'
965
+ },
966
+ {
967
+ num: 7,
968
+ title: 'Nhận hàng'
969
+ },
970
+ {
971
+ num: 8,
972
+ title: 'Thanh toán'
973
+ }
974
+ ];
975
+
976
+ option = [
977
+ {
978
+ name: 'Hoàn thành',
979
+ value: 1
980
+ },
981
+ {
982
+ name: 'Chưa hoàn thành',
983
+ value: 2
984
+ }
985
+ ];
986
+
987
+ ngOnInit() {
988
+ this.cities = [
989
+ { name: 'Vật tư', code: 'VT' },
990
+ { name: 'Nguyên liệu', code: 'NL' },
991
+ { name: 'Dịch vụ', code: 'DV' },
992
+ { name: 'Thiết bị', code: 'TB' }
993
+ ];
994
+ this.productCode = [
995
+ { name: 'MH001', code: '1' },
996
+ { name: 'MH002', code: '2' },
997
+ { name: 'MH003', code: '3' }
998
+ ];
999
+ this.supplier = [
1000
+ { name: 'NCC An Vũ', code: 'AV' },
1001
+ { name: 'NCC Nông Lâm', code: 'NL' },
1002
+ { name: 'Yamaichi VN', code: 'YM' }
1003
+ ];
1004
+ }
1005
+
1006
+ submitForm() {
1007
+ console.log({ form: this.form, selected: this.selected });
1008
+ }
1009
+
1010
+ addItem() {
1011
+ this.items.push('');
1012
+ }
1013
+
1014
+ removeItem(index: number) {
1015
+ this.items.splice(index, 1);
1016
+ }
1017
+
1018
+ trackByIndex(index: number) {
1019
+ return index;
1020
+ }
1021
+ }