adminator-admin-dashboard 2.7.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 (191) hide show
  1. package/CLAUDE.md +162 -0
  2. package/LICENSE +21 -0
  3. package/README.md +376 -0
  4. package/RELEASE_NOTES.md +92 -0
  5. package/dist/1e59d2330b4c6deb84b3.ttf +0 -0
  6. package/dist/20fd1704ea223900efa9.woff2 +0 -0
  7. package/dist/29b39089170885ae2967.woff +0 -0
  8. package/dist/404.html +24 -0
  9. package/dist/500.html +24 -0
  10. package/dist/55b07f26c86c8e3d3754.svg +1 -0
  11. package/dist/8b43027f47b20503057d.eot +0 -0
  12. package/dist/9bad94440d49256265a5.eot +0 -0
  13. package/dist/9fad440d8ee7a949a9a9.svg +1 -0
  14. package/dist/assets/c1e38fd9e0e74ba58f7a2b77ef29fdd3.svg +2671 -0
  15. package/dist/assets/f0fc8c798eac5636249c4ea287832422.svg +362 -0
  16. package/dist/assets/static/fonts/icons/fontawesome/FontAwesome.otf +0 -0
  17. package/dist/assets/static/fonts/icons/fontawesome/fontawesome-webfont.eot +0 -0
  18. package/dist/assets/static/fonts/icons/fontawesome/fontawesome-webfont.svg +2671 -0
  19. package/dist/assets/static/fonts/icons/fontawesome/fontawesome-webfont.ttf +0 -0
  20. package/dist/assets/static/fonts/icons/fontawesome/fontawesome-webfont.woff +0 -0
  21. package/dist/assets/static/fonts/icons/fontawesome/fontawesome-webfont.woff2 +0 -0
  22. package/dist/assets/static/fonts/icons/themify/themify.eot +0 -0
  23. package/dist/assets/static/fonts/icons/themify/themify.svg +362 -0
  24. package/dist/assets/static/fonts/icons/themify/themify.ttf +0 -0
  25. package/dist/assets/static/fonts/icons/themify/themify.woff +0 -0
  26. package/dist/assets/static/images/404.png +0 -0
  27. package/dist/assets/static/images/500.png +0 -0
  28. package/dist/assets/static/images/bg.jpg +0 -0
  29. package/dist/assets/static/images/datatables/sort_asc.png +0 -0
  30. package/dist/assets/static/images/datatables/sort_asc_disabled.png +0 -0
  31. package/dist/assets/static/images/datatables/sort_both.png +0 -0
  32. package/dist/assets/static/images/datatables/sort_desc.png +0 -0
  33. package/dist/assets/static/images/datatables/sort_desc_disabled.png +0 -0
  34. package/dist/assets/static/images/logo-circle.svg +7 -0
  35. package/dist/assets/static/images/logo-gradient.svg +13 -0
  36. package/dist/assets/static/images/logo-outline.svg +7 -0
  37. package/dist/assets/static/images/logo.png +0 -0
  38. package/dist/assets/static/images/logo.svg +5 -0
  39. package/dist/basic-table.html +715 -0
  40. package/dist/blank.html +522 -0
  41. package/dist/buttons.html +467 -0
  42. package/dist/calendar.html +692 -0
  43. package/dist/charts.html +681 -0
  44. package/dist/chat.html +730 -0
  45. package/dist/compose.html +643 -0
  46. package/dist/datatable.html +1009 -0
  47. package/dist/eda8b94308c6f538f04a.ttf +0 -0
  48. package/dist/email.html +992 -0
  49. package/dist/f691f37e57f04c152e23.woff +0 -0
  50. package/dist/forms.html +760 -0
  51. package/dist/google-maps.html +530 -0
  52. package/dist/index.html +1090 -0
  53. package/dist/main.js +61239 -0
  54. package/dist/main.js.map +1 -0
  55. package/dist/signin.html +107 -0
  56. package/dist/signup.html +104 -0
  57. package/dist/test.html +91 -0
  58. package/dist/ui.html +931 -0
  59. package/dist/vector-maps.html +529 -0
  60. package/package.json +112 -0
  61. package/src/404.html +24 -0
  62. package/src/500.html +24 -0
  63. package/src/assets/scripts/app.js +644 -0
  64. package/src/assets/scripts/charts/chartJS/index.js +148 -0
  65. package/src/assets/scripts/charts/easyPieChart/index.js +200 -0
  66. package/src/assets/scripts/charts/index.js +3 -0
  67. package/src/assets/scripts/charts/sparkline/index.js +208 -0
  68. package/src/assets/scripts/chat/index.js +11 -0
  69. package/src/assets/scripts/components/Chart.js +1390 -0
  70. package/src/assets/scripts/components/Sidebar.js +241 -0
  71. package/src/assets/scripts/constants/colors.js +274 -0
  72. package/src/assets/scripts/datatable/index.js +379 -0
  73. package/src/assets/scripts/datepicker/index.js +302 -0
  74. package/src/assets/scripts/email/index.js +25 -0
  75. package/src/assets/scripts/fullcalendar/index.js +86 -0
  76. package/src/assets/scripts/googleMaps/index.js +93 -0
  77. package/src/assets/scripts/index.js +18 -0
  78. package/src/assets/scripts/masonry/index.js +14 -0
  79. package/src/assets/scripts/popover/index.js +109 -0
  80. package/src/assets/scripts/scrollbar/index.js +10 -0
  81. package/src/assets/scripts/search/index.js +15 -0
  82. package/src/assets/scripts/sidebar/index.js +140 -0
  83. package/src/assets/scripts/skycons/index.js +52 -0
  84. package/src/assets/scripts/ui/index.js +412 -0
  85. package/src/assets/scripts/utils/date.js +242 -0
  86. package/src/assets/scripts/utils/dom.js +349 -0
  87. package/src/assets/scripts/utils/index.js +45 -0
  88. package/src/assets/scripts/utils/theme.js +105 -0
  89. package/src/assets/scripts/vectorMaps/index.js +277 -0
  90. package/src/assets/static/fonts/icons/fontawesome/FontAwesome.otf +0 -0
  91. package/src/assets/static/fonts/icons/fontawesome/fontawesome-webfont.eot +0 -0
  92. package/src/assets/static/fonts/icons/fontawesome/fontawesome-webfont.svg +2671 -0
  93. package/src/assets/static/fonts/icons/fontawesome/fontawesome-webfont.ttf +0 -0
  94. package/src/assets/static/fonts/icons/fontawesome/fontawesome-webfont.woff +0 -0
  95. package/src/assets/static/fonts/icons/fontawesome/fontawesome-webfont.woff2 +0 -0
  96. package/src/assets/static/fonts/icons/themify/themify.eot +0 -0
  97. package/src/assets/static/fonts/icons/themify/themify.svg +362 -0
  98. package/src/assets/static/fonts/icons/themify/themify.ttf +0 -0
  99. package/src/assets/static/fonts/icons/themify/themify.woff +0 -0
  100. package/src/assets/static/images/404.png +0 -0
  101. package/src/assets/static/images/500.png +0 -0
  102. package/src/assets/static/images/bg.jpg +0 -0
  103. package/src/assets/static/images/datatables/sort_asc.png +0 -0
  104. package/src/assets/static/images/datatables/sort_asc_disabled.png +0 -0
  105. package/src/assets/static/images/datatables/sort_both.png +0 -0
  106. package/src/assets/static/images/datatables/sort_desc.png +0 -0
  107. package/src/assets/static/images/datatables/sort_desc_disabled.png +0 -0
  108. package/src/assets/static/images/logo-circle.svg +7 -0
  109. package/src/assets/static/images/logo-gradient.svg +13 -0
  110. package/src/assets/static/images/logo-outline.svg +7 -0
  111. package/src/assets/static/images/logo.png +0 -0
  112. package/src/assets/static/images/logo.svg +5 -0
  113. package/src/assets/styles/index.scss +801 -0
  114. package/src/assets/styles/spec/components/easyPieChart.scss +11 -0
  115. package/src/assets/styles/spec/components/footer.scss +4 -0
  116. package/src/assets/styles/spec/components/forms.scss +288 -0
  117. package/src/assets/styles/spec/components/index.scss +9 -0
  118. package/src/assets/styles/spec/components/loader.scss +46 -0
  119. package/src/assets/styles/spec/components/masonry.scss +1 -0
  120. package/src/assets/styles/spec/components/pageContainer.scss +255 -0
  121. package/src/assets/styles/spec/components/progressBar.scss +6 -0
  122. package/src/assets/styles/spec/components/sidebar.scss +642 -0
  123. package/src/assets/styles/spec/components/topbar.scss +455 -0
  124. package/src/assets/styles/spec/generic/base.scss +102 -0
  125. package/src/assets/styles/spec/generic/index.scss +1 -0
  126. package/src/assets/styles/spec/index.scss +4 -0
  127. package/src/assets/styles/spec/screens/chat.scss +147 -0
  128. package/src/assets/styles/spec/screens/email.scss +108 -0
  129. package/src/assets/styles/spec/screens/index.scss +2 -0
  130. package/src/assets/styles/spec/settings/baseColors.scss +103 -0
  131. package/src/assets/styles/spec/settings/borders.scss +6 -0
  132. package/src/assets/styles/spec/settings/breakpoints.scss +26 -0
  133. package/src/assets/styles/spec/settings/fonts.scss +4 -0
  134. package/src/assets/styles/spec/settings/index.scss +4 -0
  135. package/src/assets/styles/spec/settings/materialColors.scss +550 -0
  136. package/src/assets/styles/spec/tools/index.scss +1 -0
  137. package/src/assets/styles/spec/tools/mixins/clearfix.scss +15 -0
  138. package/src/assets/styles/spec/tools/mixins/index.scss +3 -0
  139. package/src/assets/styles/spec/tools/mixins/mediaQueriesRanges.scss +58 -0
  140. package/src/assets/styles/spec/tools/mixins/placeholder.scss +10 -0
  141. package/src/assets/styles/spec/utils/colors.scss +33 -0
  142. package/src/assets/styles/spec/utils/index.scss +2 -0
  143. package/src/assets/styles/spec/utils/layout/helpers/border.scss +78 -0
  144. package/src/assets/styles/spec/utils/layout/helpers/flex.scss +220 -0
  145. package/src/assets/styles/spec/utils/layout/helpers/index.scss +11 -0
  146. package/src/assets/styles/spec/utils/layout/helpers/layout.scss +137 -0
  147. package/src/assets/styles/spec/utils/layout/helpers/lists.scss +23 -0
  148. package/src/assets/styles/spec/utils/layout/helpers/margin.scss +266 -0
  149. package/src/assets/styles/spec/utils/layout/helpers/objects.scss +91 -0
  150. package/src/assets/styles/spec/utils/layout/helpers/padding.scss +147 -0
  151. package/src/assets/styles/spec/utils/layout/helpers/positions.scss +118 -0
  152. package/src/assets/styles/spec/utils/layout/helpers/pseudo.scss +6 -0
  153. package/src/assets/styles/spec/utils/layout/helpers/sizes.scss +157 -0
  154. package/src/assets/styles/spec/utils/layout/helpers/typography.scss +127 -0
  155. package/src/assets/styles/spec/utils/layout/index.scss +3 -0
  156. package/src/assets/styles/spec/utils/layout/mixins/generateResponsive.scss +25 -0
  157. package/src/assets/styles/spec/utils/layout/mixins/index.scss +2 -0
  158. package/src/assets/styles/spec/utils/layout/mixins/mediaQueryCondition.scss +28 -0
  159. package/src/assets/styles/spec/utils/layout/utils/center.scss +54 -0
  160. package/src/assets/styles/spec/utils/layout/utils/gap.scss +229 -0
  161. package/src/assets/styles/spec/utils/layout/utils/index.scss +5 -0
  162. package/src/assets/styles/spec/utils/layout/utils/layers.scss +5 -0
  163. package/src/assets/styles/spec/utils/layout/utils/peers.scss +35 -0
  164. package/src/assets/styles/utils/mobile.scss +954 -0
  165. package/src/assets/styles/utils/theme.css +97 -0
  166. package/src/assets/styles/vendor/datepicker.scss +183 -0
  167. package/src/assets/styles/vendor/font-awesome.css +2337 -0
  168. package/src/assets/styles/vendor/fullcalendar.scss +217 -0
  169. package/src/assets/styles/vendor/index.scss +8 -0
  170. package/src/assets/styles/vendor/jquery.datatables.scss +162 -0
  171. package/src/assets/styles/vendor/perfectScrollbar.scss +4 -0
  172. package/src/assets/styles/vendor/sparkline.scss +6 -0
  173. package/src/assets/styles/vendor/themify-icons.css +1081 -0
  174. package/src/basic-table.html +725 -0
  175. package/src/blank.html +532 -0
  176. package/src/buttons.html +477 -0
  177. package/src/calendar.html +702 -0
  178. package/src/charts.html +691 -0
  179. package/src/chat.html +740 -0
  180. package/src/compose.html +653 -0
  181. package/src/datatable.html +1019 -0
  182. package/src/email.html +1002 -0
  183. package/src/forms.html +770 -0
  184. package/src/google-maps.html +540 -0
  185. package/src/index.html +1100 -0
  186. package/src/signin.html +107 -0
  187. package/src/signup.html +104 -0
  188. package/src/test.html +96 -0
  189. package/src/ui.html +941 -0
  190. package/src/vector-maps.html +539 -0
  191. package/webpack.config.js +3 -0
@@ -0,0 +1,86 @@
1
+ import { Calendar } from '@fullcalendar/core';
2
+ import interactionPlugin from '@fullcalendar/interaction';
3
+ import dayGridPlugin from '@fullcalendar/daygrid';
4
+ import timeGridPlugin from '@fullcalendar/timegrid';
5
+ import listPlugin from '@fullcalendar/list';
6
+ import DateUtils from '../utils/date';
7
+
8
+ document.addEventListener('DOMContentLoaded', function () {
9
+ const calendarEl = document.getElementById('calendar');
10
+
11
+ // element found in dom ?
12
+ if (calendarEl == null) {
13
+ return;
14
+ }
15
+
16
+ const calendar = new Calendar(calendarEl, {
17
+ plugins: [interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin],
18
+ headerToolbar: {
19
+ left: 'prev,next today',
20
+ center: 'title',
21
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek',
22
+ },
23
+ initialDate: DateUtils.format(DateUtils.now(), 'YYYY-MM-DD'),
24
+ navLinks: true, // can click day/week names to navigate views
25
+ editable: true,
26
+ dayMaxEvents: true, // allow "more" link when too many events
27
+ events: [
28
+ {
29
+ title: 'All Day Event',
30
+ start: DateUtils.format(DateUtils.now(), 'YYYY-MM-DD'),
31
+ },
32
+ {
33
+ title: 'Long Event',
34
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 1, 'day'), 'YYYY-MM-DD'),
35
+ end: DateUtils.format(DateUtils.add(DateUtils.now(), 4, 'day'), 'YYYY-MM-DD'),
36
+ },
37
+ {
38
+ groupId: 999,
39
+ title: 'Repeating Event',
40
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 2, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T16:00'),
41
+ },
42
+ {
43
+ groupId: 999,
44
+ title: 'Repeating Event',
45
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 9, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T16:00'),
46
+ },
47
+ {
48
+ title: 'Conference',
49
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 5, 'day'), 'YYYY-MM-DD'),
50
+ end: DateUtils.format(DateUtils.add(DateUtils.now(), 7, 'day'), 'YYYY-MM-DD'),
51
+ },
52
+ {
53
+ title: 'Meeting',
54
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T10:30'),
55
+ end: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T12:30'),
56
+ },
57
+ {
58
+ title: 'Lunch',
59
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T12:00'),
60
+ },
61
+ {
62
+ title: 'Meeting',
63
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T14:30'),
64
+ },
65
+ {
66
+ title: 'Happy Hour',
67
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T17:30'),
68
+ },
69
+ {
70
+ title: 'Dinner',
71
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T20:00'),
72
+ },
73
+ {
74
+ title: 'Birthday Party',
75
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 4, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T07:00'),
76
+ },
77
+ {
78
+ title: 'Click for Google',
79
+ url: 'http://google.com/',
80
+ start: DateUtils.format(DateUtils.add(DateUtils.now(), 14, 'day'), 'YYYY-MM-DD'),
81
+ },
82
+ ],
83
+ });
84
+
85
+ calendar.render();
86
+ });
@@ -0,0 +1,93 @@
1
+ import loadGoogleMapsAPI from 'load-google-maps-api';
2
+ import Theme from '../utils/theme.js';
3
+
4
+ export default (function () {
5
+ let map, marker;
6
+
7
+ const initGoogleMap = () => {
8
+ const googleMapElement = document.getElementById('google-map');
9
+ if (googleMapElement) {
10
+ loadGoogleMapsAPI({
11
+ key: 'AIzaSyDW8td30_gj6sGXjiMU0ALeMu1SDEwUnEA',
12
+ }).then(() => {
13
+ const latitude = 26.8206;
14
+ const longitude = 30.8025;
15
+ const mapZoom = 5;
16
+ const { google } = window;
17
+
18
+ const mapOptions = {
19
+ center : new google.maps.LatLng(latitude, longitude),
20
+ zoom : mapZoom,
21
+ mapTypeId : google.maps.MapTypeId.ROADMAP,
22
+ styles: [{
23
+ 'featureType': 'landscape',
24
+ 'stylers': [
25
+ { 'hue' : Theme.getCSSVar('--gmap-landscape-hue') },
26
+ { 'saturation' : 43.400000000000006 },
27
+ { 'lightness' : 37.599999999999994 },
28
+ { 'gamma' : 1 },
29
+ ],
30
+ }, {
31
+ 'featureType': 'road.highway',
32
+ 'stylers': [
33
+ { 'hue' : Theme.getCSSVar('--gmap-highway-hue') },
34
+ { 'saturation' : -61.8 },
35
+ { 'lightness' : 45.599999999999994 },
36
+ { 'gamma' : 1 },
37
+ ],
38
+ }, {
39
+ 'featureType': 'road.arterial',
40
+ 'stylers': [
41
+ { 'hue' : Theme.getCSSVar('--gmap-road-hue') },
42
+ { 'saturation' : -100 },
43
+ { 'lightness' : 51.19999999999999 },
44
+ { 'gamma' : 1 },
45
+ ],
46
+ }, {
47
+ 'featureType': 'road.local',
48
+ 'stylers': [
49
+ { 'hue' : Theme.getCSSVar('--gmap-road-hue') },
50
+ { 'saturation' : -100 },
51
+ { 'lightness' : 52 },
52
+ { 'gamma' : 1 },
53
+ ],
54
+ }, {
55
+ 'featureType': 'water',
56
+ 'stylers': [
57
+ { 'hue' : Theme.getCSSVar('--gmap-water-hue') },
58
+ { 'saturation' : -13.200000000000003 },
59
+ { 'lightness' : 2.4000000000000057 },
60
+ { 'gamma' : 1 },
61
+ ],
62
+ }, {
63
+ 'featureType': 'poi',
64
+ 'stylers': [
65
+ { 'hue' : Theme.getCSSVar('--gmap-poi-hue') },
66
+ { 'saturation' : -1.0989010989011234 },
67
+ { 'lightness' : 11.200000000000017 },
68
+ { 'gamma' : 1 },
69
+ ],
70
+ }],
71
+ };
72
+
73
+ map = new google.maps.Map(document.getElementById('google-map'), mapOptions);
74
+
75
+ if (marker) {
76
+ marker.setMap(null);
77
+ }
78
+
79
+ marker = new google.maps.Marker({
80
+ map,
81
+ position : new google.maps.LatLng(latitude, longitude),
82
+ visible : true,
83
+ });
84
+ });
85
+ }
86
+ };
87
+
88
+ // Initialize Google Maps
89
+ initGoogleMap();
90
+
91
+ // Listen for theme changes
92
+ window.addEventListener('adminator:themeChanged', initGoogleMap);
93
+ }())
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Adminator Admin Template
3
+ * Modern Entry Point - Phase 2 Modernization
4
+ */
5
+
6
+ // Import the modern application
7
+ import './app.js';
8
+
9
+ // Legacy imports that haven't been modernized yet
10
+ // These will be gradually replaced in future iterations
11
+ import './datatable';
12
+ // import './datepicker'; // REMOVED: Replaced with modern day.js implementation in app.js
13
+
14
+ // Note: The following have been modernized and are now handled by app.js:
15
+ // - sidebar (now Sidebar component)
16
+ // - charts (now ChartComponent using Chart.js instead of jQuery Sparkline)
17
+ // - Basic DOM utilities (now DOM utils)
18
+
@@ -0,0 +1,14 @@
1
+ import Masonry from 'masonry-layout';
2
+
3
+ export default (function () {
4
+ window.addEventListener('load', () => {
5
+ const masonryElement = document.querySelector('.masonry');
6
+ if (masonryElement) {
7
+ new Masonry(masonryElement, {
8
+ itemSelector: '.masonry-item',
9
+ columnWidth: '.masonry-sizer',
10
+ percentPosition: true,
11
+ });
12
+ }
13
+ });
14
+ }());
@@ -0,0 +1,109 @@
1
+ // Simple vanilla JS tooltip and popover implementation
2
+ export default (function () {
3
+
4
+ // Simple tooltip implementation
5
+ function initTooltips() {
6
+ const tooltipElements = document.querySelectorAll('[data-bs-toggle="tooltip"]');
7
+
8
+ tooltipElements.forEach(element => {
9
+ const tooltipText = element.getAttribute('data-bs-title') || element.getAttribute('title');
10
+
11
+ if (tooltipText) {
12
+ element.addEventListener('mouseenter', function() {
13
+ const tooltip = document.createElement('div');
14
+ tooltip.className = 'custom-tooltip';
15
+ tooltip.textContent = tooltipText;
16
+ tooltip.style.cssText = `
17
+ position: absolute;
18
+ background: #000;
19
+ color: #fff;
20
+ padding: 4px 8px;
21
+ border-radius: 4px;
22
+ font-size: 12px;
23
+ z-index: 1050;
24
+ pointer-events: none;
25
+ white-space: nowrap;
26
+ `;
27
+
28
+ document.body.appendChild(tooltip);
29
+
30
+ const rect = element.getBoundingClientRect();
31
+ tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2) }px`;
32
+ tooltip.style.top = `${rect.top - tooltip.offsetHeight - 5 }px`;
33
+
34
+ element._tooltip = tooltip;
35
+ });
36
+
37
+ element.addEventListener('mouseleave', function() {
38
+ if (element._tooltip) {
39
+ element._tooltip.remove();
40
+ element._tooltip = null;
41
+ }
42
+ });
43
+ }
44
+ });
45
+ }
46
+
47
+ // Simple popover implementation
48
+ function initPopovers() {
49
+ const popoverElements = document.querySelectorAll('[data-bs-toggle="popover"]');
50
+
51
+ popoverElements.forEach(element => {
52
+ const popoverContent = element.getAttribute('data-bs-content');
53
+ const popoverTitle = element.getAttribute('data-bs-title');
54
+
55
+ if (popoverContent) {
56
+ element.addEventListener('click', function(e) {
57
+ e.preventDefault();
58
+
59
+ // Remove existing popover
60
+ if (element._popover) {
61
+ element._popover.remove();
62
+ element._popover = null;
63
+ return;
64
+ }
65
+
66
+ const popover = document.createElement('div');
67
+ popover.className = 'custom-popover';
68
+ popover.innerHTML = `
69
+ ${popoverTitle ? `<div class="popover-title">${popoverTitle}</div>` : ''}
70
+ <div class="popover-content">${popoverContent}</div>
71
+ `;
72
+ popover.style.cssText = `
73
+ position: absolute;
74
+ background: #fff;
75
+ border: 1px solid #ccc;
76
+ border-radius: 6px;
77
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
78
+ z-index: 1050;
79
+ min-width: 200px;
80
+ max-width: 300px;
81
+ `;
82
+
83
+ document.body.appendChild(popover);
84
+
85
+ const rect = element.getBoundingClientRect();
86
+ popover.style.left = `${rect.left }px`;
87
+ popover.style.top = `${rect.bottom + 5 }px`;
88
+
89
+ element._popover = popover;
90
+ });
91
+ }
92
+ });
93
+ }
94
+
95
+ // Initialize both
96
+ initTooltips();
97
+ initPopovers();
98
+
99
+ // Close popovers when clicking outside
100
+ document.addEventListener('click', function(e) {
101
+ const popovers = document.querySelectorAll('.custom-popover');
102
+ popovers.forEach(popover => {
103
+ if (!popover.contains(e.target)) {
104
+ popover.remove();
105
+ }
106
+ });
107
+ });
108
+
109
+ }());
@@ -0,0 +1,10 @@
1
+ import PerfectScrollbar from 'perfect-scrollbar';
2
+
3
+ export default (function () {
4
+ const scrollables = document.querySelectorAll('.scrollable');
5
+ if (scrollables.length > 0) {
6
+ scrollables.forEach(el => {
7
+ new PerfectScrollbar(el);
8
+ });
9
+ }
10
+ }());
@@ -0,0 +1,15 @@
1
+ export default (function () {
2
+ const searchToggle = document.querySelector('.search-toggle');
3
+ const searchBox = document.querySelector('.search-box');
4
+ const searchInput = document.querySelector('.search-input');
5
+ const searchInputField = document.querySelector('.search-input input');
6
+
7
+ if (searchToggle && searchBox && searchInput && searchInputField) {
8
+ searchToggle.addEventListener('click', e => {
9
+ searchBox.classList.toggle('active');
10
+ searchInput.classList.toggle('active');
11
+ searchInputField.focus();
12
+ e.preventDefault();
13
+ });
14
+ }
15
+ }());
@@ -0,0 +1,140 @@
1
+ // Vanilla JS slide animations
2
+ function slideUp(element, duration = 200, callback = null) {
3
+ element.style.height = `${element.scrollHeight }px`;
4
+ element.style.transition = `height ${duration}ms ease`;
5
+ element.style.overflow = 'hidden';
6
+
7
+ requestAnimationFrame(() => {
8
+ element.style.height = '0';
9
+ element.style.paddingTop = '0';
10
+ element.style.paddingBottom = '0';
11
+ element.style.marginTop = '0';
12
+ element.style.marginBottom = '0';
13
+ });
14
+
15
+ setTimeout(() => {
16
+ element.style.display = 'none';
17
+ element.style.removeProperty('height');
18
+ element.style.removeProperty('padding-top');
19
+ element.style.removeProperty('padding-bottom');
20
+ element.style.removeProperty('margin-top');
21
+ element.style.removeProperty('margin-bottom');
22
+ element.style.removeProperty('overflow');
23
+ element.style.removeProperty('transition');
24
+ if (callback) callback();
25
+ }, duration);
26
+ }
27
+
28
+ function slideDown(element, duration = 200, callback = null) {
29
+ element.style.removeProperty('display');
30
+ let display = window.getComputedStyle(element).display;
31
+ if (display === 'none') display = 'block';
32
+
33
+ element.style.display = display;
34
+ element.style.height = '0';
35
+ element.style.paddingTop = '0';
36
+ element.style.paddingBottom = '0';
37
+ element.style.marginTop = '0';
38
+ element.style.marginBottom = '0';
39
+ element.style.overflow = 'hidden';
40
+
41
+ const height = element.scrollHeight;
42
+
43
+ element.style.transition = `height ${duration}ms ease`;
44
+
45
+ requestAnimationFrame(() => {
46
+ element.style.height = `${height }px`;
47
+ element.style.removeProperty('padding-top');
48
+ element.style.removeProperty('padding-bottom');
49
+ element.style.removeProperty('margin-top');
50
+ element.style.removeProperty('margin-bottom');
51
+ });
52
+
53
+ setTimeout(() => {
54
+ element.style.removeProperty('height');
55
+ element.style.removeProperty('overflow');
56
+ element.style.removeProperty('transition');
57
+ if (callback) callback();
58
+ }, duration);
59
+ }
60
+
61
+ export default (function () {
62
+ // Sidebar links
63
+ const sidebarLinks = document.querySelectorAll('.sidebar .sidebar-menu li a');
64
+
65
+ sidebarLinks.forEach(link => {
66
+ link.addEventListener('click', function () {
67
+ const parentLi = this.parentElement;
68
+ const dropdownMenu = parentLi.querySelector('.dropdown-menu');
69
+
70
+ if (!dropdownMenu) return;
71
+
72
+ if (parentLi.classList.contains('open')) {
73
+ slideUp(dropdownMenu, 200, () => {
74
+ parentLi.classList.remove('open');
75
+ });
76
+ } else {
77
+ // Close all other open menus at the same level
78
+ const siblingMenus = parentLi.parentElement.querySelectorAll('li.open');
79
+ siblingMenus.forEach(sibling => {
80
+ const siblingDropdown = sibling.querySelector('.dropdown-menu');
81
+ const siblingLink = sibling.querySelector('a');
82
+
83
+ if (siblingDropdown) {
84
+ slideUp(siblingDropdown, 200);
85
+ }
86
+ if (siblingLink) {
87
+ siblingLink.classList.remove('open');
88
+ }
89
+ sibling.classList.remove('open');
90
+ });
91
+
92
+ // Open current menu
93
+ slideDown(dropdownMenu, 200, () => {
94
+ parentLi.classList.add('open');
95
+ });
96
+ }
97
+ });
98
+ });
99
+
100
+ // Sidebar Activity Class
101
+ const sidebarLinkElements = document.querySelectorAll('.sidebar .sidebar-link');
102
+
103
+ sidebarLinkElements.forEach(link => {
104
+ link.classList.remove('active');
105
+
106
+ const href = link.getAttribute('href');
107
+ if (href) {
108
+ const pattern = href[0] === '/' ? href.substr(1) : href;
109
+ if (pattern === window.location.pathname.substr(1)) {
110
+ link.classList.add('active');
111
+ }
112
+ }
113
+ });
114
+
115
+ // Sidebar Toggle
116
+ const sidebarToggle = document.querySelector('.sidebar-toggle');
117
+ const app = document.querySelector('.app');
118
+
119
+ if (sidebarToggle && app) {
120
+ sidebarToggle.addEventListener('click', e => {
121
+ app.classList.toggle('is-collapsed');
122
+ e.preventDefault();
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Wait until sidebar fully toggled (animated in/out)
128
+ * then trigger window resize event in order to recalculate
129
+ * masonry layout widths and gutters.
130
+ */
131
+ const sidebarToggleById = document.getElementById('sidebar-toggle');
132
+ if (sidebarToggleById) {
133
+ sidebarToggleById.addEventListener('click', e => {
134
+ e.preventDefault();
135
+ setTimeout(() => {
136
+ window.dispatchEvent(new Event('resize'));
137
+ }, 300);
138
+ });
139
+ }
140
+ }());
@@ -0,0 +1,52 @@
1
+ import SkyconsInit from 'skycons';
2
+ import Theme from '../utils/theme.js';
3
+
4
+ const Skycons = SkyconsInit(window);
5
+
6
+ export default (function () {
7
+ let icons;
8
+
9
+ const initSkycons = () => {
10
+ const skyconsColor = Theme.getCSSVar('--skycons-color');
11
+
12
+ if (icons) {
13
+ icons.pause();
14
+ icons.remove('all');
15
+ }
16
+
17
+ icons = new Skycons({ 'color': skyconsColor });
18
+
19
+ const list = [
20
+ 'clear-day',
21
+ 'clear-night',
22
+ 'partly-cloudy-day',
23
+ 'partly-cloudy-night',
24
+ 'cloudy',
25
+ 'rain',
26
+ 'sleet',
27
+ 'snow',
28
+ 'wind',
29
+ 'fog',
30
+ ];
31
+ let i = list.length;
32
+
33
+ while (i--) {
34
+ const
35
+ weatherType = list[i],
36
+ elements = document.getElementsByClassName(weatherType);
37
+ let j = elements.length;
38
+
39
+ while (j--) {
40
+ icons.set(elements[j], weatherType);
41
+ }
42
+ }
43
+
44
+ icons.play();
45
+ };
46
+
47
+ // Initialize skycons
48
+ initSkycons();
49
+
50
+ // Listen for theme changes
51
+ window.addEventListener('adminator:themeChanged', initSkycons);
52
+ }());