@dropi/ui-components 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/.gitignore +13 -0
  2. package/CONTRIBUTING.md +188 -0
  3. package/MIGRATION_STEPS.md +39 -0
  4. package/PUBLISH_CHECKLIST.md +97 -0
  5. package/QUICK_START.md +108 -0
  6. package/README.md +146 -0
  7. package/jest.config.ts +21 -0
  8. package/ng-package.json +8 -0
  9. package/package.json +66 -0
  10. package/project.json +48 -0
  11. package/publish.sh +113 -0
  12. package/src/components-source/accordion/accordion-item/accordion-item.component.html +12 -0
  13. package/src/components-source/accordion/accordion-item/accordion-item.component.scss +47 -0
  14. package/src/components-source/accordion/accordion-item/accordion-item.component.spec.ts +122 -0
  15. package/src/components-source/accordion/accordion-item/accordion-item.component.ts +42 -0
  16. package/src/components-source/accordion/accordion.component.html +3 -0
  17. package/src/components-source/accordion/accordion.component.scss +5 -0
  18. package/src/components-source/accordion/accordion.component.spec.ts +243 -0
  19. package/src/components-source/accordion/accordion.component.stories.ts +111 -0
  20. package/src/components-source/accordion/accordion.component.ts +43 -0
  21. package/src/components-source/alert/alert.component.html +28 -0
  22. package/src/components-source/alert/alert.component.scss +154 -0
  23. package/src/components-source/alert/alert.component.spec.ts +185 -0
  24. package/src/components-source/alert/alert.component.stories.ts +310 -0
  25. package/src/components-source/alert/alert.component.ts +203 -0
  26. package/src/components-source/alert-legacy/alert.component.html +21 -0
  27. package/src/components-source/alert-legacy/alert.component.scss +42 -0
  28. package/src/components-source/alert-legacy/alert.component.spec.ts +159 -0
  29. package/src/components-source/alert-legacy/alert.component.ts +33 -0
  30. package/src/components-source/alert-modal/alert-modal.component.html +124 -0
  31. package/src/components-source/alert-modal/alert-modal.component.scss +203 -0
  32. package/src/components-source/alert-modal/alert-modal.component.spec.ts +557 -0
  33. package/src/components-source/alert-modal/alert-modal.component.stories.ts +295 -0
  34. package/src/components-source/alert-modal/alert-modal.component.ts +294 -0
  35. package/src/components-source/alert-modal/services/template-alert-modal.service.ts +75 -0
  36. package/src/components-source/badge/badge.component.html +49 -0
  37. package/src/components-source/badge/badge.component.scss +57 -0
  38. package/src/components-source/badge/badge.component.spec.ts +181 -0
  39. package/src/components-source/badge/badge.component.ts +21 -0
  40. package/src/components-source/breadcrumb/breadcrumb.component.html +5 -0
  41. package/src/components-source/breadcrumb/breadcrumb.component.scss +46 -0
  42. package/src/components-source/breadcrumb/breadcrumb.component.spec.ts +279 -0
  43. package/src/components-source/breadcrumb/breadcrumb.component.ts +24 -0
  44. package/src/components-source/card-product/card-product.component.html +173 -0
  45. package/src/components-source/card-product/card-product.component.spec.ts +601 -0
  46. package/src/components-source/card-product/card-product.component.stories.ts +322 -0
  47. package/src/components-source/card-product/card-product.component.ts +1101 -0
  48. package/src/components-source/card-section/card-section.component.html +22 -0
  49. package/src/components-source/card-section/card-section.component.scss +14 -0
  50. package/src/components-source/card-section/card-section.component.spec.ts +333 -0
  51. package/src/components-source/card-section/card-section.component.stories.ts +141 -0
  52. package/src/components-source/card-section/card-section.component.ts +35 -0
  53. package/src/components-source/checkbox-selection-list/checkbox-selection-list.component.html +38 -0
  54. package/src/components-source/checkbox-selection-list/checkbox-selection-list.component.scss +147 -0
  55. package/src/components-source/checkbox-selection-list/checkbox-selection-list.component.spec.ts +555 -0
  56. package/src/components-source/checkbox-selection-list/checkbox-selection-list.component.stories.ts +157 -0
  57. package/src/components-source/checkbox-selection-list/checkbox-selection-list.component.ts +219 -0
  58. package/src/components-source/city-selector/city-selector.component.html +22 -0
  59. package/src/components-source/city-selector/city-selector.component.scss +1 -0
  60. package/src/components-source/city-selector/city-selector.component.spec.ts +278 -0
  61. package/src/components-source/city-selector/city-selector.component.stories.ts +200 -0
  62. package/src/components-source/city-selector/city-selector.component.ts +151 -0
  63. package/src/components-source/color-picker/color-picker.component.html +54 -0
  64. package/src/components-source/color-picker/color-picker.component.scss +203 -0
  65. package/src/components-source/color-picker/color-picker.component.spec.ts +148 -0
  66. package/src/components-source/color-picker/color-picker.component.stories.ts +70 -0
  67. package/src/components-source/color-picker/color-picker.component.ts +353 -0
  68. package/src/components-source/country-flags/country-flags.component.html +10 -0
  69. package/src/components-source/country-flags/country-flags.component.scss +34 -0
  70. package/src/components-source/country-flags/country-flags.component.spec.ts +78 -0
  71. package/src/components-source/country-flags/country-flags.component.ts +18 -0
  72. package/src/components-source/date-picker/date-picker.component.html +35 -0
  73. package/src/components-source/date-picker/date-picker.component.scss +388 -0
  74. package/src/components-source/date-picker/date-picker.component.spec.ts +510 -0
  75. package/src/components-source/date-picker/date-picker.component.stories.ts +444 -0
  76. package/src/components-source/date-picker/date-picker.component.ts +313 -0
  77. package/src/components-source/date-picker/date-picker.stories.spec.ts +150 -0
  78. package/src/components-source/date-picker-range/date-picker-range.component.html +45 -0
  79. package/src/components-source/date-picker-range/date-picker-range.component.scss +229 -0
  80. package/src/components-source/date-picker-range/date-picker-range.component.spec.ts +555 -0
  81. package/src/components-source/date-picker-range/date-picker-range.component.ts +254 -0
  82. package/src/components-source/dropi-avatars/dropi-avatars.component.html +17 -0
  83. package/src/components-source/dropi-avatars/dropi-avatars.component.scss +58 -0
  84. package/src/components-source/dropi-avatars/dropi-avatars.component.spec.ts +403 -0
  85. package/src/components-source/dropi-avatars/dropi-avatars.component.ts +24 -0
  86. package/src/components-source/dropi-badge/dropi-badge.component.html +12 -0
  87. package/src/components-source/dropi-badge/dropi-badge.component.scss +50 -0
  88. package/src/components-source/dropi-badge/dropi-badge.component.spec.ts +108 -0
  89. package/src/components-source/dropi-badge/dropi-badge.component.stories.ts +140 -0
  90. package/src/components-source/dropi-badge/dropi-badge.component.ts +39 -0
  91. package/src/components-source/dropi-banner-external/dropi-banner-external.component.html +67 -0
  92. package/src/components-source/dropi-banner-external/dropi-banner-external.component.scss +46 -0
  93. package/src/components-source/dropi-banner-external/dropi-banner-external.component.spec.ts +170 -0
  94. package/src/components-source/dropi-banner-external/dropi-banner-external.component.stories.ts +203 -0
  95. package/src/components-source/dropi-banner-external/dropi-banner-external.component.ts +204 -0
  96. package/src/components-source/dropi-breadcrumb/dropi-breadcrumb.component.html +65 -0
  97. package/src/components-source/dropi-breadcrumb/dropi-breadcrumb.component.scss +65 -0
  98. package/src/components-source/dropi-breadcrumb/dropi-breadcrumb.component.spec.ts +125 -0
  99. package/src/components-source/dropi-breadcrumb/dropi-breadcrumb.component.ts +38 -0
  100. package/src/components-source/dropi-breadcrumb/dropi-breadcrumb.stories.ts +133 -0
  101. package/src/components-source/dropi-button/dropi-button.component.html +37 -0
  102. package/src/components-source/dropi-button/dropi-button.component.scss +266 -0
  103. package/src/components-source/dropi-button/dropi-button.component.spec.ts +264 -0
  104. package/src/components-source/dropi-button/dropi-button.component.stories.ts +221 -0
  105. package/src/components-source/dropi-button/dropi-button.component.ts +82 -0
  106. package/src/components-source/dropi-card-checkbox/dropi-card-checkbox.component.html +24 -0
  107. package/src/components-source/dropi-card-checkbox/dropi-card-checkbox.component.scss +85 -0
  108. package/src/components-source/dropi-card-checkbox/dropi-card-checkbox.component.spec.ts +157 -0
  109. package/src/components-source/dropi-card-checkbox/dropi-card-checkbox.component.stories.ts +209 -0
  110. package/src/components-source/dropi-card-checkbox/dropi-card-checkbox.component.ts +41 -0
  111. package/src/components-source/dropi-carousel/dropi-carousel.component.html +57 -0
  112. package/src/components-source/dropi-carousel/dropi-carousel.component.scss +156 -0
  113. package/src/components-source/dropi-carousel/dropi-carousel.component.spec.ts +224 -0
  114. package/src/components-source/dropi-carousel/dropi-carousel.component.ts +266 -0
  115. package/src/components-source/dropi-carousel/dropi-carousel.stories.ts +365 -0
  116. package/src/components-source/dropi-checkbox/dropi-checkbox.component.css +39 -0
  117. package/src/components-source/dropi-checkbox/dropi-checkbox.component.html +18 -0
  118. package/src/components-source/dropi-checkbox/dropi-checkbox.component.spec.ts +155 -0
  119. package/src/components-source/dropi-checkbox/dropi-checkbox.component.stories.ts +101 -0
  120. package/src/components-source/dropi-checkbox/dropi-checkbox.component.ts +25 -0
  121. package/src/components-source/dropi-chips/dropi-chips.component.html +10 -0
  122. package/src/components-source/dropi-chips/dropi-chips.component.scss +54 -0
  123. package/src/components-source/dropi-chips/dropi-chips.component.spec.ts +356 -0
  124. package/src/components-source/dropi-chips/dropi-chips.component.stories.ts +275 -0
  125. package/src/components-source/dropi-chips/dropi-chips.component.ts +100 -0
  126. package/src/components-source/dropi-country-selector/countries.data.ts +239 -0
  127. package/src/components-source/dropi-country-selector/dropi-country-selector.component.html +59 -0
  128. package/src/components-source/dropi-country-selector/dropi-country-selector.component.scss +126 -0
  129. package/src/components-source/dropi-country-selector/dropi-country-selector.component.spec.ts +244 -0
  130. package/src/components-source/dropi-country-selector/dropi-country-selector.component.stories.ts +117 -0
  131. package/src/components-source/dropi-country-selector/dropi-country-selector.component.ts +179 -0
  132. package/src/components-source/dropi-drawer/dropi-drawer.component.html +23 -0
  133. package/src/components-source/dropi-drawer/dropi-drawer.component.scss +88 -0
  134. package/src/components-source/dropi-drawer/dropi-drawer.component.spec.ts +84 -0
  135. package/src/components-source/dropi-drawer/dropi-drawer.component.ts +90 -0
  136. package/src/components-source/dropi-dropdown/dropi-dropdown.component.html +30 -0
  137. package/src/components-source/dropi-dropdown/dropi-dropdown.component.scss +58 -0
  138. package/src/components-source/dropi-dropdown/dropi-dropdown.component.spec.ts +213 -0
  139. package/src/components-source/dropi-dropdown/dropi-dropdown.component.stories.ts +143 -0
  140. package/src/components-source/dropi-dropdown/dropi-dropdown.component.ts +53 -0
  141. package/src/components-source/dropi-favorite-button/dropi-favorite-button.component.html +23 -0
  142. package/src/components-source/dropi-favorite-button/dropi-favorite-button.component.scss +21 -0
  143. package/src/components-source/dropi-favorite-button/dropi-favorite-button.component.spec.ts +240 -0
  144. package/src/components-source/dropi-favorite-button/dropi-favorite-button.component.ts +31 -0
  145. package/src/components-source/dropi-file-upload/card-view/card-view.component.html +154 -0
  146. package/src/components-source/dropi-file-upload/card-view/card-view.component.scss +118 -0
  147. package/src/components-source/dropi-file-upload/card-view/card-view.component.ts +72 -0
  148. package/src/components-source/dropi-file-upload/drop-zone/drop-zone.coment.stories.ts +179 -0
  149. package/src/components-source/dropi-file-upload/drop-zone/drop-zone.component.html +111 -0
  150. package/src/components-source/dropi-file-upload/drop-zone/drop-zone.component.scss +90 -0
  151. package/src/components-source/dropi-file-upload/drop-zone/drop-zone.component.ts +172 -0
  152. package/src/components-source/dropi-file-upload/dropi-file-upload.component.html +42 -0
  153. package/src/components-source/dropi-file-upload/dropi-file-upload.component.scss +31 -0
  154. package/src/components-source/dropi-file-upload/dropi-file-upload.component.spec.ts +398 -0
  155. package/src/components-source/dropi-file-upload/dropi-file-upload.component.stories.ts +139 -0
  156. package/src/components-source/dropi-file-upload/dropi-file-upload.component.ts +329 -0
  157. package/src/components-source/dropi-file-upload/file-list/file-list.component.html +51 -0
  158. package/src/components-source/dropi-file-upload/file-list/file-list.component.scss +60 -0
  159. package/src/components-source/dropi-file-upload/file-list/file-list.component.ts +84 -0
  160. package/src/components-source/dropi-file-upload/grid-view/grid-view.component.html +77 -0
  161. package/src/components-source/dropi-file-upload/grid-view/grid-view.component.scss +85 -0
  162. package/src/components-source/dropi-file-upload/grid-view/grid-view.component.ts +35 -0
  163. package/src/components-source/dropi-ilustration-icon/dropi-ilustration-icon.component.html +38 -0
  164. package/src/components-source/dropi-ilustration-icon/dropi-ilustration-icon.component.scss +59 -0
  165. package/src/components-source/dropi-ilustration-icon/dropi-ilustration-icon.component.spec.ts +214 -0
  166. package/src/components-source/dropi-ilustration-icon/dropi-ilustration-icon.component.ts +65 -0
  167. package/src/components-source/dropi-image-overlay/dropi-image-overlay.component.html +54 -0
  168. package/src/components-source/dropi-image-overlay/dropi-image-overlay.component.scss +210 -0
  169. package/src/components-source/dropi-image-overlay/dropi-image-overlay.component.spec.ts +145 -0
  170. package/src/components-source/dropi-image-overlay/dropi-image-overlay.component.ts +76 -0
  171. package/src/components-source/dropi-image-overlay/dropi-image-overlay.stories.ts +267 -0
  172. package/src/components-source/dropi-languages-selector/dropi-languages-selector.component.html +17 -0
  173. package/src/components-source/dropi-languages-selector/dropi-languages-selector.component.scss +82 -0
  174. package/src/components-source/dropi-languages-selector/dropi-languages-selector.component.spec.ts +152 -0
  175. package/src/components-source/dropi-languages-selector/dropi-languages-selector.component.ts +41 -0
  176. package/src/components-source/dropi-logo/dropi-logo.component.html +3 -0
  177. package/src/components-source/dropi-logo/dropi-logo.component.scss +20 -0
  178. package/src/components-source/dropi-logo/dropi-logo.component.spec.ts +274 -0
  179. package/src/components-source/dropi-logo/dropi-logo.component.ts +24 -0
  180. package/src/components-source/dropi-modal/dropi-modal-stack.service.ts +75 -0
  181. package/src/components-source/dropi-modal/dropi-modal.component.html +55 -0
  182. package/src/components-source/dropi-modal/dropi-modal.component.scss +274 -0
  183. package/src/components-source/dropi-modal/dropi-modal.component.spec.ts +46 -0
  184. package/src/components-source/dropi-modal/dropi-modal.component.stories.ts +392 -0
  185. package/src/components-source/dropi-modal/dropi-modal.component.ts +392 -0
  186. package/src/components-source/dropi-modal/p-template.directive.ts +11 -0
  187. package/src/components-source/dropi-navbar/dropi-navbar.component.html +41 -0
  188. package/src/components-source/dropi-navbar/dropi-navbar.component.scss +227 -0
  189. package/src/components-source/dropi-navbar/dropi-navbar.component.spec.ts +110 -0
  190. package/src/components-source/dropi-navbar/dropi-navbar.component.ts +52 -0
  191. package/src/components-source/dropi-paginator/dropi-paginator.component.html +64 -0
  192. package/src/components-source/dropi-paginator/dropi-paginator.component.scss +43 -0
  193. package/src/components-source/dropi-paginator/dropi-paginator.component.spec.ts +285 -0
  194. package/src/components-source/dropi-paginator/dropi-paginator.component.stories.ts +345 -0
  195. package/src/components-source/dropi-paginator/dropi-paginator.component.ts +85 -0
  196. package/src/components-source/dropi-phone-input/dropi-phone-input.component.html +93 -0
  197. package/src/components-source/dropi-phone-input/dropi-phone-input.component.scss +224 -0
  198. package/src/components-source/dropi-phone-input/dropi-phone-input.component.spec.ts +376 -0
  199. package/src/components-source/dropi-phone-input/dropi-phone-input.component.ts +203 -0
  200. package/src/components-source/dropi-phone-input/numeric-input.directive.ts +17 -0
  201. package/src/components-source/dropi-radio-button/dropi-radio-button.component.html +8 -0
  202. package/src/components-source/dropi-radio-button/dropi-radio-button.component.scss +33 -0
  203. package/src/components-source/dropi-radio-button/dropi-radio-button.component.spec.ts +225 -0
  204. package/src/components-source/dropi-radio-button/dropi-radio-button.component.ts +48 -0
  205. package/src/components-source/dropi-search/dropi-search.component.html +124 -0
  206. package/src/components-source/dropi-search/dropi-search.component.scss +116 -0
  207. package/src/components-source/dropi-search/dropi-search.component.spec.ts +483 -0
  208. package/src/components-source/dropi-search/dropi-search.component.stories.ts +267 -0
  209. package/src/components-source/dropi-search/dropi-search.component.ts +230 -0
  210. package/src/components-source/dropi-select/dropi-select.component.html +158 -0
  211. package/src/components-source/dropi-select/dropi-select.component.scss +275 -0
  212. package/src/components-source/dropi-select/dropi-select.component.spec.ts +386 -0
  213. package/src/components-source/dropi-select/dropi-select.component.stories.ts +686 -0
  214. package/src/components-source/dropi-select/dropi-select.component.ts +465 -0
  215. package/src/components-source/dropi-skeleton/dropi-skeleton.component.html +10 -0
  216. package/src/components-source/dropi-skeleton/dropi-skeleton.component.scss +28 -0
  217. package/src/components-source/dropi-skeleton/dropi-skeleton.component.spec.ts +273 -0
  218. package/src/components-source/dropi-skeleton/dropi-skeleton.component.stories.ts +145 -0
  219. package/src/components-source/dropi-skeleton/dropi-skeleton.component.ts +30 -0
  220. package/src/components-source/dropi-steps/dropi-steps.component.html +29 -0
  221. package/src/components-source/dropi-steps/dropi-steps.component.scss +110 -0
  222. package/src/components-source/dropi-steps/dropi-steps.component.spec.ts +228 -0
  223. package/src/components-source/dropi-steps/dropi-steps.component.stories.ts +231 -0
  224. package/src/components-source/dropi-steps/dropi-steps.component.ts +98 -0
  225. package/src/components-source/dropi-switch/dropi-switch.component.html +4 -0
  226. package/src/components-source/dropi-switch/dropi-switch.component.scss +50 -0
  227. package/src/components-source/dropi-switch/dropi-switch.component.spec.ts +105 -0
  228. package/src/components-source/dropi-switch/dropi-switch.component.stories.ts +106 -0
  229. package/src/components-source/dropi-switch/dropi-switch.component.ts +22 -0
  230. package/src/components-source/dropi-table/dropi-table.component.html +395 -0
  231. package/src/components-source/dropi-table/dropi-table.component.scss +506 -0
  232. package/src/components-source/dropi-table/dropi-table.component.spec.ts +578 -0
  233. package/src/components-source/dropi-table/dropi-table.component.stories.ts +313 -0
  234. package/src/components-source/dropi-table/dropi-table.component.ts +580 -0
  235. package/src/components-source/dropi-tag/dropi-tag.component.html +17 -0
  236. package/src/components-source/dropi-tag/dropi-tag.component.scss +50 -0
  237. package/src/components-source/dropi-tag/dropi-tag.component.spec.ts +267 -0
  238. package/src/components-source/dropi-tag/dropi-tag.component.stories.ts +290 -0
  239. package/src/components-source/dropi-tag/dropi-tag.component.ts +92 -0
  240. package/src/components-source/dropi-text-area/droip-text-area.component.stories.ts +138 -0
  241. package/src/components-source/dropi-text-area/dropi-text-area.component.html +63 -0
  242. package/src/components-source/dropi-text-area/dropi-text-area.component.scss +106 -0
  243. package/src/components-source/dropi-text-area/dropi-text-area.component.spec.ts +507 -0
  244. package/src/components-source/dropi-text-area/dropi-text-area.component.ts +80 -0
  245. package/src/components-source/dropi-tooltip/dropi-tooltip.component.html +70 -0
  246. package/src/components-source/dropi-tooltip/dropi-tooltip.component.scss +250 -0
  247. package/src/components-source/dropi-tooltip/dropi-tooltip.component.spec.ts +423 -0
  248. package/src/components-source/dropi-tooltip/dropi-tooltip.component.ts +153 -0
  249. package/src/components-source/dropi-youtube-lazy-video/dropi-youtube-lazy-video.component.html +20 -0
  250. package/src/components-source/dropi-youtube-lazy-video/dropi-youtube-lazy-video.component.scss +63 -0
  251. package/src/components-source/dropi-youtube-lazy-video/dropi-youtube-lazy-video.component.spec.ts +121 -0
  252. package/src/components-source/dropi-youtube-lazy-video/dropi-youtube-lazy-video.component.ts +43 -0
  253. package/src/components-source/dropi-youtube-lazy-video/dropi-youtube-lazy-video.stories.ts +125 -0
  254. package/src/components-source/empty-state/empty-state.component.html +30 -0
  255. package/src/components-source/empty-state/empty-state.component.scss +76 -0
  256. package/src/components-source/empty-state/empty-state.component.spec.ts +244 -0
  257. package/src/components-source/empty-state/empty-state.component.stories.ts +198 -0
  258. package/src/components-source/empty-state/empty-state.component.ts +34 -0
  259. package/src/components-source/file-upload-progress-bar/file-upload-progress-bar.component.html +81 -0
  260. package/src/components-source/file-upload-progress-bar/file-upload-progress-bar.component.scss +86 -0
  261. package/src/components-source/file-upload-progress-bar/file-upload-progress-bar.component.spec.ts +27 -0
  262. package/src/components-source/file-upload-progress-bar/file-upload-progress-bar.component.stories.ts +149 -0
  263. package/src/components-source/file-upload-progress-bar/file-upload-progress-bar.component.ts +89 -0
  264. package/src/components-source/foundations/dropi-border-radius-demo/dropi-border-radius-demo.component.scss +32 -0
  265. package/src/components-source/foundations/dropi-border-radius-demo/dropi-border-radius-demo.component.ts +17 -0
  266. package/src/components-source/foundations/foundations.component.html +183 -0
  267. package/src/components-source/foundations/foundations.component.scss +31 -0
  268. package/src/components-source/foundations/foundations.component.ts +26 -0
  269. package/src/components-source/icon/icon-names.const.ts +270 -0
  270. package/src/components-source/icon/icon.component.html +3 -0
  271. package/src/components-source/icon/icon.component.scss +4 -0
  272. package/src/components-source/icon/icon.component.spec.ts +304 -0
  273. package/src/components-source/icon/icon.component.ts +53 -0
  274. package/src/components-source/index.ts +89 -0
  275. package/src/components-source/input/input.component.html +97 -0
  276. package/src/components-source/input/input.component.scss +149 -0
  277. package/src/components-source/input/input.component.spec.ts +243 -0
  278. package/src/components-source/input/input.component.stories.ts +269 -0
  279. package/src/components-source/input/input.component.ts +119 -0
  280. package/src/components-source/lottie-loader/lottie-loader.component.html +16 -0
  281. package/src/components-source/lottie-loader/lottie-loader.component.scss +32 -0
  282. package/src/components-source/lottie-loader/lottie-loader.component.spec.ts +103 -0
  283. package/src/components-source/lottie-loader/lottie-loader.component.ts +20 -0
  284. package/src/components-source/otp-send-code/mock-otp-services.ts +214 -0
  285. package/src/components-source/otp-send-code/otp-send-code.component.html +151 -0
  286. package/src/components-source/otp-send-code/otp-send-code.component.scss +156 -0
  287. package/src/components-source/otp-send-code/otp-send-code.component.spec.ts +419 -0
  288. package/src/components-source/otp-send-code/otp-send-code.component.stories.ts +190 -0
  289. package/src/components-source/otp-send-code/otp-send-code.component.ts +659 -0
  290. package/src/components-source/radio-selection-list/radio-selection-list.component.html +107 -0
  291. package/src/components-source/radio-selection-list/radio-selection-list.component.scss +280 -0
  292. package/src/components-source/radio-selection-list/radio-selection-list.component.spec.ts +243 -0
  293. package/src/components-source/radio-selection-list/radio-selection-list.component.stories.ts +313 -0
  294. package/src/components-source/radio-selection-list/radio-selection-list.component.ts +143 -0
  295. package/src/components-source/read-more/read-more.component.html +14 -0
  296. package/src/components-source/read-more/read-more.component.scss +16 -0
  297. package/src/components-source/read-more/read-more.component.spec.ts +272 -0
  298. package/src/components-source/read-more/read-more.component.stories.ts +131 -0
  299. package/src/components-source/read-more/read-more.component.ts +88 -0
  300. package/src/components-source/sidebar/sidebar.component.html +42 -0
  301. package/src/components-source/sidebar/sidebar.component.scss +70 -0
  302. package/src/components-source/sidebar/sidebar.component.spec.ts +354 -0
  303. package/src/components-source/sidebar/sidebar.component.stories.ts +145 -0
  304. package/src/components-source/sidebar/sidebar.component.ts +105 -0
  305. package/src/components-source/simple-stepper/simple-stepper.component.html +17 -0
  306. package/src/components-source/simple-stepper/simple-stepper.component.scss +117 -0
  307. package/src/components-source/simple-stepper/simple-stepper.component.spec.ts +348 -0
  308. package/src/components-source/simple-stepper/simple-stepper.component.stories.ts +104 -0
  309. package/src/components-source/simple-stepper/simple-stepper.component.ts +69 -0
  310. package/src/components-source/storybook-doc-components/avatars-storybook/avatars-storybook.component.html +192 -0
  311. package/src/components-source/storybook-doc-components/avatars-storybook/avatars-storybook.component.scss +15 -0
  312. package/src/components-source/storybook-doc-components/avatars-storybook/avatars-storybook.component.ts +17 -0
  313. package/src/components-source/storybook-doc-components/border-radius-storybook/border-radius-storybook.component.html +22 -0
  314. package/src/components-source/storybook-doc-components/border-radius-storybook/border-radius-storybook.component.scss +0 -0
  315. package/src/components-source/storybook-doc-components/border-radius-storybook/border-radius-storybook.component.ts +54 -0
  316. package/src/components-source/storybook-doc-components/breakpoints-and-grids-storybook/breakpoints-and-grids-storybook.component.css +81 -0
  317. package/src/components-source/storybook-doc-components/breakpoints-and-grids-storybook/breakpoints-and-grids-storybook.component.html +143 -0
  318. package/src/components-source/storybook-doc-components/breakpoints-and-grids-storybook/breakpoints-and-grids-storybook.component.ts +97 -0
  319. package/src/components-source/storybook-doc-components/colors-storybook/colors-storybook.component.css +10 -0
  320. package/src/components-source/storybook-doc-components/colors-storybook/colors-storybook.component.html +63 -0
  321. package/src/components-source/storybook-doc-components/colors-storybook/colors-storybook.component.ts +542 -0
  322. package/src/components-source/storybook-doc-components/dropi-modal/dropi-modal.component.html +132 -0
  323. package/src/components-source/storybook-doc-components/dropi-modal/dropi-modal.component.scss +15 -0
  324. package/src/components-source/storybook-doc-components/dropi-modal/dropi-modal.component.ts +67 -0
  325. package/src/components-source/storybook-doc-components/dropi-toast/dropi-toast.component.html +156 -0
  326. package/src/components-source/storybook-doc-components/dropi-toast/dropi-toast.component.scss +13 -0
  327. package/src/components-source/storybook-doc-components/dropi-toast/dropi-toast.component.ts +55 -0
  328. package/src/components-source/storybook-doc-components/flags-storybook/flags-storybook.component.css +0 -0
  329. package/src/components-source/storybook-doc-components/flags-storybook/flags-storybook.component.html +99 -0
  330. package/src/components-source/storybook-doc-components/flags-storybook/flags-storybook.component.ts +19 -0
  331. package/src/components-source/storybook-doc-components/icons-storybook/icons-storybook.component.css +82 -0
  332. package/src/components-source/storybook-doc-components/icons-storybook/icons-storybook.component.html +111 -0
  333. package/src/components-source/storybook-doc-components/icons-storybook/icons-storybook.component.ts +196 -0
  334. package/src/components-source/storybook-doc-components/logo-storybook/logo-foundations.component.ts +19 -0
  335. package/src/components-source/storybook-doc-components/logo-storybook/logo-storybook.component.css +0 -0
  336. package/src/components-source/storybook-doc-components/logo-storybook/logo-storybook.component.html +104 -0
  337. package/src/components-source/storybook-doc-components/lustration-storybook/lustration-storybook.component.css +0 -0
  338. package/src/components-source/storybook-doc-components/lustration-storybook/lustration-storybook.component.html +218 -0
  339. package/src/components-source/storybook-doc-components/lustration-storybook/lustration-storybook.component.ts +20 -0
  340. package/src/components-source/storybook-doc-components/shadow-storybook/shadow-storybook.component.html +21 -0
  341. package/src/components-source/storybook-doc-components/shadow-storybook/shadow-storybook.component.scss +0 -0
  342. package/src/components-source/storybook-doc-components/shadow-storybook/shadow-storybook.component.ts +66 -0
  343. package/src/components-source/storybook-doc-components/spacing-storybook/spacing-storybook.component.html +33 -0
  344. package/src/components-source/storybook-doc-components/spacing-storybook/spacing-storybook.component.scss +0 -0
  345. package/src/components-source/storybook-doc-components/spacing-storybook/spacing-storybook.component.ts +37 -0
  346. package/src/components-source/storybook-doc-components/story-page/story-page.component.html +74 -0
  347. package/src/components-source/storybook-doc-components/story-page/story-page.component.scss +103 -0
  348. package/src/components-source/storybook-doc-components/story-page/story-page.component.ts +424 -0
  349. package/src/components-source/storybook-doc-components/template-breakpoint-storybook/template-breakpoint-storybook.component.html +35 -0
  350. package/src/components-source/storybook-doc-components/template-breakpoint-storybook/template-breakpoint-storybook.component.scss +64 -0
  351. package/src/components-source/storybook-doc-components/template-breakpoint-storybook/template-breakpoint-storybook.component.ts +71 -0
  352. package/src/components-source/storybook-doc-components/tillte-table-documentation/tillte-table-documentation.component.html +44 -0
  353. package/src/components-source/storybook-doc-components/tillte-table-documentation/tillte-table-documentation.component.scss +270 -0
  354. package/src/components-source/storybook-doc-components/tillte-table-documentation/tillte-table-documentation.component.ts +153 -0
  355. package/src/components-source/tabs/tabs.component.html +26 -0
  356. package/src/components-source/tabs/tabs.component.scss +62 -0
  357. package/src/components-source/tabs/tabs.component.spec.ts +212 -0
  358. package/src/components-source/tabs/tabs.component.stories.ts +203 -0
  359. package/src/components-source/tabs/tabs.component.ts +138 -0
  360. package/src/components-source/tag-type-product/tag-type-product.component.html +1 -0
  361. package/src/components-source/tag-type-product/tag-type-product.component.scss +10 -0
  362. package/src/components-source/tag-type-product/tag-type-product.component.spec.ts +38 -0
  363. package/src/components-source/tag-type-product/tag-type-product.component.ts +9 -0
  364. package/src/components-source/toast/toast.component.html +37 -0
  365. package/src/components-source/toast/toast.component.scss +142 -0
  366. package/src/components-source/toast/toast.component.spec.ts +368 -0
  367. package/src/components-source/toast/toast.component.ts +59 -0
  368. package/src/components-source/toast/toast.stories.ts +69 -0
  369. package/src/components-source/tooltip/tooltip.component.html +46 -0
  370. package/src/components-source/tooltip/tooltip.component.scss +44 -0
  371. package/src/components-source/tooltip/tooltip.component.spec.ts +327 -0
  372. package/src/components-source/tooltip/tooltip.component.ts +24 -0
  373. package/src/components-source/ui-dropi.module.ts +125 -0
  374. package/src/components-source/ui-inventory.json +1138 -0
  375. package/src/components-source/vertical-steps/vertical-steps.component.html +35 -0
  376. package/src/components-source/vertical-steps/vertical-steps.component.scss +143 -0
  377. package/src/components-source/vertical-steps/vertical-steps.component.spec.ts +121 -0
  378. package/src/components-source/vertical-steps/vertical-steps.component.stories.ts +216 -0
  379. package/src/components-source/vertical-steps/vertical-steps.component.ts +151 -0
  380. package/src/index.ts +31 -0
  381. package/src/lib/bootstrap.ts +28 -0
  382. package/src/lib/dropi-ui-elements/dropi-ui-elements.component.html +1 -0
  383. package/src/lib/dropi-ui-elements/dropi-ui-elements.component.scss +0 -0
  384. package/src/lib/dropi-ui-elements/dropi-ui-elements.component.spec.ts +21 -0
  385. package/src/lib/dropi-ui-elements/dropi-ui-elements.component.ts +9 -0
  386. package/src/lib/elements-registry.ts +66 -0
  387. package/src/lib/elements.module.ts +22 -0
  388. package/src/styles.scss +152 -0
  389. package/src/test-setup.ts +6 -0
  390. package/tsconfig.json +28 -0
  391. package/tsconfig.lib.json +18 -0
  392. package/tsconfig.lib.prod.json +9 -0
  393. package/tsconfig.spec.json +12 -0
@@ -0,0 +1,1101 @@
1
+ import {
2
+ Component,
3
+ Input,
4
+ Output,
5
+ EventEmitter,
6
+ OnInit,
7
+ SimpleChanges,
8
+ HostListener,
9
+ } from '@angular/core';
10
+ import { CommonModule, TitleCasePipe } from '@angular/common';
11
+ import { IconComponent } from '../icon/icon.component';
12
+ import { DropiTagComponent } from '../dropi-tag/dropi-tag.component';
13
+ import { CurrencyComponent } from '../../components/currency/currency.component';
14
+ import { environment } from '../../../environments/environment';
15
+ import { SettingsService } from '../../services/setting.service';
16
+ import { AdjustNamePipe } from '@app/pipe/product/adjust-name.pipe';
17
+ import { Howl } from 'howler';
18
+ import { ProductstService } from '@app/pages/service/products/products.service';
19
+ import { OrderManualService } from '@app/services/order-manual.service';
20
+ import { Router } from '@angular/router';
21
+ import { BetaTagComponent } from '@app/components/beta-tag/beta-tag.component';
22
+ import { DropiIlustrationIconComponent } from '../dropi-ilustration-icon/dropi-ilustration-icon.component';
23
+ import { TranslateModule } from '@ngx-translate/core';
24
+
25
+ export interface ProductData {
26
+ id: string | number;
27
+ sku?: string;
28
+ name: string;
29
+ type?: string;
30
+ sale_price: number;
31
+ suggested_price: number;
32
+ private_product: boolean;
33
+ variation_stock?: number;
34
+ stock_simple: number;
35
+ is_variation: boolean;
36
+ favorite: boolean;
37
+ supplier: {
38
+ id: number;
39
+ name: string;
40
+ category_user: string;
41
+ icon?: 'verified' | 'premium' | 'exclusive';
42
+ };
43
+ categories: Array<{
44
+ name: string;
45
+ }>;
46
+ private_user_stock?: number;
47
+ legacy_img?: boolean;
48
+ image: string;
49
+ // Campos opcionales para mantener compatibilidad
50
+ category?: string;
51
+ stock?: number;
52
+ supplierPrice?: number;
53
+ suggestedPrice?: number;
54
+ imageUrl?: string;
55
+ isFavorite?: boolean;
56
+ }
57
+
58
+ export type CardState = 'default' | 'hover' | 'select';
59
+
60
+ @Component({
61
+ selector: 'dropi-card-product',
62
+ standalone: true,
63
+ imports: [
64
+ CommonModule,
65
+ IconComponent,
66
+ DropiTagComponent,
67
+ CurrencyComponent,
68
+ TitleCasePipe,
69
+ AdjustNamePipe,
70
+ BetaTagComponent,
71
+ DropiIlustrationIconComponent,
72
+ TranslateModule
73
+ ],
74
+ templateUrl: './card-product.component.html',
75
+ })
76
+ export class CardProductComponent implements OnInit {
77
+ @Input() product!: ProductData;
78
+ @Input() state: CardState = 'default';
79
+ @Input() aS: boolean = true; // Nuevo input para controlar elementos anti-scraping
80
+ @Input() bettaTester: boolean = false;
81
+ @Output() onAddToCart = new EventEmitter<ProductData>();
82
+ @Output() onProductClick = new EventEmitter<ProductData>();
83
+ @Output() changeFavorite = new EventEmitter<Boolean>();
84
+
85
+ public imageError = false;
86
+ public brandName: string = '';
87
+ public onFavoriteHover = false; // Nueva propiedad para manejar el hover del favorito
88
+
89
+ // Propiedades para almacenar las clases aleatorias generadas una sola vez
90
+ public randomClasses = {
91
+ card: '',
92
+ imageContainer: '',
93
+ image: '',
94
+ tags: '',
95
+ tagsRow: '',
96
+ favoriteButton: '',
97
+ productInfo: '',
98
+ productHeader: '',
99
+ category: '',
100
+ stockInfo: '',
101
+ stockLabel: '',
102
+ stockValue: '',
103
+ productName: '',
104
+ supplierInfo: '',
105
+ supplierLabel: '',
106
+ supplierName: '',
107
+ priceContainer: '',
108
+ priceItem: '',
109
+ priceLabel: '',
110
+ priceValue: '',
111
+ separator: '',
112
+ actionButton: '',
113
+ buttonText: '',
114
+ };
115
+
116
+ // Propiedades para almacenar los arrays anti-scraping generados una sola vez
117
+ public mixedData = {
118
+ stockDivs: [] as Array<{ value: number; class: string; isReal: boolean }>,
119
+ supplierPriceDivs: [] as Array<{ value: number; class: string; isReal: boolean }>,
120
+ suggestedPriceDivs: [] as Array<{ value: number; class: string; isReal: boolean }>,
121
+ };
122
+
123
+ // Propiedades para almacenar los estilos falsos generados una sola vez
124
+ public fakeStyles = {
125
+ stock: '',
126
+ price: '',
127
+ };
128
+
129
+ // Nueva propiedad para detectar si es móvil
130
+ public isMobile: boolean = false;
131
+
132
+ constructor(
133
+ private settingService: SettingsService,
134
+ private favoriteService: ProductstService,
135
+ private orderManual: OrderManualService,
136
+ private router: Router,
137
+ ) {}
138
+
139
+ ngOnInit() {
140
+ this.brandName = this.settingService.getBrandInfo()?.name?.toLowerCase() || 'dropi';
141
+ this.generateRandomClasses();
142
+ this.generateFakeStyles();
143
+ this.generateMixedData();
144
+ this.checkScreenSize(); // Verificar tamaño de pantalla al inicializar
145
+ }
146
+
147
+ ngOnChanges(changes: SimpleChanges) {
148
+ // Regenerar los datos mezclados cuando cambie el producto o aS
149
+ if (changes['product'] || changes['aS']) {
150
+ this.generateMixedData();
151
+ }
152
+ }
153
+
154
+ // Listener para detectar cambios en el tamaño de pantalla
155
+ @HostListener('window:resize', ['$event'])
156
+ onResize(event: any) {
157
+ this.checkScreenSize();
158
+ }
159
+
160
+ // Método para verificar si es móvil
161
+ private checkScreenSize() {
162
+ this.isMobile = window.innerWidth <= 420;
163
+ }
164
+
165
+ // Método para generar todas las clases aleatorias una sola vez
166
+ private generateRandomClasses() {
167
+ this.randomClasses = {
168
+ card: this.generateRandomClass('dropi-card-product'),
169
+ imageContainer: this.generateRandomClass('product-image-container'),
170
+ image: this.generateRandomClass('product-image'),
171
+ tags: this.generateRandomClass('product-tags'),
172
+ tagsRow: this.generateRandomClass('tags-row'),
173
+ favoriteButton: this.generateRandomClass('favorite-button'),
174
+ productInfo: this.generateRandomClass('product-info'),
175
+ productHeader: this.generateRandomClass('product-header'),
176
+ category: this.generateRandomClass('category'),
177
+ stockInfo: this.generateRandomClass('stock-info'),
178
+ stockLabel: this.generateRandomClass('stock-label'),
179
+ stockValue: this.generateRandomClass('stock-value'),
180
+ productName: this.generateRandomClass('product-name'),
181
+ supplierInfo: this.generateRandomClass('supplier-info'),
182
+ supplierLabel: this.generateRandomClass('supplier-label'),
183
+ supplierName: this.generateRandomClass('supplier-name'),
184
+ priceContainer: this.generateRandomClass('price-container'),
185
+ priceItem: this.generateRandomClass('price-item'),
186
+ priceLabel: this.generateRandomClass('price-label'),
187
+ priceValue: this.generateRandomClass('price-value'),
188
+ separator: this.generateRandomClass('separator'),
189
+ actionButton: this.generateRandomClass('action-button'),
190
+ buttonText: this.generateRandomClass('button-text'),
191
+ };
192
+ }
193
+
194
+ // Método para generar todos los arrays anti-scraping una sola vez
195
+ private generateMixedData() {
196
+ this.mixedData.stockDivs = this.generateMixedStockDivs();
197
+ this.mixedData.supplierPriceDivs = this.generateMixedSupplierPriceDivs();
198
+ this.mixedData.suggestedPriceDivs = this.generateMixedSuggestedPriceDivs();
199
+ }
200
+
201
+ // Método para generar todos los estilos falsos una sola vez
202
+ private generateFakeStyles() {
203
+ this.fakeStyles.stock = this.generateFakeStyleVariant();
204
+ this.fakeStyles.price = this.generateFakeStyleVariant();
205
+ }
206
+
207
+ get imageUrl(): string | undefined {
208
+ // Si el producto tiene el campo 'image' directamente (nueva estructura)
209
+ if (this.product && this.product.image) {
210
+ // Si legacy_img es true, usar img_server, de lo contrario usar S3
211
+ if (this.product.legacy_img === true) {
212
+ return `${environment.img_server}/${this.product.image}`;
213
+ } else {
214
+ return `${environment.AWS3.cloudfront_server}/${this.product.image}`;
215
+ }
216
+ }
217
+
218
+ // Fallback: mantener compatibilidad con imageUrl directo
219
+ if (this.product && this.product.imageUrl) {
220
+ return this.product.imageUrl;
221
+ }
222
+
223
+ return undefined;
224
+ }
225
+
226
+ onError(event: any) {
227
+ this.imageError = true;
228
+ if (this.brandName === 'dropi') {
229
+ event.target.src = './assets/utils/no-image.jpg';
230
+ } else {
231
+ event.target.src = './assets/utils/wb-no-image.jpg';
232
+ }
233
+ }
234
+
235
+ get productTags(): Array<{
236
+ text: string;
237
+ type: 'primary' | 'secondary';
238
+ state: 'default' | 'warning' | 'info';
239
+ showIcon?: boolean;
240
+ icon?: string;
241
+ }> {
242
+ const tags = [];
243
+
244
+ if (this.product?.type?.includes('variable')) {
245
+ tags.push({ text: 'Variable', type: 'primary' as const, state: 'default' as const });
246
+ }
247
+
248
+ if (this.product?.type?.includes('privado')) {
249
+ tags.push({
250
+ text: null,
251
+ type: 'primary' as const,
252
+ state: 'warning' as const,
253
+ showIcon: true,
254
+ icon: 'Lock',
255
+ });
256
+ }
257
+
258
+ if (this.product?.type?.includes('combo')) {
259
+ tags.push({ text: 'Combo', type: 'primary' as const, state: 'info' as const });
260
+ }
261
+
262
+ return tags;
263
+ }
264
+
265
+ // Método para obtener el stock correcto según el tipo de producto
266
+ private getProductStock(): number {
267
+ if (this.product?.type === 'VARIABLE' && this.product?.is_variation) {
268
+ return this.product?.variation_stock || 0;
269
+ }
270
+ return this.product?.stock_simple || 0;
271
+ }
272
+
273
+ get stockStatus(): 'success' | 'warning' | 'error' {
274
+ const stock = this.getProductStock();
275
+ if (stock === 0) return 'error';
276
+ if (stock <= 10) return 'warning';
277
+ return 'success';
278
+ }
279
+
280
+ get stockStatusClass(): string {
281
+ switch (this.stockStatus) {
282
+ case 'success':
283
+ return 'stock-success';
284
+ case 'warning':
285
+ return 'stock-warning';
286
+ case 'error':
287
+ return 'stock-error';
288
+ default:
289
+ return 'stock-success';
290
+ }
291
+ }
292
+
293
+ handleAddToCart(): void {
294
+ const stock = this.getProductStock();
295
+ if (stock > 0) {
296
+ this.onAddToCart.emit(this.product);
297
+ let productId = Number(this.product.id);
298
+ this.orderManual.setModalOpen(true);
299
+ this.orderManual.clearProductsIds();
300
+ this.orderManual.setProductsIds(productId);
301
+ }
302
+ }
303
+
304
+ handleFavoriteToggle(): void {
305
+ // Cambiar el estado favorito internamente usando suscripción en addFavoriteProduct de ProductstService
306
+ if (!this.product || !this.product.id) {
307
+ console.error('Product or product ID is not defined');
308
+ return;
309
+ }
310
+ let body = {
311
+ product_id: this.product.id,
312
+ };
313
+
314
+ if (!this.product.favorite) {
315
+ console.log('Adding product to favorites:', this.product.id);
316
+ this.favoriteService.addFavoriteProduct(body).subscribe({
317
+ next: (response: any) => {
318
+ console.log('Favorite toggled successfully:', response);
319
+ if (response?.is_successful) {
320
+ this.product.favorite = true;
321
+ this.playAudio();
322
+ // Emitir evento de cambio de favorito
323
+ this.changeFavorite.emit(true);
324
+ }
325
+ },
326
+ error: (error) => {
327
+ console.error('Error toggling favorite:', error);
328
+ },
329
+ });
330
+ } else {
331
+ this.favoriteService.removeFavoriteProduct(body).subscribe({
332
+ next: (response: any) => {
333
+ console.log('Favorite removed successfully:', response);
334
+ if (response?.is_successful) {
335
+ this.product.favorite = false;
336
+ this.playAudio();
337
+ // Emitir evento de cambio de favorito
338
+ this.changeFavorite.emit(false);
339
+ }
340
+ },
341
+ error: (error) => {
342
+ console.error('Error removing favorite:', error);
343
+ },
344
+ });
345
+ }
346
+ }
347
+
348
+ // Método para obtener el color del icono favorito con hover
349
+ getFavoriteIconColor(): string {
350
+ if (this.product?.favorite) {
351
+ return '#fff'; // Blanco cuando es favorito
352
+ }
353
+ return this.onFavoriteHover ? '#f49a3d' : '#858ea6'; // Naranja en hover, gris normal
354
+ }
355
+
356
+ playAudio() {
357
+ let sound = new Howl({
358
+ src: ['assets/audio/pop.mp3'],
359
+ });
360
+ sound.volume(0.4);
361
+ sound.play();
362
+ }
363
+
364
+ getProductDetails(): void {
365
+ // if (this.noClick) {
366
+ // return;
367
+ // }
368
+ let nameProductUrl = this.product.name;
369
+
370
+ if (!nameProductUrl || typeof nameProductUrl !== 'string') {
371
+ nameProductUrl = 'producto'; // Fallback por defecto
372
+ } else {
373
+ const cleanName = nameProductUrl
374
+ .normalize('NFD') // Normaliza a Unicode con descomposición
375
+ .replace(/[\u0300-\u036f]/g, '') // Elimina las marcas diacríticas
376
+ .replace(/[\u{1F600}-\u{1F64F}]/gu, '') // Elimina emoticonos
377
+ .replace(/[\u{1F300}-\u{1F5FF}]/gu, '') // Elimina símbolos y pictogramas misceláneos
378
+ .replace(/[\u{1F680}-\u{1F6FF}]/gu, '') // Elimina símbolos de transporte y mapas
379
+ .replace(/[\u{1F700}-\u{1F77F}]/gu, '') // Elimina símbolos alquímicos
380
+ .replace(/[\u{2600}-\u{26FF}]/gu, '') // Elimina símbolos misceláneos
381
+ .replace(/[\u{2700}-\u{27BF}]/gu, '') // Elimina Dingbats
382
+ .replace(/[\/\\]/g, '') // Elimina barras que pueden afectar URLs
383
+ .replace(/[&%#?]/g, '') // Elimina caracteres problemáticos para URLs
384
+ .replace(/[<>"\[\]{}|^`]/g, '') // Elimina caracteres no permitidos en URLs
385
+ .replace(/[^a-zA-Z0-9\süÜñÑ]/g, '') // Elimina los caracteres especiales excepto ü, Ü, ñ, Ñ
386
+ .replace(/\s+/g, '-') // Reemplaza espacios en blanco con guiones
387
+ .replace(/-+/g, '-') // Reemplaza múltiples guiones consecutivos por uno solo
388
+ .replace(/^-+|-+$/g, '') // Elimina guiones al principio o al final
389
+ .toLowerCase() // Convierte a minúsculas
390
+ .substring(0, 100); // Limita la longitud para evitar URLs muy largas
391
+
392
+ // Verificar que el resultado no esté vacío después de la limpieza
393
+ nameProductUrl = cleanName || 'producto';
394
+ }
395
+
396
+ const url = `/dashboard/product-details/${this.product.id}/${nameProductUrl}`;
397
+
398
+ // Abre la URL en una nueva ventana
399
+ window.open(url, '_blank');
400
+ }
401
+
402
+ getProvidersDetails(): void {
403
+ console.log('getProvidersDetails called');
404
+
405
+ const cleanName = this.product?.supplier?.name
406
+ .normalize('NFD') // Normaliza a Unicode con descomposición
407
+ .replace(/[\u0300-\u036f]/g, '') // Elimina las marcas diacríticas
408
+ .replace(/[\u{1F600}-\u{1F64F}]/gu, '') // Elimina emoticonos
409
+ .replace(/[\u{1F300}-\u{1F5FF}]/gu, '') // Elimina símbolos y pictogramas misceláneos
410
+ .replace(/[\u{1F680}-\u{1F6FF}]/gu, '') // Elimina símbolos de transporte y mapas
411
+ .replace(/[\u{1F700}-\u{1F77F}]/gu, '') // Elimina símbolos alquímicos
412
+ .replace(/[\u{2600}-\u{26FF}]/gu, '') // Elimina símbolos misceláneos
413
+ .replace(/[\u{2700}-\u{27BF}]/gu, '') // Elimina Dingbats
414
+ .replace(/[\/\\]/g, '') // Elimina barras que pueden afectar URLs
415
+ .replace(/[&%#?]/g, '') // Elimina caracteres problemáticos para URLs
416
+ .replace(/[<>"\[\]{}|^`]/g, '') // Elimina caracteres no permitidos en URLs
417
+ .replace(/[^a-zA-Z0-9\süÜñÑ]/g, '') // Elimina los caracteres especiales excepto ü, Ü, ñ, Ñ
418
+ .replace(/\s+/g, '-') // Reemplaza espacios en blanco con guiones
419
+ .replace(/-+/g, '-') // Reemplaza múltiples guiones consecutivos por uno solo
420
+ .replace(/^-+|-+$/g, '') // Elimina guiones al principio o al final
421
+ .toLowerCase() // Convierte a minúsculas
422
+ .substring(0, 100); // Limita la longitud para evitar URLs muy largas
423
+
424
+ // solo si esta en este path dashboard/search abrir en una nueva ventana
425
+ if (this.router.url === '/dashboard/search') {
426
+ const url = `/dashboard/provider/${this.product.supplier.id}/${cleanName}`;
427
+ window.open(url, '_blank');
428
+ return;
429
+ } else {
430
+ this.router.navigate(['/dashboard/provider', this.product.supplier.id, cleanName]);
431
+ }
432
+ }
433
+
434
+ hasStock(): boolean {
435
+ const stock = this.getProductStock();
436
+ return stock > 0;
437
+ }
438
+
439
+ // Métodos para estilos inline
440
+ getCardStyles(): string {
441
+ const baseStyles = `
442
+ position: relative;
443
+ background: #ffffff;
444
+ border-radius: 8px;
445
+ overflow: hidden;
446
+ transition: all 0.2s ease-in-out;
447
+ cursor: pointer;
448
+ display: flex;
449
+ flex-direction: column;
450
+ height: 100%;
451
+ box-sizing: border-box;
452
+ width: 100%;
453
+ max-width: 450px;
454
+ `;
455
+
456
+ let stateStyles = '';
457
+ switch (this.state) {
458
+ case 'hover':
459
+ stateStyles =
460
+ 'box-shadow: 0.5px 4px 8px 0px rgba(0, 0, 0, 0.08); transform: scale(1.02) translateY(-2px);';
461
+ break;
462
+ case 'select':
463
+ stateStyles = 'border: 1px solid #f49a3d;';
464
+ break;
465
+ default:
466
+ stateStyles = 'box-shadow: none;';
467
+ }
468
+
469
+ return baseStyles + stateStyles;
470
+ }
471
+
472
+ getRandomProviderCategoryStyles(): string {
473
+ // Retorna una clase aleatoria para la categoría del proveedor
474
+ return `
475
+ top: -20px;
476
+ left: 2px;
477
+ position: absolute;
478
+ `;
479
+ }
480
+
481
+ getImageContainerStyles(): string {
482
+ return `
483
+ padding: 4px;
484
+ flex-shrink: 0;
485
+ `;
486
+ }
487
+
488
+ getImageStyles(): string {
489
+ return `
490
+ position: relative;
491
+ width: 100%;
492
+ aspect-ratio: 1;
493
+ border-radius: 8px;
494
+ border: 1px solid #c3c9d9;
495
+ overflow: hidden;
496
+ display: flex;
497
+ align-items: center;
498
+ justify-content: center;
499
+ background-color: #f8f9fa;
500
+ `;
501
+ }
502
+
503
+ getTagsContainerStyles(): string {
504
+ return `
505
+ position: absolute;
506
+ top: 8px;
507
+ left: 8px;
508
+ display: flex;
509
+ flex-direction: column;
510
+ gap: 6px;
511
+ z-index: 2;
512
+ `;
513
+ }
514
+
515
+ getTagsRowStyles(): string {
516
+ return `
517
+ display: flex;
518
+ gap: 5px;
519
+ `;
520
+ }
521
+
522
+ getFavoriteButtonStyles(): string {
523
+ const baseStyles = `
524
+ position: absolute;
525
+ bottom: 5px;
526
+ right: 6px;
527
+ border-radius: 8px;
528
+ padding: 12px;
529
+ cursor: pointer;
530
+ transition: all 0.2s ease-in-out;
531
+ z-index: 2;
532
+ display: flex;
533
+ align-items: center;
534
+ justify-content: center;
535
+ width: 40px;
536
+ height: 40px;
537
+ `;
538
+
539
+ // Estilos específicos según si es favorito o no
540
+ const favoriteStyles = this.product?.favorite
541
+ ? `
542
+ background: var(--Primary-Primary-500, #f49a3d);
543
+ border: 1px solid var(--Primary-Primary-500, #f49a3d);
544
+ `
545
+ : `
546
+ background: #ffffff;
547
+ border: 1px solid #858ea6;
548
+ `;
549
+
550
+ return baseStyles + favoriteStyles;
551
+ }
552
+
553
+ getProductInfoStyles(): string {
554
+ return `
555
+ position: relative;
556
+ padding: 8px;
557
+ display: flex;
558
+ flex-direction: column;
559
+ gap: 4px;
560
+ flex: 1;
561
+ justify-content: space-between;
562
+ `;
563
+ }
564
+
565
+ getProductHeaderStyles(): string {
566
+ return `
567
+ display: flex;
568
+ justify-content: space-between;
569
+ align-items: center;
570
+ width: 100%;
571
+ height: 26px;
572
+ `;
573
+ }
574
+
575
+ getCategoryStyles(): string {
576
+ return `
577
+ color: #69738c;
578
+ font-family: 'Inter', sans-serif;
579
+ font-size: 12px;
580
+ font-weight: 400;
581
+ line-height: 1.5;
582
+ flex: 1;
583
+ `;
584
+ }
585
+
586
+ getStockInfoStyles(): string {
587
+ return `
588
+ display: flex;
589
+ align-items: center;
590
+ gap: 2px;
591
+ font-family: 'Inter', sans-serif;
592
+ font-size: 12px;
593
+ font-weight: 400;
594
+ line-height: 1.5;
595
+ `;
596
+ }
597
+
598
+ getStockLabelStyles(): string {
599
+ return `
600
+ color: #69738c;
601
+ `;
602
+ }
603
+
604
+ getStockValueStyles(): string {
605
+ const stock = this.getProductStock();
606
+ let color = '#0abb87'; // success
607
+ if (stock === 0) {
608
+ color = '#ef4444'; // error
609
+ } else if (stock <= 10) {
610
+ color = '#f59e0b'; // warning
611
+ }
612
+
613
+ return `
614
+ font-weight: 500;
615
+ color: ${color};
616
+ `;
617
+ }
618
+
619
+ getProductNameStyles(): string {
620
+ return `
621
+ color: #32394d;
622
+ font-family: 'Inter', sans-serif;
623
+ font-size: 16px;
624
+ font-weight: 500;
625
+ line-height: 1.5;
626
+ margin: 0;
627
+ overflow: hidden;
628
+ text-overflow: ellipsis;
629
+ display: -webkit-box;
630
+ -webkit-line-clamp: 2;
631
+ -webkit-box-orient: vertical;
632
+ `;
633
+ }
634
+
635
+ getSupplierInfoStyles(): string {
636
+ return `
637
+ font-family: 'Inter', sans-serif;
638
+ font-size: 12px;
639
+ line-height: 1.2;
640
+ `;
641
+ }
642
+
643
+ getSupplierLabelStyles(): string {
644
+ return `
645
+ color: #69738c;
646
+ font-weight: 400;
647
+ `;
648
+ }
649
+
650
+ getSupplierNameStyles(): string {
651
+ return `
652
+ color: #50a5f1;
653
+ font-weight: 400;
654
+ margin-left: 4px;
655
+ `;
656
+ }
657
+
658
+ getPriceContainerStyles(): string {
659
+ return `
660
+ display: flex;
661
+ gap: 8px;
662
+ margin-top: 4px;
663
+ `;
664
+ }
665
+
666
+ getPriceItemStyles(): string {
667
+ return `
668
+ flex: 1;
669
+ display: flex;
670
+ flex-direction: column;
671
+ `;
672
+ }
673
+
674
+ getPriceLabelStyles(): string {
675
+ const baseStyles = `
676
+ color: #69738c;
677
+ font-family: 'Inter', sans-serif;
678
+ font-size: 12px;
679
+ font-weight: 400;
680
+ line-height: 1.5;
681
+ `;
682
+
683
+ // Estilos condicionales basados en el tamaño de pantalla
684
+ const responsiveStyles = this.isMobile
685
+ ? `
686
+ height: auto;
687
+ min-width: auto;
688
+ margin-bottom: 6px;
689
+ `
690
+ : `
691
+ height: 18px;
692
+ min-width: max-content;
693
+ `;
694
+
695
+ return baseStyles + responsiveStyles;
696
+ }
697
+
698
+ getPriceValueStyles(): string {
699
+ return `
700
+ color: #32394d;
701
+ font-family: 'Inter', sans-serif;
702
+ font-size: 14px;
703
+ font-weight: 700;
704
+ line-height: 1.1;
705
+ margin-top: 2px;
706
+ `;
707
+ }
708
+
709
+ getSeparatorStyles(): string {
710
+ return `
711
+ height: 1px;
712
+ background: #e6eaf2;
713
+ margin: 0;
714
+ flex-shrink: 0;
715
+ `;
716
+ }
717
+
718
+ getActionButtonStyles(): string {
719
+ const stock = this.getProductStock();
720
+ const baseStyles = `
721
+ background: #ffffff;
722
+ border: none;
723
+ border-top: 1px solid #e6eaf2;
724
+ padding: 12px;
725
+ cursor: pointer;
726
+ transition: all 0.2s ease-in-out;
727
+ display: flex;
728
+ align-items: center;
729
+ justify-content: center;
730
+ gap: 8px;
731
+ height: 40px;
732
+ flex-shrink: 0;
733
+ `;
734
+
735
+ const disabledStyles = stock === 0 ? 'opacity: 0.3; cursor: not-allowed;' : '';
736
+
737
+ return baseStyles + disabledStyles;
738
+ }
739
+
740
+ getButtonTextStyles(): string {
741
+ return `
742
+ font-family: 'Inter', sans-serif;
743
+ font-size: 14px;
744
+ font-weight: 700;
745
+ line-height: 1.1;
746
+ color: #f49a3d;
747
+ text-align: center;
748
+ white-space: nowrap;
749
+ `;
750
+ }
751
+
752
+ // Métodos para generar clases aleatorias
753
+ private generateRandomClass(baseName: string): string {
754
+ const randomPrefix = Math.random().toString(36).substring(2, 8);
755
+ const randomSuffix = Math.random().toString(36).substring(2, 8);
756
+ return `${randomPrefix}-${baseName}-${randomSuffix}`;
757
+ }
758
+
759
+ // Métodos para obtener las clases aleatorias (ahora retornan valores fijos)
760
+ getRandomCardClass(): string {
761
+ return this.randomClasses.card;
762
+ }
763
+
764
+ getRandomImageContainerClass(): string {
765
+ return this.randomClasses.imageContainer;
766
+ }
767
+
768
+ getRandomImageClass(): string {
769
+ return this.randomClasses.image;
770
+ }
771
+
772
+ getRandomTagsClass(): string {
773
+ return this.randomClasses.tags;
774
+ }
775
+
776
+ getRandomTagsRowClass(): string {
777
+ return this.randomClasses.tagsRow;
778
+ }
779
+
780
+ getRandomFavoriteButtonClass(): string {
781
+ return this.randomClasses.favoriteButton;
782
+ }
783
+
784
+ getRandomProductInfoClass(): string {
785
+ return this.randomClasses.productInfo;
786
+ }
787
+
788
+ getRandomProductHeaderClass(): string {
789
+ return this.randomClasses.productHeader;
790
+ }
791
+
792
+ getRandomCategoryClass(): string {
793
+ return this.randomClasses.category;
794
+ }
795
+
796
+ getRandomStockInfoClass(): string {
797
+ return this.randomClasses.stockInfo;
798
+ }
799
+
800
+ getRandomStockLabelClass(): string {
801
+ return this.randomClasses.stockLabel;
802
+ }
803
+
804
+ getRandomStockValueClass(): string {
805
+ return this.randomClasses.stockValue;
806
+ }
807
+
808
+ getRandomProductNameClass(): string {
809
+ return this.randomClasses.productName;
810
+ }
811
+
812
+ getRandomSupplierInfoClass(): string {
813
+ return this.randomClasses.supplierInfo;
814
+ }
815
+
816
+ getRandomSupplierLabelClass(): string {
817
+ return this.randomClasses.supplierLabel;
818
+ }
819
+
820
+ getRandomSupplierNameClass(): string {
821
+ return this.randomClasses.supplierName;
822
+ }
823
+
824
+ getRandomPriceContainerClass(): string {
825
+ return this.randomClasses.priceContainer;
826
+ }
827
+
828
+ getRandomPriceItemClass(): string {
829
+ return this.randomClasses.priceItem;
830
+ }
831
+
832
+ getRandomPriceLabelClass(): string {
833
+ return this.randomClasses.priceLabel;
834
+ }
835
+
836
+ getRandomPriceValueClass(): string {
837
+ return this.randomClasses.priceValue;
838
+ }
839
+
840
+ getRandomSeparatorClass(): string {
841
+ return this.randomClasses.separator;
842
+ }
843
+
844
+ getRandomActionButtonClass(): string {
845
+ return this.randomClasses.actionButton;
846
+ }
847
+
848
+ getRandomButtonTextClass(): string {
849
+ return this.randomClasses.buttonText;
850
+ }
851
+
852
+ // Métodos para generar stock falso
853
+ private generateFakeStockCalculations(): number[] {
854
+ const realStock = this.getProductStock(); // Usar el método que determina el stock correcto
855
+
856
+ // 1. MEJORA: Cantidad variable de elementos falsos (3-8)
857
+ const fakeCount = Math.floor(Math.random() * 6) + 3; // 3-8 elementos
858
+ const variations = [];
859
+
860
+ for (let i = 0; i < fakeCount; i++) {
861
+ let fakeValue;
862
+ switch (i % 6) {
863
+ case 0:
864
+ fakeValue = Math.floor(realStock * (0.8 + Math.random() * 0.4)); // ±20% variación
865
+ break;
866
+ case 1:
867
+ fakeValue = Math.floor(realStock + (Math.random() * 10 - 5)); // ±5 unidades aleatorias
868
+ break;
869
+ case 2:
870
+ fakeValue = Math.floor(realStock * (1 + Math.random() * 0.3)); // +30% máximo
871
+ break;
872
+ case 3:
873
+ fakeValue = Math.floor(realStock * (0.9 + Math.random() * 0.2)); // ±10% variación
874
+ break;
875
+ case 4:
876
+ fakeValue = Math.floor(realStock + (Math.random() * 20 - 10)); // ±10 unidades aleatorias
877
+ break;
878
+ case 5:
879
+ fakeValue = Math.floor(realStock * (1 + Math.random() * 0.5)); // +50% máximo
880
+ break;
881
+ default:
882
+ fakeValue = Math.floor(realStock * (0.85 + Math.random() * 0.3)); // Variación adicional
883
+ }
884
+ variations.push(fakeValue);
885
+ }
886
+
887
+ // Asegurar que no haya valores negativos
888
+ return variations.map((value) => Math.max(0, value));
889
+ }
890
+
891
+ getFakeStockDivs(): Array<{ value: number; class: string }> {
892
+ const fakeStocks = this.generateFakeStockCalculations();
893
+ return fakeStocks.map((stock) => ({
894
+ value: stock,
895
+ class: this.generateRandomClass('stock-value'),
896
+ }));
897
+ }
898
+
899
+ // Método para obtener todos los stocks mezclados (real + falsos) - ahora retorna valores almacenados
900
+ getMixedStockDivs(): Array<{ value: number; class: string; isReal: boolean }> {
901
+ return this.mixedData.stockDivs;
902
+ }
903
+
904
+ // Método para generar todos los stocks mezclados una sola vez
905
+ private generateMixedStockDivs(): Array<{ value: number; class: string; isReal: boolean }> {
906
+ const realStock = {
907
+ value: this.getProductStock(), // Usar el método que determina el stock correcto
908
+ class: this.getRandomStockValueClass(),
909
+ isReal: true,
910
+ };
911
+
912
+ // Solo agregar elementos falsos si aS está activado
913
+ if (!this.aS) {
914
+ return [realStock];
915
+ }
916
+
917
+ const fakeStocks = this.getFakeStockDivs().map((fake) => ({
918
+ ...fake,
919
+ isReal: false,
920
+ }));
921
+
922
+ // Combinar real + falsos y mezclar aleatoriamente
923
+ const allStocks = [realStock, ...fakeStocks];
924
+
925
+ // Algoritmo Fisher-Yates para mezclar aleatoriamente
926
+ for (let i = allStocks.length - 1; i > 0; i--) {
927
+ const j = Math.floor(Math.random() * (i + 1));
928
+ [allStocks[i], allStocks[j]] = [allStocks[j], allStocks[i]];
929
+ }
930
+
931
+ return allStocks;
932
+ }
933
+
934
+ // Métodos para generar precios falsos
935
+ private generateFakePriceCalculations(realPrice: number): number[] {
936
+ // Detectar el patrón de redondeo del precio real
937
+ const roundingPattern = this.detectPriceRounding(realPrice);
938
+
939
+ const variations = [
940
+ realPrice * (0.85 + Math.random() * 0.3), // ±15% variación
941
+ realPrice + (Math.random() * 10000 - 5000), // ±5000 pesos aleatorios
942
+ realPrice * (1 + Math.random() * 0.25), // +25% máximo
943
+ realPrice * (0.9 + Math.random() * 0.2), // ±10% variación
944
+ realPrice + (Math.random() * 20000 - 10000), // ±10000 pesos aleatorios
945
+ realPrice * (1 + Math.random() * 0.4), // +40% máximo
946
+ ];
947
+
948
+ // Aplicar el mismo patrón de redondeo y asegurar valores mínimos
949
+ return variations.map((value) => {
950
+ const roundedValue = this.roundToPattern(Math.max(1000, value), roundingPattern);
951
+ return Math.floor(roundedValue);
952
+ });
953
+ }
954
+
955
+ // Detectar el patrón de redondeo del precio real
956
+ private detectPriceRounding(price: number): number {
957
+ const lastThreeDigits = price % 1000;
958
+
959
+ if (lastThreeDigits === 0) return 1000; // Termina en .000
960
+ if (lastThreeDigits === 500) return 500; // Termina en .500
961
+ if (price % 100 === 0) return 100; // Termina en .00
962
+ if (price % 50 === 0) return 50; // Termina en .50
963
+ if (price % 10 === 0) return 10; // Termina en .0
964
+
965
+ return 1; // Sin patrón específico
966
+ }
967
+
968
+ // Redondear un valor según el patrón detectado
969
+ private roundToPattern(value: number, pattern: number): number {
970
+ return Math.round(value / pattern) * pattern;
971
+ }
972
+
973
+ getFakePriceDivs(
974
+ realPrice: number,
975
+ priceType: 'supplier' | 'suggested',
976
+ ): Array<{ value: number; class: string }> {
977
+ const fakePrices = this.generateFakePriceCalculations(realPrice);
978
+ return fakePrices.map((price) => ({
979
+ value: price,
980
+ class: this.generateRandomClass(`price-value`),
981
+ }));
982
+ }
983
+
984
+ // Método para obtener precios de proveedor mezclados (real + falsos) - ahora retorna valores almacenados
985
+ getMixedSupplierPriceDivs(): Array<{ value: number; class: string; isReal: boolean }> {
986
+ return this.mixedData.supplierPriceDivs;
987
+ }
988
+
989
+ // Método para generar precios de proveedor mezclados una sola vez
990
+ private generateMixedSupplierPriceDivs(): Array<{
991
+ value: number;
992
+ class: string;
993
+ isReal: boolean;
994
+ }> {
995
+ const realPrice = {
996
+ value: this.product?.sale_price || 0,
997
+ class: this.getRandomPriceValueClass(),
998
+ isReal: true,
999
+ };
1000
+
1001
+ // Solo agregar elementos falsos si aS está activado
1002
+ if (!this.aS) {
1003
+ return [realPrice];
1004
+ }
1005
+
1006
+ const fakePrices = this.getFakePriceDivs(this.product?.sale_price || 0, 'supplier').map(
1007
+ (fake) => ({
1008
+ ...fake,
1009
+ isReal: false,
1010
+ }),
1011
+ );
1012
+
1013
+ // Combinar real + falsos y mezclar aleatoriamente
1014
+ const allPrices = [realPrice, ...fakePrices];
1015
+
1016
+ // Algoritmo Fisher-Yates para mezclar aleatoriamente
1017
+ for (let i = allPrices.length - 1; i > 0; i--) {
1018
+ const j = Math.floor(Math.random() * (i + 1));
1019
+ [allPrices[i], allPrices[j]] = [allPrices[j], allPrices[i]];
1020
+ }
1021
+
1022
+ return allPrices;
1023
+ }
1024
+
1025
+ // Método para obtener precios sugeridos mezclados (real + falsos) - ahora retorna valores almacenados
1026
+ getMixedSuggestedPriceDivs(): Array<{ value: number; class: string; isReal: boolean }> {
1027
+ return this.mixedData.suggestedPriceDivs;
1028
+ }
1029
+
1030
+ // Método para generar precios sugeridos mezclados una sola vez
1031
+ private generateMixedSuggestedPriceDivs(): Array<{
1032
+ value: number;
1033
+ class: string;
1034
+ isReal: boolean;
1035
+ }> {
1036
+ const realPrice = {
1037
+ value: this.product?.suggested_price || 0,
1038
+ class: this.getRandomPriceValueClass(),
1039
+ isReal: true,
1040
+ };
1041
+
1042
+ // Solo agregar elementos falsos si aS está activado
1043
+ if (!this.aS) {
1044
+ return [realPrice];
1045
+ }
1046
+
1047
+ const fakePrices = this.getFakePriceDivs(this.product?.suggested_price || 0, 'suggested').map(
1048
+ (fake) => ({
1049
+ ...fake,
1050
+ isReal: false,
1051
+ }),
1052
+ );
1053
+
1054
+ // Combinar real + falsos y mezclar aleatoriamente
1055
+ const allPrices = [realPrice, ...fakePrices];
1056
+
1057
+ // Algoritmo Fisher-Yates para mezclar aleatoriamente
1058
+ for (let i = allPrices.length - 1; i > 0; i--) {
1059
+ const j = Math.floor(Math.random() * (i + 1));
1060
+ [allPrices[i], allPrices[j]] = [allPrices[j], allPrices[i]];
1061
+ }
1062
+
1063
+ return allPrices;
1064
+ }
1065
+
1066
+ // 2. MEJORA: Técnicas de ocultación variadas para elementos falsos
1067
+ private generateFakeStyleVariant(): string {
1068
+ const variants = [
1069
+ // Variante 1: Ocultación clásica
1070
+ `display: none !important;`,
1071
+
1072
+ // Variante 2: Posicionamiento fuera de pantalla
1073
+ `position: absolute !important; left: -9999px !important; top: -9999px !important; z-index: -1 !important;`,
1074
+
1075
+ // Variante 3: Invisibilidad con dimensiones zero
1076
+ `visibility: hidden !important; height: 0 !important; width: 0 !important; overflow: hidden !important;`,
1077
+
1078
+ // Variante 4: Opacidad zero con eventos deshabilitados
1079
+ `opacity: 0 !important; pointer-events: none !important; position: absolute !important;`,
1080
+
1081
+ // Variante 5: Fixed positioning fuera de pantalla
1082
+ `position: fixed !important; top: -100vh !important; left: -100vw !important; z-index: -999 !important;`,
1083
+
1084
+ // Variante 6: Clip path para ocultar
1085
+ `clip-path: polygon(0 0, 0 0, 0 0) !important; position: absolute !important;`,
1086
+
1087
+ // Variante 7: Transform scale(0)
1088
+ `transform: scale(0) !important; position: absolute !important; overflow: hidden !important;`,
1089
+ ];
1090
+
1091
+ return variants[Math.floor(Math.random() * variants.length)];
1092
+ }
1093
+
1094
+ getFakePriceStyles(): string {
1095
+ return this.fakeStyles.price;
1096
+ }
1097
+
1098
+ getFakeStockStyles(): string {
1099
+ return this.fakeStyles.stock;
1100
+ }
1101
+ }