zebra-day 0.0.32__py3-none-any.whl → 1.0.2__py3-none-any.whl

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 (190) hide show
  1. zebra_day/__init__.py +35 -0
  2. zebra_day/bin/fetch_zebra_config.py +15 -0
  3. zebra_day/bin/generate_coord_grid_zpl.py +50 -0
  4. zebra_day/bin/print_zpl_from_file.py +21 -0
  5. zebra_day/bin/probe_new_label_dimensions.py +75 -0
  6. zebra_day/bin/scan_for_networed_zebra_printers_curl.sh +2 -1
  7. zebra_day/bin/zserve.py +701 -259
  8. zebra_day/cli/__init__.py +240 -0
  9. zebra_day/cli/cognito.py +121 -0
  10. zebra_day/cli/gui.py +255 -0
  11. zebra_day/cli/printer.py +168 -0
  12. zebra_day/cli/template.py +176 -0
  13. zebra_day/cmd_mgr.py +35 -0
  14. zebra_day/etc/label_styles/blank.zpl +0 -0
  15. zebra_day/etc/label_styles/cornersStripOf4Squares_1inX1in.zpl +55 -0
  16. zebra_day/etc/label_styles/corners_1inX2in.zpl +28 -0
  17. zebra_day/etc/label_styles/corners_20cmX30cm.zpl +6 -0
  18. zebra_day/etc/label_styles/corners_smallTube.zpl +7 -0
  19. zebra_day/etc/label_styles/corners_unspecifiedDimensions.zpl +15 -0
  20. zebra_day/etc/label_styles/plate_1inX0.25inHD.zpl +9 -0
  21. zebra_day/etc/label_styles/smallTubeWdotHD_prod.zpl +8 -0
  22. zebra_day/etc/label_styles/smallTubeWdot_corners.zpl +7 -0
  23. zebra_day/etc/label_styles/smallTubeWdot_prod.zpl +8 -0
  24. zebra_day/etc/label_styles/smallTubeWdot_prodAlt1.zpl +6 -0
  25. zebra_day/etc/label_styles/smallTubeWdot_prodAlt1b.zpl +3 -0
  26. zebra_day/etc/label_styles/smallTubeWdot_prodV2.zpl +8 -0
  27. zebra_day/etc/label_styles/smallTubeWdot_reagent.zpl +29 -0
  28. zebra_day/etc/label_styles/stripOf4Squares_1inX1in.zpl +32 -0
  29. zebra_day/etc/label_styles/test_800dX800dCoordinateArray.zpl +1 -0
  30. zebra_day/etc/label_styles/tmps/tmp_zpl_templates.here +0 -0
  31. zebra_day/etc/label_styles/tube_20mmX30mmA.zpl +7 -0
  32. zebra_day/etc/label_styles/tube_2inX0.5in.zpl +15 -0
  33. zebra_day/etc/label_styles/tube_2inX0.5inHD.zpl +15 -0
  34. zebra_day/etc/label_styles/tube_2inX1inHD.zpl +22 -0
  35. zebra_day/etc/label_styles/tube_2inX1inHDv3.zpl +21 -0
  36. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.022846_printer_config.json +1 -0
  37. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.033657_printer_config.json +1 -0
  38. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.039597_printer_config.json +3 -0
  39. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.047295_printer_config.json +1 -0
  40. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.055804_printer_config.json +1 -0
  41. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.061337_printer_config.json +3 -0
  42. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.073326_printer_config.json +1 -0
  43. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.081950_printer_config.json +1 -0
  44. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.088251_printer_config.json +3 -0
  45. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.096501_printer_config.json +1 -0
  46. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.104767_printer_config.json +1 -0
  47. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.110364_printer_config.json +3 -0
  48. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.118239_printer_config.json +1 -0
  49. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.125950_printer_config.json +1 -0
  50. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.349866_printer_config.json +1 -0
  51. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.361085_printer_config.json +3 -0
  52. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.558323_printer_config.json +1 -0
  53. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.565756_printer_config.json +3 -0
  54. zebra_day/etc/old_printer_config/{2023-10-25_02:19:04.139607_printer_config.json → 2026-02-01_01:51:29.739070_printer_config.json} +4 -3
  55. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.753796_printer_config.json +1 -0
  56. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.760201_printer_config.json +3 -0
  57. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.768747_printer_config.json +1 -0
  58. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.775312_printer_config.json +3 -0
  59. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.782533_printer_config.json +1 -0
  60. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.789287_printer_config.json +1 -0
  61. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.794230_printer_config.json +3 -0
  62. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.800021_printer_config.json +5 -0
  63. zebra_day/etc/printer_config.json +3 -54
  64. zebra_day/etc/printer_config.template.json +3 -2
  65. zebra_day/etc/tmp_printers0.json +5 -0
  66. zebra_day/etc/tmp_printers374.json +5 -0
  67. zebra_day/etc/tmp_printers383.json +5 -0
  68. zebra_day/etc/tmp_printers450.json +5 -0
  69. zebra_day/etc/tmp_printers504.json +5 -0
  70. zebra_day/etc/tmp_printers608.json +5 -0
  71. zebra_day/etc/tmp_printers657.json +5 -0
  72. zebra_day/etc/tmp_printers838.json +5 -0
  73. zebra_day/etc/tmp_printers839.json +5 -0
  74. zebra_day/etc/tmp_printers933.json +5 -0
  75. zebra_day/etc/tmp_printers957.json +5 -0
  76. zebra_day/exceptions.py +88 -0
  77. zebra_day/files/hold +0 -0
  78. zebra_day/files/test_png_17696.png +0 -0
  79. zebra_day/files/test_png_23477.png +0 -0
  80. zebra_day/files/test_png_28157.png +0 -0
  81. zebra_day/files/test_png_35832.png +0 -0
  82. zebra_day/files/test_png_36400.png +0 -0
  83. zebra_day/files/test_png_40816.png +0 -0
  84. zebra_day/files/test_png_49564.png +0 -0
  85. zebra_day/files/test_png_53848.png +0 -0
  86. zebra_day/files/test_png_62542.png +0 -0
  87. zebra_day/files/test_png_91597.png +0 -0
  88. zebra_day/files/test_png_93633.png +0 -0
  89. zebra_day/files/tmpbjo3k7q1.png +0 -0
  90. zebra_day/files/tmpigtr4pwy.png +0 -0
  91. zebra_day/files/zpl_label_tube_2inX1in_2026-02-01_01:51:24.370964.png +0 -0
  92. zebra_day/logging_config.py +74 -0
  93. zebra_day/logs/.hold +0 -0
  94. zebra_day/logs/print_requests.log +2 -0
  95. zebra_day/paths.py +143 -0
  96. zebra_day/print_mgr.py +489 -103
  97. zebra_day/static/datschund.css +63 -43
  98. zebra_day/static/datschund.png +0 -0
  99. zebra_day/static/daylily.png +0 -0
  100. zebra_day/static/favicon.svg +20 -0
  101. zebra_day/static/general.css +99 -0
  102. zebra_day/static/js/zebra_modern.js +172 -0
  103. zebra_day/static/lsmc.css +354 -0
  104. zebra_day/static/moon.jpeg +0 -0
  105. zebra_day/static/oakland.css +0 -32
  106. zebra_day/static/popday_daylily.css +1 -1
  107. zebra_day/static/style.css +39 -0
  108. zebra_day/static/zebra_modern.css +771 -0
  109. zebra_day/templates/base.html +36 -0
  110. zebra_day/templates/bpr.html +72 -0
  111. zebra_day/templates/build_new_config.html +36 -0
  112. zebra_day/templates/build_print_request.html +32 -0
  113. zebra_day/templates/chg_ui_style.html +19 -0
  114. zebra_day/templates/edit_template.html +128 -0
  115. zebra_day/templates/edit_zpl.html +37 -0
  116. zebra_day/templates/index.html +82 -0
  117. zebra_day/templates/legacy/base.html +37 -0
  118. zebra_day/templates/legacy/bpr.html +72 -0
  119. zebra_day/templates/legacy/build_new_config.html +36 -0
  120. zebra_day/templates/legacy/build_print_request.html +32 -0
  121. zebra_day/templates/legacy/chg_ui_style.html +19 -0
  122. zebra_day/templates/legacy/edit_template.html +128 -0
  123. zebra_day/templates/legacy/edit_zpl.html +37 -0
  124. zebra_day/templates/legacy/index.html +82 -0
  125. zebra_day/templates/legacy/list_prior_configs.html +24 -0
  126. zebra_day/templates/legacy/print_result.html +30 -0
  127. zebra_day/templates/legacy/printer_details.html +25 -0
  128. zebra_day/templates/legacy/printer_status.html +70 -0
  129. zebra_day/templates/legacy/save_result.html +17 -0
  130. zebra_day/templates/legacy/send_print_request.html +34 -0
  131. zebra_day/templates/legacy/simple_print.html +94 -0
  132. zebra_day/templates/legacy/view_pstation_json.html +29 -0
  133. zebra_day/templates/list_prior_configs.html +24 -0
  134. zebra_day/templates/modern/base.html +98 -0
  135. zebra_day/templates/modern/config.html +141 -0
  136. zebra_day/templates/modern/dashboard.html +160 -0
  137. zebra_day/templates/modern/print_request.html +141 -0
  138. zebra_day/templates/modern/print_result.html +88 -0
  139. zebra_day/templates/modern/printer_detail.html +117 -0
  140. zebra_day/templates/modern/printers.html +133 -0
  141. zebra_day/templates/modern/save_result.html +46 -0
  142. zebra_day/templates/modern/template_editor.html +172 -0
  143. zebra_day/templates/modern/templates.html +122 -0
  144. zebra_day/templates/print_result.html +30 -0
  145. zebra_day/templates/printer_details.html +25 -0
  146. zebra_day/templates/printer_status.html +70 -0
  147. zebra_day/templates/save_result.html +17 -0
  148. zebra_day/templates/send_print_request.html +34 -0
  149. zebra_day/templates/simple_print.html +94 -0
  150. zebra_day/templates/view_pstation_json.html +29 -0
  151. zebra_day/web/__init__.py +9 -0
  152. zebra_day/web/app.py +171 -0
  153. zebra_day/web/auth.py +172 -0
  154. zebra_day/web/middleware.py +159 -0
  155. zebra_day/web/routers/__init__.py +2 -0
  156. zebra_day/web/routers/api.py +163 -0
  157. zebra_day/web/routers/ui.py +1051 -0
  158. zebra_day/zpl_renderer.py +273 -0
  159. zebra_day-1.0.2.dist-info/METADATA +786 -0
  160. zebra_day-1.0.2.dist-info/RECORD +179 -0
  161. {zebra_day-0.0.32.dist-info → zebra_day-1.0.2.dist-info}/WHEEL +1 -1
  162. zebra_day-1.0.2.dist-info/entry_points.txt +4 -0
  163. zebra_day/etc/.blind +0 -1
  164. zebra_day/etc/current_style.txt +0 -1
  165. zebra_day/etc/label_styles/test_2inX1in.zpl +0 -22
  166. zebra_day/etc/label_styles/tmps/labware_2inX1in.na.2023-10-24_12:49:21.045127.zpl +0 -21
  167. zebra_day/etc/label_styles/tmps/labware_2inX1in.naggg.2023-10-24_16:02:04.704814.8888.2023-10-24_16:02:16.443911.zpl +0 -21
  168. zebra_day/etc/label_styles/tmps/labware_2inX1in.naggg.2023-10-24_16:02:04.704814.zpl +0 -21
  169. zebra_day/etc/label_styles/tmps/test_2inX1in.na.2023-10-24_12:45:37.002774.zpl +0 -22
  170. zebra_day/etc/old_printer_config/2023-10-24_16:06:06.931764_printer_config.json +0 -67
  171. zebra_day/etc/printer_config.json~ +0 -67
  172. zebra_day/files/tmp_2olihg4.png +0 -0
  173. zebra_day/files/tmpveojoyvn.png +0 -0
  174. zebra_day/files/zpl_label_labware_2inX1in_2023-10-25_02:30:08.093631.png +0 -0
  175. zebra_day/files/zpl_label_test_2inX1in_2023-10-24_15:54:29.343124.png +0 -0
  176. zebra_day/files/zpl_label_test_2inX1in_2023-10-24_16:01:45.670132.png +0 -0
  177. zebra_day/static/beyonce.css +0 -227
  178. zebra_day/static/datschund_on_moon.css +0 -164
  179. zebra_day/static/medicalsci.css +0 -144
  180. zebra_day/static/moar_zebra.css +0 -133
  181. zebra_day/static/popday.css +0 -140
  182. zebra_day/static/popday_dark.css +0 -140
  183. zebra_day/static/popday_dog.css +0 -140
  184. zebra_day-0.0.32.dist-info/METADATA +0 -14
  185. zebra_day-0.0.32.dist-info/RECORD +0 -53
  186. zebra_day-0.0.32.dist-info/entry_points.txt +0 -2
  187. /zebra_day/{etc/label_styles/blank_0inX0in.zpl → bin/__init__.py} +0 -0
  188. /zebra_day/etc/label_styles/{labware_2inX1in.zpl → generic_2inX1in.zpl} +0 -0
  189. {zebra_day-0.0.32.dist-info → zebra_day-1.0.2.dist-info/licenses}/LICENSE +0 -0
  190. {zebra_day-0.0.32.dist-info → zebra_day-1.0.2.dist-info}/top_level.txt +0 -0
@@ -7,15 +7,17 @@
7
7
 
8
8
  body {
9
9
  font-family: 'Monoid', monospace;
10
- background-color: #E6C79C; /* Light tan reminiscent of a dachshund's fur */
11
- color: #4B321F; /* Deep brown for text color, like a dachshund's coat */
10
+ background-color: #FFD700; /* Bold golden background reminiscent of Warhol's color palette */
11
+ color: #D91E63; /* Bold Pink text, Warhol-esque */
12
12
  margin: 0;
13
13
  padding: 20px;
14
+ background-image: linear-gradient(rgba(21, 2, 2, 0.99), rgba(55, 55, 55, 0.8)), url('./datschund.png');
15
+ background-repeat: repeat;
14
16
  }
15
17
 
16
18
  h1, h2 {
17
- color: #825C41; /* A deeper brown for headers */
18
- border-bottom: 2px dashed #4B321F; /* Dashed border to evoke the dachshund's playfulness */
19
+ color: rgb(222,221,222); /* Vibrant blue for headers */
20
+ border-bottom: 3px solid #2E86C1;
19
21
  padding-bottom: 5px;
20
22
  }
21
23
 
@@ -26,95 +28,113 @@ ul {
26
28
  }
27
29
 
28
30
  li::before {
29
- content: '\2022'; /* A simple dot as bullet */
30
- color: #825C41;
31
- font-weight: bold;
31
+ content: '';
32
32
  display: inline-block;
33
- margin-right: 10px;
34
- font-size: 1.5em;
35
- line-height: 0; /* Adjust for the bullet point */
33
+ width: 5px;
34
+ height: 5px;
35
+ border-radius: 50%;
36
+ background-color: #D91E63; /* Reusing bold pink color */
37
+ margin-right: 10px;
38
+ vertical-align: middle;
36
39
  }
37
40
 
38
41
  a {
39
- color: #825C41; /* Brown links for a coherent feel */
42
+ color: rgb(111,255,10); /* A deep green for links, contrast with the daylily theme */
40
43
  text-decoration: none;
41
44
  transition: color 0.3s ease;
42
45
  }
43
46
 
44
47
  a:hover {
45
- color: #4B321F; /* Darker shade of brown for hover */
48
+ color: #2E86C1; /* Vibrant blue on hover */
46
49
  }
47
50
 
48
51
  small {
49
- color: #A8977E; /* Lighter shade of brown for less prominent text */
52
+ color: rgba(221,1,211); /* Purple tint for smaller text, keeping with the vibrant palette */
50
53
  }
51
54
 
52
55
  .spinner-hidden {
53
- /* [No changes here] */
56
+ display: none;
57
+ position: fixed;
58
+ top: 0; left: 0; right: 0; bottom: 0;
59
+ background: rgba(255,215,0,0.7); /* Transparent golden background, keeping in theme */
60
+ z-index: 1000;
61
+ align-items: center;
62
+ justify-content: center;
63
+ display: flex;
54
64
  }
55
65
 
56
66
  #spinner {
57
- /* [No changes here] */
67
+ position: fixed;
68
+ top: 50%;
69
+ left: 50%;
70
+ transform: translate(-50%, -50%);
71
+ z-index: 9999;
58
72
  }
59
73
 
60
- .loader {
61
- /* Change the loader colors to match the theme */
62
- border: 8px solid #E6C79C;
63
- border-top: 8px solid #825C41;
74
+ .loader, .cloader {
75
+ border: 8px solid #7D3C98; /* Purple borders */
76
+ border-top: 8px solid #2E86C1; /* Blue on top to keep the spinning noticeable */
64
77
  border-radius: 50%;
65
78
  width: 50px;
66
79
  height: 50px;
67
80
  animation: spin 1s linear infinite;
68
81
  }
69
82
 
70
- .cloader {
71
- /* Change the cloader colors to match the theme */
72
- border: 16px solid #E6C79C;
73
- border-top: 16px solid #4B321F;
74
- border-radius: 50%;
75
- width: 50px;
76
- height: 50px;
77
- animation: spin 2s linear infinite;
78
- }
79
-
80
83
  @keyframes spin {
81
- /* [No changes here] */
84
+ 0% { transform: rotate(0deg); }
85
+ 100% { transform: rotate(360deg); }
82
86
  }
83
87
 
84
88
  hr {
85
89
  border: 0;
86
- height: 1px;
87
- background-image: linear-gradient(to right, #825C41, #E6C79C, #825C41); /* Gradient using the dachshund palette */
90
+ height: 2px;
91
+ background-image: linear-gradient(to right, #D91E63, #FFD700, #2E86C1);
88
92
  margin: 20px 0;
89
93
  }
90
94
 
91
95
  input[type=text], textarea, select {
92
- background-color: #F3E4D1; /* Slightly off-white for inputs */
93
- color: #4B321F;
94
- border: 2px solid #825C41;
95
- border-radius: 5px;
96
+ background-color: #FFFFFF; /* White background for input fields */
97
+ color: #D91E63; /* Pink text */
98
+ border: 2px solid #196F3D; /* Green border */
99
+ border-radius: 5px;
96
100
  padding: 5px 10px;
97
101
  outline: none;
98
102
  transition: background-color 0.3s ease;
99
103
  }
100
104
 
101
105
  input[type=text]:hover, textarea:hover, select:hover {
102
- background-color: #E6C79C;
106
+ background-color: #FFFAE5; /* A very light yellow for hover */
103
107
  }
104
108
 
105
109
  input[type=submit], button, input[type="button"] {
106
- background-color: #825C41;
107
- color: #E6C79C;
110
+ background-color: #D91E63; /* Pink buttons */
111
+ color: #FFFFFF; /* White text on buttons */
108
112
  border: none;
109
113
  border-radius: 5px;
110
- padding: 5px 10px;
114
+ padding: 8px 15px;
111
115
  cursor: pointer;
116
+ outline: none;
112
117
  transition: background-color 0.3s ease;
113
118
  }
114
119
 
115
120
  input[type=submit]:hover, button:hover, input[type="button"]:hover {
116
- background-color: #4B321F;
117
- color: #F3E4D1;
121
+ background-color: #E74C3C; /* Reddish hover effect */
118
122
  }
119
123
 
120
- /* Adjust other styles as needed */
124
+ textarea::-webkit-scrollbar {
125
+ width: 10px;
126
+ }
127
+
128
+ textarea::-webkit-scrollbar-thumb {
129
+ background-color: #2E86C1;
130
+ border-radius: 5px;
131
+ }
132
+
133
+ textarea::-webkit-scrollbar-track {
134
+ background-color: #FFD700; /* Golden background to keep in theme */
135
+ border-radius: 5px;
136
+ }
137
+
138
+ #spinner.spinner-hidden {
139
+ display: none;
140
+ }
Binary file
Binary file
@@ -0,0 +1,20 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
+ <!-- Background circle -->
3
+ <circle cx="16" cy="16" r="15" fill="#f5f5f5" stroke="#333" stroke-width="1"/>
4
+
5
+ <!-- Zebra stripes pattern -->
6
+ <g fill="#1a1a1a">
7
+ <!-- Diagonal stripes -->
8
+ <path d="M4 8 L8 4 L10 4 L4 10 Z"/>
9
+ <path d="M4 14 L14 4 L16 4 L4 16 Z"/>
10
+ <path d="M4 20 L20 4 L22 4 L4 22 Z"/>
11
+ <path d="M4 26 L26 4 L28 4 L6 28 L4 28 Z"/>
12
+ <path d="M10 28 L28 10 L28 12 L12 28 Z"/>
13
+ <path d="M16 28 L28 16 L28 18 L18 28 Z"/>
14
+ <path d="M22 28 L28 22 L28 24 L24 28 Z"/>
15
+ </g>
16
+
17
+ <!-- Z letter overlay -->
18
+ <text x="16" y="22" font-family="system-ui, -apple-system, sans-serif" font-size="16" font-weight="bold" fill="#6b46c1" text-anchor="middle">Z</text>
19
+ </svg>
20
+
@@ -0,0 +1,99 @@
1
+ @font-face {
2
+ font-family: 'Monoid';
3
+ src: url('/etc/Monoid-Regular-HalfTight-Dollar-0-1-l.ttf') format('truetype');
4
+ font-weight: normal;
5
+ font-style: normal;
6
+ }
7
+
8
+ body {
9
+ font-family: 'DejaVu Sans Mono', monospace;
10
+ }
11
+
12
+ :root {
13
+ --hrColor: #C400DB;
14
+ }
15
+
16
+ .hrTiny {
17
+ height: 1px;
18
+ background-color: var(--hrColor);
19
+ width:100%;
20
+ }
21
+
22
+ .hrSmall {
23
+ height: 2px;
24
+ background-color: var(--hrColor);
25
+ width:100%;
26
+ }
27
+
28
+ .hrMed {
29
+ height: 3px;
30
+ width: 100%;
31
+ background-color: var(--hrColor);
32
+ }
33
+
34
+
35
+ .hrLarge {
36
+ height: 4px;
37
+ background-color: var(--hrColor);
38
+ width:100%;
39
+ }
40
+
41
+ .hrVLarge {
42
+ height: 5px;
43
+ background-color: var(--hrColor);
44
+ width:100%;
45
+ }
46
+
47
+ h3 {
48
+ margin-bottom: auto;
49
+ }
50
+
51
+
52
+ .spinner-hidden {
53
+ display: none;
54
+ position: fixed;
55
+ top: 0; left: 0; right: 0; bottom: 0;
56
+ background: rgba(0,0,0,0.6);
57
+ z-index: 1000;
58
+ align-items: center;
59
+ justify-content: center;
60
+ display: flex;
61
+ }
62
+
63
+
64
+ #spinner.spinner-hidden {
65
+ display: none;
66
+ }
67
+
68
+
69
+ #spinner {
70
+ position: fixed;
71
+ top: 50%;
72
+ left: 50%;
73
+ transform: translate(-50%, -50%);
74
+ z-index: 9999;
75
+ }
76
+
77
+
78
+ .loader, .cloader {
79
+ border: 8px solid #7D3C98; /* Purple borders */
80
+ border-top: 8px solid #2E86C1; /* Blue on top to keep the spinning noticeable */
81
+ border-radius: 50%;
82
+ width: 50px;
83
+ height: 50px;
84
+ animation: spin 1s linear infinite;
85
+ }
86
+
87
+ @keyframes spin {
88
+ 0% { transform: rotate(0deg); }
89
+ 100% { transform: rotate(360deg); }
90
+ }
91
+
92
+ @keyframes spin {
93
+ 0% { transform: rotate(0deg); }
94
+ 100% { transform: rotate(360deg); }
95
+ }
96
+
97
+ #spinner.spinner-hidden {
98
+ display: none;
99
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Zebra Day Modern UI - JavaScript Utilities
3
+ */
4
+
5
+ // Global state
6
+ const ZebraDay = {
7
+ config: window.ZebraConfig || {},
8
+ toasts: [],
9
+ };
10
+
11
+ // DOM Ready
12
+ document.addEventListener('DOMContentLoaded', function() {
13
+ initMobileMenu();
14
+ initTooltips();
15
+ });
16
+
17
+ // Mobile Menu Toggle
18
+ function initMobileMenu() {
19
+ const menuToggle = document.getElementById('menu-toggle');
20
+ const navLinks = document.getElementById('nav-links');
21
+
22
+ if (menuToggle && navLinks) {
23
+ menuToggle.addEventListener('click', () => {
24
+ navLinks.classList.toggle('active');
25
+ });
26
+ }
27
+ }
28
+
29
+ // Tooltips
30
+ function initTooltips() {
31
+ document.querySelectorAll('[title]').forEach(el => {
32
+ el.addEventListener('mouseenter', showTooltip);
33
+ el.addEventListener('mouseleave', hideTooltip);
34
+ });
35
+ }
36
+
37
+ function showTooltip(e) {
38
+ const title = e.target.getAttribute('title');
39
+ if (!title) return;
40
+
41
+ e.target.setAttribute('data-title', title);
42
+ e.target.removeAttribute('title');
43
+
44
+ const tooltip = document.createElement('div');
45
+ tooltip.className = 'tooltip';
46
+ tooltip.textContent = title;
47
+ tooltip.style.cssText = `
48
+ position: fixed;
49
+ background: var(--color-gray-700, #1f1f1f);
50
+ color: white;
51
+ padding: 6px 10px;
52
+ border-radius: 6px;
53
+ font-size: 12px;
54
+ max-width: 280px;
55
+ z-index: 9999;
56
+ pointer-events: none;
57
+ `;
58
+
59
+ document.body.appendChild(tooltip);
60
+
61
+ const rect = e.target.getBoundingClientRect();
62
+ const margin = 8;
63
+ let left = rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2);
64
+ let top = rect.top - tooltip.offsetHeight - margin;
65
+
66
+ left = Math.max(margin, Math.min(left, window.innerWidth - tooltip.offsetWidth - margin));
67
+ if (top < margin) top = rect.bottom + margin;
68
+
69
+ tooltip.style.left = left + 'px';
70
+ tooltip.style.top = top + 'px';
71
+
72
+ e.target._tooltip = tooltip;
73
+ }
74
+
75
+ function hideTooltip(e) {
76
+ const title = e.target.getAttribute('data-title');
77
+ if (title) {
78
+ e.target.setAttribute('title', title);
79
+ e.target.removeAttribute('data-title');
80
+ }
81
+ if (e.target._tooltip) {
82
+ e.target._tooltip.remove();
83
+ delete e.target._tooltip;
84
+ }
85
+ }
86
+
87
+ // Toast Notifications
88
+ function showToast(type, title, message, duration = 5000) {
89
+ const container = document.getElementById('toast-container');
90
+ if (!container) return;
91
+
92
+ const icons = {
93
+ success: 'fa-check-circle',
94
+ error: 'fa-exclamation-circle',
95
+ warning: 'fa-exclamation-triangle',
96
+ info: 'fa-info-circle'
97
+ };
98
+
99
+ const toast = document.createElement('div');
100
+ toast.className = `toast toast-${type}`;
101
+ toast.innerHTML = `
102
+ <div class="toast-icon">
103
+ <i class="fas ${icons[type] || icons.info}"></i>
104
+ </div>
105
+ <div class="toast-content">
106
+ <div class="toast-title">${title}</div>
107
+ <div class="toast-message">${message}</div>
108
+ </div>
109
+ <button class="toast-close" onclick="this.parentElement.remove()">&times;</button>
110
+ `;
111
+
112
+ container.appendChild(toast);
113
+
114
+ if (duration > 0) {
115
+ setTimeout(() => toast.remove(), duration);
116
+ }
117
+
118
+ return toast;
119
+ }
120
+
121
+ // Loading Overlay
122
+ function showLoading(message = 'Loading...') {
123
+ const overlay = document.getElementById('loading-overlay');
124
+ if (overlay) {
125
+ const p = overlay.querySelector('p');
126
+ if (p) p.textContent = message;
127
+ overlay.classList.remove('d-none');
128
+ }
129
+ }
130
+
131
+ function hideLoading() {
132
+ const overlay = document.getElementById('loading-overlay');
133
+ if (overlay) {
134
+ overlay.classList.add('d-none');
135
+ }
136
+ }
137
+
138
+ // Copy to Clipboard
139
+ async function copyToClipboard(text) {
140
+ try {
141
+ await navigator.clipboard.writeText(text);
142
+ showToast('success', 'Copied!', 'Text copied to clipboard');
143
+ } catch (err) {
144
+ showToast('error', 'Copy Failed', 'Could not copy to clipboard');
145
+ }
146
+ }
147
+
148
+ // Format Date
149
+ function formatDate(dateString) {
150
+ const date = new Date(dateString);
151
+ return date.toLocaleDateString('en-US', {
152
+ year: 'numeric',
153
+ month: 'short',
154
+ day: 'numeric',
155
+ hour: '2-digit',
156
+ minute: '2-digit'
157
+ });
158
+ }
159
+
160
+ // Debounce
161
+ function debounce(func, wait) {
162
+ let timeout;
163
+ return function executedFunction(...args) {
164
+ const later = () => {
165
+ clearTimeout(timeout);
166
+ func(...args);
167
+ };
168
+ clearTimeout(timeout);
169
+ timeout = setTimeout(later, wait);
170
+ };
171
+ }
172
+