@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.
- package/.editorconfig +16 -0
- package/.gitmodules +3 -0
- package/.postcssrc.json +5 -0
- package/.prettierignore +14 -0
- package/.prettierrc.json +29 -0
- package/LICENSE.md +21 -0
- package/README.md +59 -0
- package/angular.json +98 -0
- package/eslint.config.js +89 -0
- package/package.json +59 -0
- package/public/demo/images/flag/flag_placeholder.png +0 -0
- package/public/demo/images/footer-image.gif +0 -0
- package/public/demo/images/galleria/galleria1.jpg +0 -0
- package/public/demo/images/galleria/galleria10.jpg +0 -0
- package/public/demo/images/galleria/galleria10s.jpg +0 -0
- package/public/demo/images/galleria/galleria11.jpg +0 -0
- package/public/demo/images/galleria/galleria11s.jpg +0 -0
- package/public/demo/images/galleria/galleria12.jpg +0 -0
- package/public/demo/images/galleria/galleria12s.jpg +0 -0
- package/public/demo/images/galleria/galleria13.jpg +0 -0
- package/public/demo/images/galleria/galleria13s.jpg +0 -0
- package/public/demo/images/galleria/galleria14.jpg +0 -0
- package/public/demo/images/galleria/galleria14s.jpg +0 -0
- package/public/demo/images/galleria/galleria15.jpg +0 -0
- package/public/demo/images/galleria/galleria15s.jpg +0 -0
- package/public/demo/images/galleria/galleria1s.jpg +0 -0
- package/public/demo/images/galleria/galleria2.jpg +0 -0
- package/public/demo/images/galleria/galleria2s.jpg +0 -0
- package/public/demo/images/galleria/galleria3.jpg +0 -0
- package/public/demo/images/galleria/galleria3s.jpg +0 -0
- package/public/demo/images/galleria/galleria4.jpg +0 -0
- package/public/demo/images/galleria/galleria4s.jpg +0 -0
- package/public/demo/images/galleria/galleria5.jpg +0 -0
- package/public/demo/images/galleria/galleria5s.jpg +0 -0
- package/public/demo/images/galleria/galleria6.jpg +0 -0
- package/public/demo/images/galleria/galleria6s.jpg +0 -0
- package/public/demo/images/galleria/galleria7.jpg +0 -0
- package/public/demo/images/galleria/galleria7s.jpg +0 -0
- package/public/demo/images/galleria/galleria8.jpg +0 -0
- package/public/demo/images/galleria/galleria8s.jpg +0 -0
- package/public/demo/images/galleria/galleria9.jpg +0 -0
- package/public/demo/images/galleria/galleria9s.jpg +0 -0
- package/public/demo/images/product/bamboo-watch.jpg +0 -0
- package/public/demo/images/product/black-watch.jpg +0 -0
- package/public/demo/images/product/blue-band.jpg +0 -0
- package/public/demo/images/product/blue-t-shirt.jpg +0 -0
- package/public/demo/images/product/bracelet.jpg +0 -0
- package/public/demo/images/product/brown-purse.jpg +0 -0
- package/public/demo/images/product/chakra-bracelet.jpg +0 -0
- package/public/demo/images/product/galaxy-earrings.jpg +0 -0
- package/public/demo/images/product/game-controller.jpg +0 -0
- package/public/demo/images/product/gaming-set.jpg +0 -0
- package/public/demo/images/product/gold-phone-case.jpg +0 -0
- package/public/demo/images/product/green-earbuds.jpg +0 -0
- package/public/demo/images/product/green-t-shirt.jpg +0 -0
- package/public/demo/images/product/grey-t-shirt.jpg +0 -0
- package/public/demo/images/product/headphones.jpg +0 -0
- package/public/demo/images/product/light-green-t-shirt.jpg +0 -0
- package/public/demo/images/product/lime-band.jpg +0 -0
- package/public/demo/images/product/mini-speakers.jpg +0 -0
- package/public/demo/images/product/painted-phone-case.jpg +0 -0
- package/public/demo/images/product/pink-band.jpg +0 -0
- package/public/demo/images/product/pink-purse.jpg +0 -0
- package/public/demo/images/product/product-placeholder.svg +10 -0
- package/public/demo/images/product/purple-band.jpg +0 -0
- package/public/demo/images/product/purple-gemstone-necklace.jpg +0 -0
- package/public/demo/images/product/purple-t-shirt.jpg +0 -0
- package/public/demo/images/product/shoes.jpg +0 -0
- package/public/demo/images/product/sneakers.jpg +0 -0
- package/public/demo/images/product/teal-t-shirt.jpg +0 -0
- package/public/demo/images/product/yellow-earbuds.jpg +0 -0
- package/public/demo/images/product/yoga-mat.jpg +0 -0
- package/public/demo/images/product/yoga-set.jpg +0 -0
- package/src/app/layout/component/configurator/app.configurator.html +48 -0
- package/src/app/layout/component/configurator/app.configurator.ts +396 -0
- package/src/app/layout/component/floatingconfigurator/app.floatingconfigurator.ts +31 -0
- package/src/app/layout/component/footer/app.footer.scss +52 -0
- package/src/app/layout/component/footer/app.footer.ts +26 -0
- package/src/app/layout/component/layout/app.layout.ts +50 -0
- package/src/app/layout/component/menu/app.menu.html +7 -0
- package/src/app/layout/component/menu/app.menu.scss +13 -0
- package/src/app/layout/component/menu/app.menu.ts +90 -0
- package/src/app/layout/component/menuitem/app.menuitem.html +56 -0
- package/src/app/layout/component/menuitem/app.menuitem.scss +218 -0
- package/src/app/layout/component/menuitem/app.menuitem.ts +126 -0
- package/src/app/layout/component/sidebar/app.sidebar.html +3 -0
- package/src/app/layout/component/sidebar/app.sidebar.scss +0 -0
- package/src/app/layout/component/sidebar/app.sidebar.ts +106 -0
- package/src/app/layout/component/topbar/app.topbar.html +190 -0
- package/src/app/layout/component/topbar/app.topbar.scss +8 -0
- package/src/app/layout/component/topbar/app.topbar.ts +68 -0
- package/src/app/layout/service/layout.service.ts +117 -0
- package/src/app/pages/auth/access.ts +32 -0
- package/src/app/pages/auth/auth.routes.ts +10 -0
- package/src/app/pages/auth/error.ts +32 -0
- package/src/app/pages/auth/login.ts +71 -0
- package/src/app/pages/crud/crud.ts +387 -0
- package/src/app/pages/dashboard/dashboard.css +778 -0
- package/src/app/pages/dashboard/dashboard.html +191 -0
- package/src/app/pages/dashboard/dashboard.ts +348 -0
- package/src/app/pages/documentation/documentation.ts +73 -0
- package/src/app/pages/empty/empty.ts +11 -0
- package/src/app/pages/landing/components/featureswidget.ts +139 -0
- package/src/app/pages/landing/components/footerwidget.ts +73 -0
- package/src/app/pages/landing/components/herowidget.ts +25 -0
- package/src/app/pages/landing/components/highlightswidget.ts +46 -0
- package/src/app/pages/landing/components/pricingwidget.ts +119 -0
- package/src/app/pages/landing/components/topbarwidget.component.ts +68 -0
- package/src/app/pages/landing/landing.ts +31 -0
- package/src/app/pages/notfound/notfound.ts +68 -0
- package/src/app/pages/pages.routes.ts +17 -0
- package/src/app/pages/profile/profile.html +57 -0
- package/src/app/pages/profile/profile.scss +145 -0
- package/src/app/pages/profile/profile.ts +19 -0
- package/src/app/pages/service/country.service.ts +255 -0
- package/src/app/pages/service/customer.service.ts +9057 -0
- package/src/app/pages/service/icon.service.ts +23 -0
- package/src/app/pages/service/node.service.ts +816 -0
- package/src/app/pages/service/photo.service.ts +103 -0
- package/src/app/pages/service/product.service.ts +1322 -0
- package/src/app/pages/tickets/tickets-create/tickets-create.html +140 -0
- package/src/app/pages/tickets/tickets-create/tickets-create.scss +617 -0
- package/src/app/pages/tickets/tickets-create/tickets-create.ts +104 -0
- package/src/app/pages/tickets/tickets-list/ticket-list.html +150 -0
- package/src/app/pages/tickets/tickets-list/ticket-list.scss +392 -0
- package/src/app/pages/tickets/tickets-list/ticket-list.ts +178 -0
- package/src/app/pages/uikit/buttondemo.ts +254 -0
- package/src/app/pages/uikit/chartdemo.ts +290 -0
- package/src/app/pages/uikit/filedemo.ts +52 -0
- package/src/app/pages/uikit/formlayoutdemo.ts +129 -0
- package/src/app/pages/uikit/inputdemo.ts +339 -0
- package/src/app/pages/uikit/listdemo.ts +217 -0
- package/src/app/pages/uikit/mediademo.ts +1021 -0
- package/src/app/pages/uikit/menudemo.ts +540 -0
- package/src/app/pages/uikit/messagesdemo.ts +101 -0
- package/src/app/pages/uikit/miscdemo.ts +192 -0
- package/src/app/pages/uikit/overlaydemo.ts +235 -0
- package/src/app/pages/uikit/panelsdemo.ts +235 -0
- package/src/app/pages/uikit/tabledemo.ts +568 -0
- package/src/app/pages/uikit/timelinedemo.ts +141 -0
- package/src/app/pages/uikit/treedemo.ts +75 -0
- package/src/app/pages/uikit/uikit.routes.ts +35 -0
- package/src/app.component.ts +22 -0
- package/src/app.config.ts +23 -0
- package/src/app.routes.ts +23 -0
- package/src/assets/demo/code.scss +17 -0
- package/src/assets/demo/demo.scss +2 -0
- package/src/assets/demo/flags/flags.css +984 -0
- package/src/assets/layout/_core.scss +24 -0
- package/src/assets/layout/_footer.scss +8 -0
- package/src/assets/layout/_main.scss +21 -0
- package/src/assets/layout/_menu.scss +159 -0
- package/src/assets/layout/_mixins.scss +15 -0
- package/src/assets/layout/_preloading.scss +47 -0
- package/src/assets/layout/_responsive.scss +111 -0
- package/src/assets/layout/_topbar.scss +201 -0
- package/src/assets/layout/_typography.scss +68 -0
- package/src/assets/layout/_utils.scss +25 -0
- package/src/assets/layout/layout.scss +13 -0
- package/src/assets/layout/variables/_common.scss +21 -0
- package/src/assets/layout/variables/_dark.scss +5 -0
- package/src/assets/layout/variables/_light.scss +5 -0
- package/src/assets/styles.scss +4 -0
- package/src/assets/tailwind.css +32 -0
- package/src/index.html +15 -0
- package/src/main.ts +5 -0
- package/tsconfig.app.json +15 -0
- package/tsconfig.json +33 -0
- package/tsconfig.spec.json +15 -0
- package/vercel.json +9 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
2
|
+
import { Component, computed, inject, PLATFORM_ID, signal } from '@angular/core';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { Router } from '@angular/router';
|
|
5
|
+
import { $t, updatePreset, updateSurfacePalette } from '@primeuix/themes';
|
|
6
|
+
import Aura from '@primeuix/themes/aura';
|
|
7
|
+
import Lara from '@primeuix/themes/lara';
|
|
8
|
+
import Nora from '@primeuix/themes/nora';
|
|
9
|
+
import { PrimeNG } from 'primeng/config';
|
|
10
|
+
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
11
|
+
import { LayoutService } from '@/app/layout/service/layout.service';
|
|
12
|
+
|
|
13
|
+
const presets = {
|
|
14
|
+
Aura,
|
|
15
|
+
Lara,
|
|
16
|
+
Nora
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
declare type KeyOfType<T> = keyof T extends infer U ? U : never;
|
|
20
|
+
|
|
21
|
+
declare type SurfacesType = {
|
|
22
|
+
name?: string;
|
|
23
|
+
palette?: {
|
|
24
|
+
0?: string;
|
|
25
|
+
50?: string;
|
|
26
|
+
100?: string;
|
|
27
|
+
200?: string;
|
|
28
|
+
300?: string;
|
|
29
|
+
400?: string;
|
|
30
|
+
500?: string;
|
|
31
|
+
600?: string;
|
|
32
|
+
700?: string;
|
|
33
|
+
800?: string;
|
|
34
|
+
900?: string;
|
|
35
|
+
950?: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
@Component({
|
|
40
|
+
selector: 'app-configurator',
|
|
41
|
+
standalone: true,
|
|
42
|
+
imports: [CommonModule, FormsModule, SelectButtonModule],
|
|
43
|
+
templateUrl: 'app.configurator.html',
|
|
44
|
+
host: {
|
|
45
|
+
class: 'hidden absolute top-13 right-0 w-72 p-4 bg-surface-0 dark:bg-surface-900 border border-surface rounded-border origin-top shadow-[0px_3px_5px_rgba(0,0,0,0.02),0px_0px_2px_rgba(0,0,0,0.05),0px_1px_4px_rgba(0,0,0,0.08)]'
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
export class AppConfigurator {
|
|
49
|
+
router = inject(Router);
|
|
50
|
+
|
|
51
|
+
config: PrimeNG = inject(PrimeNG);
|
|
52
|
+
|
|
53
|
+
layoutService: LayoutService = inject(LayoutService);
|
|
54
|
+
|
|
55
|
+
platformId = inject(PLATFORM_ID);
|
|
56
|
+
|
|
57
|
+
primeng = inject(PrimeNG);
|
|
58
|
+
|
|
59
|
+
presets = Object.keys(presets);
|
|
60
|
+
|
|
61
|
+
showMenuModeButton = signal(!this.router.url.includes('auth'));
|
|
62
|
+
|
|
63
|
+
menuModeOptions = [
|
|
64
|
+
{ label: 'Static', value: 'static' },
|
|
65
|
+
{ label: 'Overlay', value: 'overlay' }
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
ngOnInit() {
|
|
69
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
70
|
+
this.onPresetChange(this.layoutService.layoutConfig().preset);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
surfaces: SurfacesType[] = [
|
|
75
|
+
{
|
|
76
|
+
name: 'slate',
|
|
77
|
+
palette: {
|
|
78
|
+
0: '#ffffff',
|
|
79
|
+
50: '#f8fafc',
|
|
80
|
+
100: '#f1f5f9',
|
|
81
|
+
200: '#e2e8f0',
|
|
82
|
+
300: '#cbd5e1',
|
|
83
|
+
400: '#94a3b8',
|
|
84
|
+
500: '#64748b',
|
|
85
|
+
600: '#475569',
|
|
86
|
+
700: '#334155',
|
|
87
|
+
800: '#1e293b',
|
|
88
|
+
900: '#0f172a',
|
|
89
|
+
950: '#020617'
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'gray',
|
|
94
|
+
palette: {
|
|
95
|
+
0: '#ffffff',
|
|
96
|
+
50: '#f9fafb',
|
|
97
|
+
100: '#f3f4f6',
|
|
98
|
+
200: '#e5e7eb',
|
|
99
|
+
300: '#d1d5db',
|
|
100
|
+
400: '#9ca3af',
|
|
101
|
+
500: '#6b7280',
|
|
102
|
+
600: '#4b5563',
|
|
103
|
+
700: '#374151',
|
|
104
|
+
800: '#1f2937',
|
|
105
|
+
900: '#111827',
|
|
106
|
+
950: '#030712'
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'zinc',
|
|
111
|
+
palette: {
|
|
112
|
+
0: '#ffffff',
|
|
113
|
+
50: '#fafafa',
|
|
114
|
+
100: '#f4f4f5',
|
|
115
|
+
200: '#e4e4e7',
|
|
116
|
+
300: '#d4d4d8',
|
|
117
|
+
400: '#a1a1aa',
|
|
118
|
+
500: '#71717a',
|
|
119
|
+
600: '#52525b',
|
|
120
|
+
700: '#3f3f46',
|
|
121
|
+
800: '#27272a',
|
|
122
|
+
900: '#18181b',
|
|
123
|
+
950: '#09090b'
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'neutral',
|
|
128
|
+
palette: {
|
|
129
|
+
0: '#ffffff',
|
|
130
|
+
50: '#fafafa',
|
|
131
|
+
100: '#f5f5f5',
|
|
132
|
+
200: '#e5e5e5',
|
|
133
|
+
300: '#d4d4d4',
|
|
134
|
+
400: '#a3a3a3',
|
|
135
|
+
500: '#737373',
|
|
136
|
+
600: '#525252',
|
|
137
|
+
700: '#404040',
|
|
138
|
+
800: '#262626',
|
|
139
|
+
900: '#171717',
|
|
140
|
+
950: '#0a0a0a'
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'stone',
|
|
145
|
+
palette: {
|
|
146
|
+
0: '#ffffff',
|
|
147
|
+
50: '#fafaf9',
|
|
148
|
+
100: '#f5f5f4',
|
|
149
|
+
200: '#e7e5e4',
|
|
150
|
+
300: '#d6d3d1',
|
|
151
|
+
400: '#a8a29e',
|
|
152
|
+
500: '#78716c',
|
|
153
|
+
600: '#57534e',
|
|
154
|
+
700: '#44403c',
|
|
155
|
+
800: '#292524',
|
|
156
|
+
900: '#1c1917',
|
|
157
|
+
950: '#0c0a09'
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'soho',
|
|
162
|
+
palette: {
|
|
163
|
+
0: '#ffffff',
|
|
164
|
+
50: '#ececec',
|
|
165
|
+
100: '#dedfdf',
|
|
166
|
+
200: '#c4c4c6',
|
|
167
|
+
300: '#adaeb0',
|
|
168
|
+
400: '#97979b',
|
|
169
|
+
500: '#7f8084',
|
|
170
|
+
600: '#6a6b70',
|
|
171
|
+
700: '#55565b',
|
|
172
|
+
800: '#3f4046',
|
|
173
|
+
900: '#2c2c34',
|
|
174
|
+
950: '#16161d'
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'viva',
|
|
179
|
+
palette: {
|
|
180
|
+
0: '#ffffff',
|
|
181
|
+
50: '#f3f3f3',
|
|
182
|
+
100: '#e7e7e8',
|
|
183
|
+
200: '#cfd0d0',
|
|
184
|
+
300: '#b7b8b9',
|
|
185
|
+
400: '#9fa1a1',
|
|
186
|
+
500: '#87898a',
|
|
187
|
+
600: '#6e7173',
|
|
188
|
+
700: '#565a5b',
|
|
189
|
+
800: '#3e4244',
|
|
190
|
+
900: '#262b2c',
|
|
191
|
+
950: '#0e1315'
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'ocean',
|
|
196
|
+
palette: {
|
|
197
|
+
0: '#ffffff',
|
|
198
|
+
50: '#fbfcfc',
|
|
199
|
+
100: '#F7F9F8',
|
|
200
|
+
200: '#EFF3F2',
|
|
201
|
+
300: '#DADEDD',
|
|
202
|
+
400: '#B1B7B6',
|
|
203
|
+
500: '#828787',
|
|
204
|
+
600: '#5F7274',
|
|
205
|
+
700: '#415B61',
|
|
206
|
+
800: '#29444E',
|
|
207
|
+
900: '#183240',
|
|
208
|
+
950: '#0c1920'
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
selectedPrimaryColor = computed(() => {
|
|
214
|
+
return this.layoutService.layoutConfig().primary;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
selectedSurfaceColor = computed(() => this.layoutService.layoutConfig().surface);
|
|
218
|
+
|
|
219
|
+
selectedPreset = computed(() => this.layoutService.layoutConfig().preset);
|
|
220
|
+
|
|
221
|
+
menuMode = computed(() => this.layoutService.layoutConfig().menuMode);
|
|
222
|
+
|
|
223
|
+
primaryColors = computed<SurfacesType[]>(() => {
|
|
224
|
+
const presetPalette = presets[this.layoutService.layoutConfig().preset as KeyOfType<typeof presets>].primitive;
|
|
225
|
+
const colors = ['emerald', 'green', 'lime', 'orange', 'amber', 'yellow', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose'];
|
|
226
|
+
const palettes: SurfacesType[] = [{ name: 'noir', palette: {} }];
|
|
227
|
+
|
|
228
|
+
colors.forEach((color) => {
|
|
229
|
+
palettes.push({
|
|
230
|
+
name: color,
|
|
231
|
+
palette: presetPalette?.[color as KeyOfType<typeof presetPalette>] as SurfacesType['palette']
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return palettes;
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
getPresetExt() {
|
|
239
|
+
const color: SurfacesType = this.primaryColors().find((c) => c.name === this.selectedPrimaryColor()) || {};
|
|
240
|
+
const preset = this.layoutService.layoutConfig().preset;
|
|
241
|
+
|
|
242
|
+
if (color.name === 'noir') {
|
|
243
|
+
return {
|
|
244
|
+
semantic: {
|
|
245
|
+
primary: {
|
|
246
|
+
50: '{surface.50}',
|
|
247
|
+
100: '{surface.100}',
|
|
248
|
+
200: '{surface.200}',
|
|
249
|
+
300: '{surface.300}',
|
|
250
|
+
400: '{surface.400}',
|
|
251
|
+
500: '{surface.500}',
|
|
252
|
+
600: '{surface.600}',
|
|
253
|
+
700: '{surface.700}',
|
|
254
|
+
800: '{surface.800}',
|
|
255
|
+
900: '{surface.900}',
|
|
256
|
+
950: '{surface.950}'
|
|
257
|
+
},
|
|
258
|
+
colorScheme: {
|
|
259
|
+
light: {
|
|
260
|
+
primary: {
|
|
261
|
+
color: '{primary.950}',
|
|
262
|
+
contrastColor: '#ffffff',
|
|
263
|
+
hoverColor: '{primary.800}',
|
|
264
|
+
activeColor: '{primary.700}'
|
|
265
|
+
},
|
|
266
|
+
highlight: {
|
|
267
|
+
background: '{primary.950}',
|
|
268
|
+
focusBackground: '{primary.700}',
|
|
269
|
+
color: '#ffffff',
|
|
270
|
+
focusColor: '#ffffff'
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
dark: {
|
|
274
|
+
primary: {
|
|
275
|
+
color: '{primary.50}',
|
|
276
|
+
contrastColor: '{primary.950}',
|
|
277
|
+
hoverColor: '{primary.200}',
|
|
278
|
+
activeColor: '{primary.300}'
|
|
279
|
+
},
|
|
280
|
+
highlight: {
|
|
281
|
+
background: '{primary.50}',
|
|
282
|
+
focusBackground: '{primary.300}',
|
|
283
|
+
color: '{primary.950}',
|
|
284
|
+
focusColor: '{primary.950}'
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
} else {
|
|
291
|
+
if (preset === 'Nora') {
|
|
292
|
+
return {
|
|
293
|
+
semantic: {
|
|
294
|
+
primary: color.palette,
|
|
295
|
+
colorScheme: {
|
|
296
|
+
light: {
|
|
297
|
+
primary: {
|
|
298
|
+
color: '{primary.600}',
|
|
299
|
+
contrastColor: '#ffffff',
|
|
300
|
+
hoverColor: '{primary.700}',
|
|
301
|
+
activeColor: '{primary.800}'
|
|
302
|
+
},
|
|
303
|
+
highlight: {
|
|
304
|
+
background: '{primary.600}',
|
|
305
|
+
focusBackground: '{primary.700}',
|
|
306
|
+
color: '#ffffff',
|
|
307
|
+
focusColor: '#ffffff'
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
dark: {
|
|
311
|
+
primary: {
|
|
312
|
+
color: '{primary.500}',
|
|
313
|
+
contrastColor: '{surface.900}',
|
|
314
|
+
hoverColor: '{primary.400}',
|
|
315
|
+
activeColor: '{primary.300}'
|
|
316
|
+
},
|
|
317
|
+
highlight: {
|
|
318
|
+
background: '{primary.500}',
|
|
319
|
+
focusBackground: '{primary.400}',
|
|
320
|
+
color: '{surface.900}',
|
|
321
|
+
focusColor: '{surface.900}'
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
} else {
|
|
328
|
+
return {
|
|
329
|
+
semantic: {
|
|
330
|
+
primary: color.palette,
|
|
331
|
+
colorScheme: {
|
|
332
|
+
light: {
|
|
333
|
+
primary: {
|
|
334
|
+
color: '{primary.500}',
|
|
335
|
+
contrastColor: '#ffffff',
|
|
336
|
+
hoverColor: '{primary.600}',
|
|
337
|
+
activeColor: '{primary.700}'
|
|
338
|
+
},
|
|
339
|
+
highlight: {
|
|
340
|
+
background: '{primary.50}',
|
|
341
|
+
focusBackground: '{primary.100}',
|
|
342
|
+
color: '{primary.700}',
|
|
343
|
+
focusColor: '{primary.800}'
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
dark: {
|
|
347
|
+
primary: {
|
|
348
|
+
color: '{primary.400}',
|
|
349
|
+
contrastColor: '{surface.900}',
|
|
350
|
+
hoverColor: '{primary.300}',
|
|
351
|
+
activeColor: '{primary.200}'
|
|
352
|
+
},
|
|
353
|
+
highlight: {
|
|
354
|
+
background: 'color-mix(in srgb, {primary.400}, transparent 84%)',
|
|
355
|
+
focusBackground: 'color-mix(in srgb, {primary.400}, transparent 76%)',
|
|
356
|
+
color: 'rgba(255,255,255,.87)',
|
|
357
|
+
focusColor: 'rgba(255,255,255,.87)'
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
updateColors(event: any, type: string, color: any) {
|
|
368
|
+
if (type === 'primary') {
|
|
369
|
+
this.layoutService.layoutConfig.update((state) => ({ ...state, primary: color.name }));
|
|
370
|
+
} else if (type === 'surface') {
|
|
371
|
+
this.layoutService.layoutConfig.update((state) => ({ ...state, surface: color.name }));
|
|
372
|
+
}
|
|
373
|
+
this.applyTheme(type, color);
|
|
374
|
+
|
|
375
|
+
event.stopPropagation();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
applyTheme(type: string, color: any) {
|
|
379
|
+
if (type === 'primary') {
|
|
380
|
+
updatePreset(this.getPresetExt());
|
|
381
|
+
} else if (type === 'surface') {
|
|
382
|
+
updateSurfacePalette(color.palette);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
onPresetChange(event: any) {
|
|
387
|
+
this.layoutService.layoutConfig.update((state) => ({ ...state, preset: event }));
|
|
388
|
+
const preset = presets[event as KeyOfType<typeof presets>];
|
|
389
|
+
const surfacePalette = this.surfaces.find((s) => s.name === this.selectedSurfaceColor())?.palette;
|
|
390
|
+
$t().preset(preset).preset(this.getPresetExt()).surfacePalette(surfacePalette).use({ useDefaultOptions: true });
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
onMenuModeChange(event: string) {
|
|
394
|
+
this.layoutService.layoutConfig.update((prev) => ({ ...prev, menuMode: event }));
|
|
395
|
+
}
|
|
396
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Component, computed, inject, input } from '@angular/core';
|
|
2
|
+
import { ButtonModule } from 'primeng/button';
|
|
3
|
+
import { StyleClassModule } from 'primeng/styleclass';
|
|
4
|
+
import { AppConfigurator } from './../configurator/app.configurator';
|
|
5
|
+
import { LayoutService } from '@/app/layout/service/layout.service';
|
|
6
|
+
import { CommonModule } from '@angular/common';
|
|
7
|
+
|
|
8
|
+
@Component({
|
|
9
|
+
selector: 'app-floating-configurator',
|
|
10
|
+
imports: [CommonModule, ButtonModule, StyleClassModule, AppConfigurator],
|
|
11
|
+
template: `
|
|
12
|
+
<div class="flex gap-4 top-8 right-8" [ngClass]="{ fixed: float() }">
|
|
13
|
+
<p-button type="button" (onClick)="toggleDarkMode()" [rounded]="true" [icon]="isDarkTheme() ? 'pi pi-moon' : 'pi pi-sun'" severity="secondary" />
|
|
14
|
+
<div class="relative">
|
|
15
|
+
<p-button icon="pi pi-palette" pStyleClass="@next" enterFromClass="hidden" enterActiveClass="animate-scalein" leaveToClass="hidden" leaveActiveClass="animate-fadeout" [hideOnOutsideClick]="true" type="button" rounded />
|
|
16
|
+
<app-configurator />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
`
|
|
20
|
+
})
|
|
21
|
+
export class AppFloatingConfigurator {
|
|
22
|
+
LayoutService = inject(LayoutService);
|
|
23
|
+
|
|
24
|
+
float = input<boolean>(true);
|
|
25
|
+
|
|
26
|
+
isDarkTheme = computed(() => this.LayoutService.layoutConfig().darkTheme);
|
|
27
|
+
|
|
28
|
+
toggleDarkMode() {
|
|
29
|
+
this.LayoutService.layoutConfig.update((state) => ({ ...state, darkTheme: !state.darkTheme }));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.footer {
|
|
2
|
+
background: #404040;
|
|
3
|
+
padding: 0 0 5px;
|
|
4
|
+
color: #fff;
|
|
5
|
+
font-size: 14px;
|
|
6
|
+
background-image: url('./../../../../../public/demo//images/footer-image.gif');
|
|
7
|
+
height: 60px;
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
width: 100%;
|
|
12
|
+
margin: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.overlay {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.content {
|
|
22
|
+
text-align: center;
|
|
23
|
+
color: #fff;
|
|
24
|
+
display: flex;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
gap: 10px;
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.copyright {
|
|
33
|
+
font-size: 13px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.credits {
|
|
37
|
+
font-size: 12px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.text-colorful {
|
|
41
|
+
background-image: linear-gradient(to left, #dedede, #00ff04, #71b5f3, #ffa7e5, #ff0, #ffc253, #ff3939);
|
|
42
|
+
-webkit-background-clip: text;
|
|
43
|
+
-moz-background-clip: text;
|
|
44
|
+
background-clip: text;
|
|
45
|
+
color: transparent;
|
|
46
|
+
font-weight: 800;
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
border: 2px solid rgb(255, 137, 196);
|
|
50
|
+
border-radius: 20px;
|
|
51
|
+
padding: 3px 6px;
|
|
52
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
standalone: true,
|
|
5
|
+
selector: 'app-footer',
|
|
6
|
+
styleUrl: './app.footer.scss',
|
|
7
|
+
template: `
|
|
8
|
+
<footer class="footer">
|
|
9
|
+
<div class="overlay">
|
|
10
|
+
<div class="content">
|
|
11
|
+
<div class="copyright">
|
|
12
|
+
Copyright © 2026
|
|
13
|
+
<strong><span>Maruei Vietnam Precision Co., Ltd</span></strong
|
|
14
|
+
>.
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="credits">
|
|
18
|
+
Designed by
|
|
19
|
+
<span class="text-colorful">IFS Team</span>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</footer>
|
|
24
|
+
`
|
|
25
|
+
})
|
|
26
|
+
export class AppFooter {}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Component, computed, effect, inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { RouterModule } from '@angular/router';
|
|
4
|
+
import { AppTopbar } from '../topbar/app.topbar';
|
|
5
|
+
import { AppSidebar } from '../sidebar/app.sidebar';
|
|
6
|
+
import { AppFooter } from '../footer/app.footer';
|
|
7
|
+
import { LayoutService } from '@/app/layout/service/layout.service';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'app-layout',
|
|
11
|
+
standalone: true,
|
|
12
|
+
imports: [CommonModule, AppTopbar, AppSidebar, RouterModule, AppFooter],
|
|
13
|
+
template: `<div class="layout-wrapper" [ngClass]="containerClass()">
|
|
14
|
+
<app-topbar></app-topbar>
|
|
15
|
+
<app-sidebar></app-sidebar>
|
|
16
|
+
<div class="layout-main-container">
|
|
17
|
+
<div class="layout-main">
|
|
18
|
+
<router-outlet></router-outlet>
|
|
19
|
+
</div>
|
|
20
|
+
<app-footer></app-footer>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="layout-mask"></div>
|
|
23
|
+
</div> `
|
|
24
|
+
})
|
|
25
|
+
export class AppLayout {
|
|
26
|
+
layoutService = inject(LayoutService);
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
effect(() => {
|
|
30
|
+
const state = this.layoutService.layoutState();
|
|
31
|
+
if (state.mobileMenuActive) {
|
|
32
|
+
document.body.classList.add('blocked-scroll');
|
|
33
|
+
} else {
|
|
34
|
+
document.body.classList.remove('blocked-scroll');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
containerClass = computed(() => {
|
|
40
|
+
const config = this.layoutService.layoutConfig();
|
|
41
|
+
const state = this.layoutService.layoutState();
|
|
42
|
+
return {
|
|
43
|
+
'layout-overlay': config.menuMode === 'overlay',
|
|
44
|
+
'layout-static': config.menuMode === 'static',
|
|
45
|
+
'layout-static-inactive': state.staticMenuDesktopInactive && config.menuMode === 'static',
|
|
46
|
+
'layout-overlay-active': state.overlayMenuActive,
|
|
47
|
+
'layout-mobile-active': state.mobileMenuActive
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// ===== MENU WRAPPER =====
|
|
2
|
+
.layout-menu {
|
|
3
|
+
list-style: none;
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0.5rem 0;
|
|
6
|
+
|
|
7
|
+
.menu-separator {
|
|
8
|
+
height: 1px;
|
|
9
|
+
background: linear-gradient(90deg, transparent, var(--surface-border), transparent);
|
|
10
|
+
margin: 0.5rem 1rem;
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { RouterModule } from '@angular/router';
|
|
4
|
+
import { MenuItem } from 'primeng/api';
|
|
5
|
+
import { AppMenuitem } from './../menuitem/app.menuitem';
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'app-menu',
|
|
9
|
+
standalone: true,
|
|
10
|
+
imports: [CommonModule, AppMenuitem, RouterModule],
|
|
11
|
+
templateUrl: './app.menu.html'
|
|
12
|
+
})
|
|
13
|
+
export class AppMenu {
|
|
14
|
+
model: MenuItem[] = [];
|
|
15
|
+
|
|
16
|
+
ngOnInit() {
|
|
17
|
+
this.model = [
|
|
18
|
+
{
|
|
19
|
+
label: 'MENU CHÍNH',
|
|
20
|
+
items: [{ label: 'Dashboard', icon: 'pi pi-fw pi-home', routerLink: ['/'] }]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: 'MIAT KAKOTORA',
|
|
24
|
+
items: [
|
|
25
|
+
{ label: 'Danh sách', icon: 'pi pi-fw pi-briefcase', class: 'rotated-icon', routerLink: ['/projects/ticket-list'] },
|
|
26
|
+
{ label: 'Tạo phiếu', icon: 'pi pi-fw pi-briefcase', class: 'rotated-icon', routerLink: ['/projects/ticket-create'] }
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Tạo TICKET',
|
|
31
|
+
items: [
|
|
32
|
+
{ label: 'Tạo Phiếu', icon: 'pi pi-fw pi-image', routerLink: ['projects/phieu-yeu-cau/tao-phieu-yeu-cau'] },
|
|
33
|
+
{ label: 'Danh Sách Phiếu', icon: 'pi pi-fw pi-bars', routerLink: ['/uikit/menu'] },
|
|
34
|
+
{ label: 'Message', icon: 'pi pi-fw pi-comment', routerLink: ['/uikit/message'] }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
label: 'Hệ THỐNG',
|
|
39
|
+
path: '/hierarchy',
|
|
40
|
+
items: [
|
|
41
|
+
{
|
|
42
|
+
label: 'Submenu 1',
|
|
43
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
44
|
+
path: '/hierarchy/submenu_1',
|
|
45
|
+
items: [
|
|
46
|
+
{
|
|
47
|
+
label: 'Submenu 1.1',
|
|
48
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
49
|
+
path: '/hierarchy/submenu_1/submenu_1_1',
|
|
50
|
+
items: [
|
|
51
|
+
{ label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-bookmark' },
|
|
52
|
+
{ label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-bookmark' },
|
|
53
|
+
{ label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-bookmark' }
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
label: 'Submenu 1.2',
|
|
58
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
59
|
+
path: '/hierarchy/submenu_1/submenu_1_2',
|
|
60
|
+
items: [{ label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-bookmark' }]
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
label: 'Submenu 2',
|
|
66
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
67
|
+
path: '/hierarchy/submenu_2',
|
|
68
|
+
items: [
|
|
69
|
+
{
|
|
70
|
+
label: 'Submenu 2.1',
|
|
71
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
72
|
+
path: '/hierarchy/submenu_2/submenu_2_1',
|
|
73
|
+
items: [
|
|
74
|
+
{ label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-bookmark' },
|
|
75
|
+
{ label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-bookmark' }
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
label: 'Submenu 2.2',
|
|
80
|
+
icon: 'pi pi-fw pi-bookmark',
|
|
81
|
+
path: '/hierarchy/submenu_2/submenu_2_2',
|
|
82
|
+
items: [{ label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-bookmark' }]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
}
|