adminator-admin-dashboard 2.7.1 → 2.8.1

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.
@@ -1,542 +0,0 @@
1
- /**
2
- * Vector Maps Implementation with TypeScript
3
- * Interactive world map using JSVectorMap with theme support
4
- */
5
-
6
- import jsVectorMap from 'jsvectormap';
7
- import 'jsvectormap/dist/jsvectormap.css';
8
- import 'jsvectormap/dist/maps/world.js';
9
- import { debounce } from 'lodash';
10
- import { ThemeManager } from '../utils/theme';
11
- import type { ComponentInterface } from '../../types';
12
-
13
- // Type definitions for Vector Maps
14
- export interface VectorMapMarker {
15
- name: string;
16
- coords: [number, number];
17
- data?: any;
18
- }
19
-
20
- export interface VectorMapColors {
21
- backgroundColor: string;
22
- regionColor: string;
23
- borderColor: string;
24
- hoverColor: string;
25
- selectedColor: string;
26
- markerFill: string;
27
- markerStroke: string;
28
- scaleStart: string;
29
- scaleEnd: string;
30
- textColor: string;
31
- }
32
-
33
- export interface VectorMapOptions {
34
- selector: string;
35
- map: string;
36
- backgroundColor?: string;
37
- regionStyle?: {
38
- initial?: Record<string, any>;
39
- hover?: Record<string, any>;
40
- selected?: Record<string, any>;
41
- };
42
- markerStyle?: {
43
- initial?: Record<string, any>;
44
- hover?: Record<string, any>;
45
- };
46
- markers?: VectorMapMarker[];
47
- series?: {
48
- regions?: Array<{
49
- attribute: string;
50
- scale: [string, string];
51
- normalizeFunction?: string;
52
- values: Record<string, number>;
53
- }>;
54
- };
55
- zoomOnScroll?: boolean;
56
- zoomButtons?: boolean;
57
- onMarkerTooltipShow?: (event: Event, tooltip: any, index: number) => void;
58
- onRegionTooltipShow?: (event: Event, tooltip: any, code: string) => void;
59
- onLoaded?: (map: any) => void;
60
- }
61
-
62
- export interface VectorMapInstance {
63
- destroy(): void;
64
- updateSeries(type: string, config: any): void;
65
- markers?: VectorMapMarker[];
66
- mapData?: any;
67
- series?: any;
68
- }
69
-
70
- declare global {
71
- interface HTMLElement {
72
- mapInstance?: VectorMapInstance;
73
- }
74
- }
75
-
76
- // Enhanced Vector Map implementation
77
- export class VectorMapComponent implements ComponentInterface {
78
- public name: string = 'VectorMapComponent';
79
- public element: HTMLElement;
80
- public options: VectorMapOptions;
81
- public isInitialized: boolean = false;
82
-
83
- private mapInstance: VectorMapInstance | null = null;
84
- private container: HTMLElement | null = null;
85
- private resizeObserver: ResizeObserver | null = null;
86
- private themeChangeHandler: (() => void) | null = null;
87
- private resizeHandler: (() => void) | null = null;
88
- private themeManager: typeof ThemeManager;
89
-
90
- constructor(element: HTMLElement, options: Partial<VectorMapOptions> = {}) {
91
- this.element = element;
92
- this.options = {
93
- selector: '#vmap',
94
- map: 'world',
95
- backgroundColor: 'transparent',
96
- zoomOnScroll: false,
97
- zoomButtons: false,
98
- markers: [
99
- {
100
- name: 'INDIA : 350',
101
- coords: [21.00, 78.00],
102
- },
103
- {
104
- name: 'Australia : 250',
105
- coords: [-33.00, 151.00],
106
- },
107
- {
108
- name: 'USA : 250',
109
- coords: [36.77, -119.41],
110
- },
111
- {
112
- name: 'UK : 250',
113
- coords: [55.37, -3.41],
114
- },
115
- {
116
- name: 'UAE : 250',
117
- coords: [25.20, 55.27],
118
- },
119
- ],
120
- ...options,
121
- };
122
-
123
- this.themeManager = ThemeManager;
124
- this.init();
125
- }
126
-
127
- public init(): void {
128
- this.setupContainer();
129
- this.setupEventHandlers();
130
- this.createMap();
131
- this.isInitialized = true;
132
- }
133
-
134
- public destroy(): void {
135
- this.cleanup();
136
- this.isInitialized = false;
137
- }
138
-
139
- private setupContainer(): void {
140
- // Remove existing map
141
- const existingMap = document.getElementById('vmap');
142
- if (existingMap) {
143
- existingMap.remove();
144
- }
145
-
146
- // Create new map container
147
- this.container = document.createElement('div');
148
- this.container.id = 'vmap';
149
- this.container.style.height = '490px';
150
- this.container.style.position = 'relative';
151
- this.container.style.overflow = 'hidden';
152
- this.container.style.borderRadius = '8px';
153
- this.container.style.border = '1px solid var(--c-border, #d3d9e3)';
154
- this.container.style.backgroundColor = 'var(--c-bkg-card, #f9fafb)';
155
-
156
- this.element.appendChild(this.container);
157
- }
158
-
159
- private setupEventHandlers(): void {
160
- // Theme change handler
161
- this.themeChangeHandler = debounce(this.updateMapTheme.bind(this), 150);
162
- window.addEventListener('adminator:themeChanged', this.themeChangeHandler);
163
-
164
- // Resize handler
165
- this.resizeHandler = debounce(this.handleResize.bind(this), 300);
166
- window.addEventListener('resize', this.resizeHandler);
167
-
168
- // Setup ResizeObserver if available
169
- if ('ResizeObserver' in window) {
170
- this.resizeObserver = new ResizeObserver(
171
- debounce(() => {
172
- if (this.mapInstance) {
173
- this.handleResize();
174
- }
175
- }, 300)
176
- );
177
- this.resizeObserver.observe(this.element);
178
- }
179
- }
180
-
181
- private createMap(): void {
182
- if (!this.container) return;
183
-
184
- // Destroy existing map instance
185
- this.destroyMapInstance();
186
-
187
- const colors = this.getThemeColors();
188
- const mapConfig = this.buildMapConfig(colors);
189
-
190
- try {
191
- this.mapInstance = jsVectorMap(mapConfig);
192
- this.element.mapInstance = this.mapInstance;
193
- } catch (error) {
194
- console.error('VectorMap: Failed to initialize map', error);
195
- this.showFallbackContent(colors);
196
- }
197
- }
198
-
199
- private getThemeColors(): VectorMapColors {
200
- const isDark = this.themeManager.current() === 'dark';
201
-
202
- return {
203
- backgroundColor: isDark ? '#313644' : '#f9fafb',
204
- regionColor: isDark ? '#565a5c' : '#e6eaf0',
205
- borderColor: isDark ? '#72777a' : '#d3d9e3',
206
- hoverColor: isDark ? '#7774e7' : '#0f9aee',
207
- selectedColor: isDark ? '#37c936' : '#7774e7',
208
- markerFill: isDark ? '#0f9aee' : '#7774e7',
209
- markerStroke: isDark ? '#37c936' : '#0f9aee',
210
- scaleStart: isDark ? '#b9c2d0' : '#e6eaf0',
211
- scaleEnd: isDark ? '#0f9aee' : '#007bff',
212
- textColor: isDark ? '#99abb4' : '#72777a',
213
- };
214
- }
215
-
216
- private buildMapConfig(colors: VectorMapColors): VectorMapOptions {
217
- return {
218
- selector: '#vmap',
219
- map: 'world',
220
- backgroundColor: this.options.backgroundColor || 'transparent',
221
-
222
- // Region styling
223
- regionStyle: {
224
- initial: {
225
- fill: colors.regionColor,
226
- stroke: colors.borderColor,
227
- 'stroke-width': 1,
228
- 'stroke-opacity': 0.4,
229
- },
230
- hover: {
231
- fill: colors.hoverColor,
232
- cursor: 'pointer',
233
- },
234
- selected: {
235
- fill: colors.selectedColor,
236
- },
237
- ...this.options.regionStyle,
238
- },
239
-
240
- // Marker styling
241
- markerStyle: {
242
- initial: {
243
- r: 7,
244
- fill: colors.markerFill,
245
- stroke: colors.markerStroke,
246
- 'stroke-width': 2,
247
- 'stroke-opacity': 0.4,
248
- },
249
- hover: {
250
- r: 10,
251
- fill: colors.hoverColor,
252
- 'stroke-opacity': 0.8,
253
- cursor: 'pointer',
254
- },
255
- ...this.options.markerStyle,
256
- },
257
-
258
- // Markers data
259
- markers: this.options.markers || [],
260
-
261
- // Series configuration
262
- series: this.options.series,
263
-
264
- // Interaction options
265
- zoomOnScroll: this.options.zoomOnScroll || false,
266
- zoomButtons: this.options.zoomButtons || false,
267
-
268
- // Event handlers
269
- onMarkerTooltipShow: this.handleMarkerTooltip.bind(this),
270
- onRegionTooltipShow: this.handleRegionTooltip.bind(this),
271
- onLoaded: this.handleMapLoaded.bind(this),
272
- };
273
- }
274
-
275
- private handleMarkerTooltip(event: Event, tooltip: any, index: number): void {
276
- try {
277
- const marker = this.mapInstance?.markers?.[index];
278
- const markerName = marker?.name || `Marker ${index + 1}`;
279
- tooltip.text(markerName);
280
- } catch (error) {
281
- console.warn('VectorMap: Error in marker tooltip', error);
282
- }
283
-
284
- // Call custom handler if provided
285
- if (this.options.onMarkerTooltipShow) {
286
- this.options.onMarkerTooltipShow(event, tooltip, index);
287
- }
288
- }
289
-
290
- private handleRegionTooltip(event: Event, tooltip: any, code: string): void {
291
- try {
292
- const mapData = this.mapInstance?.mapData;
293
- const regionName = mapData?.paths?.[code]?.name || code;
294
- const series = this.mapInstance?.series?.regions?.[0];
295
- const value = series?.values?.[code];
296
-
297
- const text = value ? `${regionName}: ${value}` : regionName;
298
- tooltip.text(text);
299
- } catch (error) {
300
- console.warn('VectorMap: Error in region tooltip', error);
301
- tooltip.text(code);
302
- }
303
-
304
- // Call custom handler if provided
305
- if (this.options.onRegionTooltipShow) {
306
- this.options.onRegionTooltipShow(event, tooltip, code);
307
- }
308
- }
309
-
310
- private handleMapLoaded(map: any): void {
311
- console.log('VectorMap: Map loaded successfully');
312
-
313
- // Call custom handler if provided
314
- if (this.options.onLoaded) {
315
- this.options.onLoaded(map);
316
- }
317
- }
318
-
319
- private showFallbackContent(colors: VectorMapColors): void {
320
- if (!this.container) return;
321
-
322
- this.container.innerHTML = `
323
- <div style="
324
- display: flex;
325
- align-items: center;
326
- justify-content: center;
327
- height: 100%;
328
- background: ${colors.backgroundColor};
329
- border: 1px solid ${colors.borderColor};
330
- border-radius: 8px;
331
- color: ${colors.textColor};
332
- font-size: 14px;
333
- font-family: system-ui, -apple-system, sans-serif;
334
- ">
335
- <div style="text-align: center; padding: 20px;">
336
- <div style="font-size: 32px; margin-bottom: 12px;">🗺️</div>
337
- <div style="font-size: 16px; font-weight: 500; margin-bottom: 8px;">World Map</div>
338
- <div style="font-size: 12px; opacity: 0.7;">Interactive map will load here</div>
339
- </div>
340
- </div>
341
- `;
342
- }
343
-
344
- private updateMapTheme(): void {
345
- if (!this.mapInstance || !this.container) {
346
- this.createMap();
347
- return;
348
- }
349
-
350
- const colors = this.getThemeColors();
351
-
352
- try {
353
- // Update container background
354
- this.container.style.backgroundColor = colors.backgroundColor;
355
- this.container.style.borderColor = colors.borderColor;
356
-
357
- // Update series if available
358
- if (this.mapInstance.series?.regions?.[0]) {
359
- this.mapInstance.updateSeries('regions', {
360
- attribute: 'fill',
361
- scale: [colors.scaleStart, colors.scaleEnd],
362
- values: this.mapInstance.series.regions[0].values || {},
363
- });
364
- }
365
- } catch (error) {
366
- console.warn('VectorMap: Theme update failed, reinitializing', error);
367
- this.createMap();
368
- }
369
- }
370
-
371
- private handleResize(): void {
372
- if (this.mapInstance && this.container) {
373
- // Force a re-render by recreating the map
374
- this.createMap();
375
- }
376
- }
377
-
378
- private destroyMapInstance(): void {
379
- if (this.mapInstance) {
380
- try {
381
- this.mapInstance.destroy();
382
- } catch (error) {
383
- console.warn('VectorMap: Error destroying map instance', error);
384
- }
385
- this.mapInstance = null;
386
- }
387
- }
388
-
389
- private cleanup(): void {
390
- this.destroyMapInstance();
391
-
392
- // Remove event listeners
393
- if (this.themeChangeHandler) {
394
- window.removeEventListener('adminator:themeChanged', this.themeChangeHandler);
395
- this.themeChangeHandler = null;
396
- }
397
-
398
- if (this.resizeHandler) {
399
- window.removeEventListener('resize', this.resizeHandler);
400
- this.resizeHandler = null;
401
- }
402
-
403
- // Disconnect ResizeObserver
404
- if (this.resizeObserver) {
405
- this.resizeObserver.disconnect();
406
- this.resizeObserver = null;
407
- }
408
-
409
- // Clear container
410
- if (this.container && this.container.parentNode) {
411
- this.container.parentNode.removeChild(this.container);
412
- this.container = null;
413
- }
414
- }
415
-
416
- // Public API methods
417
- public updateMarkers(markers: VectorMapMarker[]): void {
418
- this.options.markers = markers;
419
- this.createMap();
420
- }
421
-
422
- public updateSeries(type: string, config: any): void {
423
- if (this.mapInstance) {
424
- try {
425
- this.mapInstance.updateSeries(type, config);
426
- } catch (error) {
427
- console.warn('VectorMap: Error updating series', error);
428
- }
429
- }
430
- }
431
-
432
- public getMapInstance(): VectorMapInstance | null {
433
- return this.mapInstance;
434
- }
435
-
436
- public refresh(): void {
437
- this.createMap();
438
- }
439
-
440
- public updateOptions(newOptions: Partial<VectorMapOptions>): void {
441
- this.options = { ...this.options, ...newOptions };
442
- this.createMap();
443
- }
444
- }
445
-
446
- // Vector Map Manager
447
- export class VectorMapManager {
448
- private instances: Map<string, VectorMapComponent> = new Map();
449
-
450
- public initialize(selector: string = '#world-map-marker', options: Partial<VectorMapOptions> = {}): VectorMapComponent | null {
451
- const element = document.querySelector<HTMLElement>(selector);
452
- if (!element) {
453
- // Silently return null if element doesn't exist (normal for pages without maps)
454
- return null;
455
- }
456
-
457
- // Clean up existing instance
458
- const existingInstance = this.instances.get(selector);
459
- if (existingInstance) {
460
- existingInstance.destroy();
461
- }
462
-
463
- // Create new instance
464
- const vectorMap = new VectorMapComponent(element, options);
465
- this.instances.set(selector, vectorMap);
466
-
467
- return vectorMap;
468
- }
469
-
470
- public getInstance(selector: string): VectorMapComponent | undefined {
471
- return this.instances.get(selector);
472
- }
473
-
474
- public destroyInstance(selector: string): void {
475
- const instance = this.instances.get(selector);
476
- if (instance) {
477
- instance.destroy();
478
- this.instances.delete(selector);
479
- }
480
- }
481
-
482
- public destroyAll(): void {
483
- this.instances.forEach((instance) => {
484
- instance.destroy();
485
- });
486
- this.instances.clear();
487
- }
488
- }
489
-
490
- // Create singleton manager
491
- const vectorMapManager = new VectorMapManager();
492
-
493
- // Main initialization function
494
- const vectorMapInit = (): void => {
495
- // Only initialize if the map container exists
496
- if (document.querySelector('#world-map-marker')) {
497
- vectorMapManager.initialize('#world-map-marker', {
498
- markers: [
499
- {
500
- name: 'INDIA : 350',
501
- coords: [21.00, 78.00],
502
- },
503
- {
504
- name: 'Australia : 250',
505
- coords: [-33.00, 151.00],
506
- },
507
- {
508
- name: 'USA : 250',
509
- coords: [36.77, -119.41],
510
- },
511
- {
512
- name: 'UK : 250',
513
- coords: [55.37, -3.41],
514
- },
515
- {
516
- name: 'UAE : 250',
517
- coords: [25.20, 55.27],
518
- },
519
- ],
520
- });
521
- }
522
- };
523
-
524
- // Initialize map
525
- if (document.readyState === 'loading') {
526
- document.addEventListener('DOMContentLoaded', vectorMapInit);
527
- } else {
528
- vectorMapInit();
529
- }
530
-
531
- // Cleanup on page unload
532
- window.addEventListener('beforeunload', () => {
533
- vectorMapManager.destroyAll();
534
- });
535
-
536
- // Export default for compatibility
537
- export default {
538
- init: vectorMapInit,
539
- manager: vectorMapManager,
540
- VectorMapComponent,
541
- VectorMapManager,
542
- };
package/src/test.html DELETED
@@ -1,96 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
- <title>Test</title>
7
- <style>
8
- #loader {
9
- transition: all 0.3s ease-in-out;
10
- opacity: 1;
11
- visibility: visible;
12
- position: fixed;
13
- height: 100vh;
14
- width: 100%;
15
- background: #fff;
16
- z-index: 90000;
17
- }
18
-
19
- #loader.fadeOut {
20
- opacity: 0;
21
- visibility: hidden;
22
- }
23
-
24
-
25
-
26
- .spinner {
27
- width: 40px;
28
- height: 40px;
29
- position: absolute;
30
- top: calc(50% - 20px);
31
- left: calc(50% - 20px);
32
- background-color: #333;
33
- border-radius: 100%;
34
- -webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
35
- animation: sk-scaleout 1.0s infinite ease-in-out;
36
- }
37
-
38
- @-webkit-keyframes sk-scaleout {
39
- 0% { -webkit-transform: scale(0) }
40
- 100% {
41
- -webkit-transform: scale(1.0);
42
- opacity: 0;
43
- }
44
- }
45
-
46
- @keyframes sk-scaleout {
47
- 0% {
48
- -webkit-transform: scale(0);
49
- transform: scale(0);
50
- } 100% {
51
- -webkit-transform: scale(1.0);
52
- transform: scale(1.0);
53
- opacity: 0;
54
- }
55
- }
56
- </style>
57
- </head>
58
- <body class="app">
59
- <div id='loader'>
60
- <div class="spinner"></div>
61
- </div>
62
-
63
- <script>
64
- window.addEventListener('load', function load() {
65
- const loader = document.getElementById('loader');
66
- setTimeout(function() {
67
- loader.classList.add('fadeOut');
68
- }, 300);
69
- });
70
- </script>
71
- <div class="page-container">
72
- <!-- <div class="header navbar">
73
- <div class="header-container">
74
-
75
- </div>
76
-
77
- </div> -->
78
- <main class='main-content bgc-grey-100'>
79
- <div id='mainContent'>
80
- <div class="full-container">
81
- <button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top">
82
- Tooltip on top
83
- </button>
84
- <button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top">
85
- Tooltip on top
86
- </button>
87
-
88
- </div>
89
- </div>
90
- </main>
91
- <footer class="bdT ta-c p-30 lh-0 fsz-sm c-grey-600">
92
- <span>Copyright © 2025 Designed by <a href="https://colorlib.com" target="_blank" rel="nofollow noopener noreferrer" title="Colorlib">Colorlib</a>. All rights reserved.</span>
93
- </footer>
94
- </div>
95
- </body>
96
- </html>