@hhgtech/hhg-components 1.29.88 → 1.29.90

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 (463) hide show
  1. package/build/{LastPeriod-235fc10e.js → LastPeriod-5e6d2274.js} +1 -1
  2. package/build/MobileBottomNavigationIcon-3103ca02.js +193 -0
  3. package/build/{WhatsApp-e6406d8d.js → WhatsApp-21d7b616.js} +1 -1
  4. package/build/adapters.js +18 -16
  5. package/build/atoms.js +47 -45
  6. package/build/babyGrowth.js +82 -80
  7. package/build/cache.js +2 -2
  8. package/build/care.js +28 -25
  9. package/build/careBookingSearchBar.js +1594 -0
  10. package/build/careBookingSearchBarV2.js +1665 -0
  11. package/build/components/molecules/popup/index.d.ts +2 -1
  12. package/build/components.js +125 -115
  13. package/build/{constants-2d046b25.js → constants-8abd9991.js} +1 -1
  14. package/build/constants.js +3 -3
  15. package/build/constantsDomainLocales.js +1 -1
  16. package/build/constantsRiskScreener.js +2 -2
  17. package/build/constantsSite.js +2 -2
  18. package/build/{core-ab09e68b.js → core-e12ff855.js} +1 -1
  19. package/build/{dataTransform-945e5f4f.js → dataTransform-27a22c74.js} +1 -1
  20. package/build/ecom.js +4 -4
  21. package/build/editor-e761dc49.js +986 -0
  22. package/build/embeddedHeathToolCards_babyGrowth.js +22 -20
  23. package/build/embeddedHeathToolCards_babyPoop.js +18 -16
  24. package/build/embeddedHeathToolCards_babyVaccine.js +21 -19
  25. package/build/embeddedHeathToolCards_bmi_bmi.js +25 -23
  26. package/build/embeddedHeathToolCards_bmrBmr.js +25 -23
  27. package/build/embeddedHeathToolCards_dueDate_dueDate.js +21 -19
  28. package/build/embeddedHeathToolCards_ovulation_ovulation.js +21 -19
  29. package/build/embeddedHeathToolCards_pwg_pwg.js +26 -24
  30. package/build/embeddedHeathToolCards_targetHeartRate.js +27 -25
  31. package/build/esm/{LastPeriod-fcd2b5ec.js → LastPeriod-cd2e1a56.js} +1 -1
  32. package/build/esm/MobileBottomNavigationIcon-cfcb7894.js +185 -0
  33. package/build/esm/{WhatsApp-2f54ed26.js → WhatsApp-6e473416.js} +1 -1
  34. package/build/esm/adapters.js +18 -16
  35. package/build/esm/atoms.js +44 -42
  36. package/build/esm/babyGrowth.js +82 -80
  37. package/build/esm/cache.js +2 -2
  38. package/build/esm/care.js +26 -23
  39. package/build/esm/careBookingSearchBar.js +1582 -0
  40. package/build/esm/careBookingSearchBarV2.js +1655 -0
  41. package/build/esm/components/molecules/popup/index.d.ts +2 -1
  42. package/build/esm/components.js +93 -83
  43. package/build/esm/{constants-b68073ea.js → constants-6409f351.js} +1 -1
  44. package/build/esm/constants.js +3 -3
  45. package/build/esm/constantsDomainLocales.js +1 -1
  46. package/build/esm/constantsRiskScreener.js +2 -2
  47. package/build/esm/constantsSite.js +2 -2
  48. package/build/esm/{core-bcdf3422.js → core-f2306660.js} +1 -1
  49. package/build/esm/{dataTransform-c3905a10.js → dataTransform-7074431d.js} +2 -2
  50. package/build/esm/ecom.js +4 -4
  51. package/build/esm/editor-f1c53093.js +959 -0
  52. package/build/esm/embeddedHeathToolCards_babyGrowth.js +22 -20
  53. package/build/esm/embeddedHeathToolCards_babyPoop.js +18 -16
  54. package/build/esm/embeddedHeathToolCards_babyVaccine.js +21 -19
  55. package/build/esm/embeddedHeathToolCards_bmi_bmi.js +25 -23
  56. package/build/esm/embeddedHeathToolCards_bmrBmr.js +25 -23
  57. package/build/esm/embeddedHeathToolCards_dueDate_dueDate.js +21 -19
  58. package/build/esm/embeddedHeathToolCards_ovulation_ovulation.js +21 -19
  59. package/build/esm/embeddedHeathToolCards_pwg_pwg.js +26 -24
  60. package/build/esm/embeddedHeathToolCards_targetHeartRate.js +27 -25
  61. package/build/esm/{fixedBottomAdBlock-bb1a3c50.js → fixedBottomAdBlock-3d6bb6ed.js} +26 -662
  62. package/build/esm/footer.js +20 -18
  63. package/build/esm/gAssets.js +2 -2
  64. package/build/esm/healthToolsCardWrapper.js +17 -15
  65. package/build/esm/healthToolsForm.js +33 -31
  66. package/build/esm/hooks.js +15 -15
  67. package/build/esm/i18n.js +2 -2
  68. package/build/esm/i18nV2.js +2 -2
  69. package/build/esm/{index-2b20b8ce.js → index-00949e45.js} +2 -2
  70. package/build/esm/{index-7ab1ac4c.js → index-011e1a41.js} +2 -2
  71. package/build/esm/{index-e84f16f3.js → index-050b8644.js} +3 -142
  72. package/build/esm/{index-a7bfcfbd.js → index-0ad45a17.js} +6 -6
  73. package/build/esm/{index-48fdf51c.js → index-1065c7d0.js} +16 -15
  74. package/build/esm/{index-b927d85a.js → index-1778704d.js} +12 -11
  75. package/build/esm/{index-c0790cdc.js → index-1ba53d6c.js} +20 -17
  76. package/build/esm/{index-a2704991.js → index-21c80677.js} +16 -88
  77. package/build/esm/{index-8570e132.js → index-296a1099.js} +2 -2
  78. package/build/esm/index-2f30d1dd.js +860 -0
  79. package/build/esm/index-3367898a.js +1264 -0
  80. package/build/esm/{index-11bc6557.js → index-391aad5b.js} +3 -3
  81. package/build/esm/{index-63d30402.js → index-405b11d3.js} +16 -15
  82. package/build/esm/{index-d3c3615e.js → index-42286f3e.js} +2 -2
  83. package/build/esm/{index-1f944c2d.js → index-44ced5ce.js} +5 -5
  84. package/build/esm/{index-140ea208.js → index-4d512cd9.js} +17 -16
  85. package/build/esm/{index-2f06b1d8.js → index-51179764.js} +1 -1
  86. package/build/esm/{index-fcf9a2ce.js → index-52f07e54.js} +14 -13
  87. package/build/esm/{index-b4cab951.js → index-54d714a2.js} +16 -15
  88. package/build/esm/index-5bd382e3.js +281 -0
  89. package/build/esm/{index-7d97103f.js → index-5d2f2783.js} +2 -2
  90. package/build/esm/{index-d10d5d1f.js → index-5f04e701.js} +4 -4
  91. package/build/esm/{index-04146795.js → index-670afcce.js} +5 -3
  92. package/build/esm/{index-17115a3b.js → index-6ce0d042.js} +15 -14
  93. package/build/esm/{index-e5797070.js → index-6ebc4e40.js} +3 -3
  94. package/build/esm/{index-fbe76c43.js → index-714d2892.js} +7 -6
  95. package/build/esm/{index-efdc151c.js → index-75811f98.js} +12 -11
  96. package/build/esm/{index-321f0612.js → index-78cb9c0e.js} +1 -1
  97. package/build/esm/{index-19a9a60d.js → index-7a3ac1f6.js} +1 -1
  98. package/build/esm/{index-29676661.js → index-8002ffd2.js} +6 -6
  99. package/build/esm/index-82b481bf.js +468 -0
  100. package/build/esm/{index-83ab0594.js → index-83dba9e4.js} +35 -800
  101. package/build/esm/{index-f42f0c66.js → index-918a026b.js} +2 -2
  102. package/build/esm/{index-67603e6c.js → index-9197f143.js} +15 -14
  103. package/build/esm/{index-69c631bf.js → index-9c7493b6.js} +12 -11
  104. package/build/esm/{index-2292c1f3.js → index-a0d47b03.js} +2 -2
  105. package/build/esm/{index-0cf91429.js → index-a134d156.js} +1 -1
  106. package/build/esm/index-a8b7284e.js +144 -0
  107. package/build/esm/{index-05075062.js → index-b013dd09.js} +1 -1
  108. package/build/esm/{index-9a0b3bcd.js → index-b266ccec.js} +7 -7
  109. package/build/esm/{index-4e92aaf2.js → index-b4efb261.js} +3 -3
  110. package/build/esm/{index-ef2b1e44.js → index-b87e6e0b.js} +6 -6
  111. package/build/esm/{index-0e0f3ac6.js → index-ba8e6508.js} +1 -1
  112. package/build/esm/{index-5303fcd9.js → index-bda0913e.js} +2 -2
  113. package/build/esm/{index-58ed669e.js → index-c2e1fb70.js} +23 -19
  114. package/build/esm/{index-b23b0c82.js → index-c8368a30.js} +14 -13
  115. package/build/esm/{index-877a46df.js → index-cb4b219f.js} +2 -2
  116. package/build/esm/index-d034201a.js +22 -0
  117. package/build/esm/{index-69ca7b6a.js → index-d5543323.js} +2 -2
  118. package/build/esm/index-d66bd239.js +1030 -0
  119. package/build/esm/{index-155daac5.js → index-da92eee1.js} +2 -2
  120. package/build/esm/{index-a715b700.js → index-e63aadb3.js} +15 -14
  121. package/build/esm/{index-5a81cbdd.js → index-e7128232.js} +1 -1
  122. package/build/esm/{index-58982ea1.js → index-ec003775.js} +3 -3
  123. package/build/esm/{index-cde1edae.js → index-f0dc90df.js} +21 -19
  124. package/build/esm/{index-478546e8.js → index-f8cc91fb.js} +12 -11
  125. package/build/esm/index.js +118 -98
  126. package/build/esm/index.styles-793c0b30.js +62 -0
  127. package/build/esm/interfaces/types/Subot.d.ts +3 -3
  128. package/build/esm/{labelSorting-db27bdad.js → labelSorting-feaa24fb.js} +4 -4
  129. package/build/esm/lead.js +22 -20
  130. package/build/esm/{logoIcon-6ed45e55.js → logoIcon-fbc8e7a1.js} +2 -2
  131. package/build/esm/mantine.js +24 -22
  132. package/build/esm/misc.js +18 -18
  133. package/build/esm/miscGetDynamicHealthTool.js +7 -7
  134. package/build/esm/miscGetSocialList.js +8 -8
  135. package/build/esm/miscScreenSizeContext.js +1 -1
  136. package/build/esm/mobileBottomNavigation.js +19 -0
  137. package/build/esm/mobileBottomNavigationIcon.js +10 -0
  138. package/build/esm/molecules.js +71 -64
  139. package/build/esm/moleculesArticleCard.js +85 -0
  140. package/build/esm/moleculesArticleCardV2.js +171 -0
  141. package/build/esm/navigation.js +40 -35
  142. package/build/esm/navigationLogoutPopup.js +116 -0
  143. package/build/esm/navigationProfileButton.js +43 -0
  144. package/build/esm/{normalizeLink-fcd22117.js → normalizeLink-136a636d.js} +1 -1
  145. package/build/esm/onboardingV2.js +27 -25
  146. package/build/esm/organisms.js +46 -41
  147. package/build/esm/post-203760fe.js +267 -0
  148. package/build/esm/profileNavigation.js +441 -0
  149. package/build/esm/progressBar.js +250 -0
  150. package/build/esm/pwg.js +21 -19
  151. package/build/esm/{routing-ed745cc6.js → routing-e57320c2.js} +1 -1
  152. package/build/esm/subot.js +29 -27
  153. package/build/esm/surveyOrPremiumBanner.js +30 -28
  154. package/build/esm/surveyQuestionCard.js +10 -10
  155. package/build/esm/{surveyThankyouCard-6fc9a327.js → surveyThankyouCard-5a060837.js} +5 -5
  156. package/build/esm/together/components/molecules/popupFrame/index.d.ts +2 -1
  157. package/build/esm/together.js +53 -44
  158. package/build/esm/togetherApiUtils.js +4 -4
  159. package/build/esm/togetherAtoms.js +29 -26
  160. package/build/esm/togetherComponentGlobalContext.js +4 -4
  161. package/build/esm/togetherMolecules.js +56 -47
  162. package/build/esm/togetherMoleculesCardAuthor.js +41 -0
  163. package/build/esm/togetherMoleculesPostImagePreview.js +21 -0
  164. package/build/esm/togetherMoleculesProfileDetail.js +53 -0
  165. package/build/esm/togetherOrganisms.js +53 -44
  166. package/build/esm/togetherRichTextEditor.js +27 -0
  167. package/build/esm/togetherShareBox.js +305 -0
  168. package/build/esm/{treePopoverMenu-937ef815.js → treePopoverMenu-7845b5c1.js} +18 -17
  169. package/build/esm/types-5f680f53.js +44 -0
  170. package/build/esm/types.js +2 -2
  171. package/build/esm/{useCategory-d239339f.js → useCategory-c847c3ee.js} +5 -5
  172. package/build/esm/{useHealthToolCache-e6e0e96c.js → useHealthToolCache-41375a2b.js} +1 -1
  173. package/build/esm/{useMantineLocale-2ece6eac.js → useMantineLocale-bef42461.js} +5 -5
  174. package/build/esm/{usePlacesAutocomplete-ecf31643.js → usePlacesAutocomplete-44a9e05c.js} +1 -1
  175. package/build/esm/useTogetherAuthRequiredAction.js +4 -4
  176. package/build/esm/{useTranslations-160e66cc.js → useTranslations-9767b0ea.js} +1 -1
  177. package/build/esm/utils-7871047f.js +206 -0
  178. package/build/esm/{utils-3d9043fb.js → utils-8a1ccf09.js} +4 -4
  179. package/build/esm/{utils-d78e02e6.js → utils-c1678a05.js} +2 -2
  180. package/build/esm/vaccination.js +20 -18
  181. package/build/{fixedBottomAdBlock-87988744.js → fixedBottomAdBlock-bfdbc0df.js} +49 -691
  182. package/build/footer.js +20 -18
  183. package/build/gAssets.js +2 -2
  184. package/build/healthToolsCardWrapper.js +17 -15
  185. package/build/healthToolsForm.js +33 -31
  186. package/build/hooks.js +15 -15
  187. package/build/i18n.js +1 -1
  188. package/build/i18nV2.js +1 -1
  189. package/build/{index-c016b1bb.js → index-133544cd.js} +14 -13
  190. package/build/index-137b351f.js +1045 -0
  191. package/build/{index-92815934.js → index-190832cb.js} +5 -5
  192. package/build/{index-0772398f.js → index-1b1ac8fe.js} +1 -1
  193. package/build/{index-a6acde43.js → index-2089929b.js} +38 -34
  194. package/build/{index-f8a51099.js → index-2c23680e.js} +2 -2
  195. package/build/index-2d391b09.js +151 -0
  196. package/build/{index-b040447b.js → index-2f31063d.js} +2 -2
  197. package/build/{index-d9559ac1.js → index-31045247.js} +2 -2
  198. package/build/{index-e4004288.js → index-330e16a8.js} +2 -2
  199. package/build/{index-b8620e16.js → index-3c6a1bfc.js} +2 -2
  200. package/build/{index-e7b871b4.js → index-3f49c41e.js} +3 -143
  201. package/build/index-4b1b3672.js +478 -0
  202. package/build/{index-4a6c95fe.js → index-5209298d.js} +12 -11
  203. package/build/index-5cc887da.js +870 -0
  204. package/build/{index-a97a7a53.js → index-5e1337b4.js} +31 -29
  205. package/build/{index-2de1a14d.js → index-6266a5df.js} +2 -2
  206. package/build/{index-f3553904.js → index-62f912e0.js} +9 -8
  207. package/build/{index-84e8b355.js → index-63f2aaa5.js} +15 -14
  208. package/build/{index-9f995309.js → index-65eb73e7.js} +34 -31
  209. package/build/{index-6c2d2f25.js → index-67fa5818.js} +24 -99
  210. package/build/index-69cd0b40.js +1307 -0
  211. package/build/{index-d39f2445.js → index-6cda2bed.js} +4 -4
  212. package/build/{index-9add51eb.js → index-74869e06.js} +3 -3
  213. package/build/{index-227e17fd.js → index-7b74a414.js} +2 -2
  214. package/build/{index-6ce119f5.js → index-7b8badf9.js} +2 -2
  215. package/build/{index-bac0bd08.js → index-7dfa541c.js} +3 -3
  216. package/build/{index-519a6287.js → index-81dcaeb1.js} +12 -11
  217. package/build/{index-5ddda8f4.js → index-82577dcf.js} +16 -15
  218. package/build/{index-f05721a0.js → index-870325c1.js} +7 -7
  219. package/build/{index-a136cba7.js → index-87d6e499.js} +6 -6
  220. package/build/{index-554ad68c.js → index-8ce24abd.js} +1 -1
  221. package/build/{index-03834ac7.js → index-8e2a718b.js} +3 -3
  222. package/build/{index-347a91f6.js → index-930f87f9.js} +1 -1
  223. package/build/{index-ae03f378.js → index-96e9edfa.js} +16 -15
  224. package/build/{index-196d4981.js → index-9ca1658b.js} +1 -1
  225. package/build/{index-8b8263ed.js → index-a0dd7ee6.js} +34 -33
  226. package/build/{index-c294ccc2.js → index-a94d3a6e.js} +3 -3
  227. package/build/{index-a688f865.js → index-ae4a2ce9.js} +12 -11
  228. package/build/{index-1489f027.js → index-b1181a62.js} +3 -3
  229. package/build/{index-1245ea43.js → index-b74f6d6c.js} +12 -11
  230. package/build/{index-7ca746d3.js → index-bee8ec72.js} +15 -14
  231. package/build/index-c0960783.js +289 -0
  232. package/build/{index-6313ec6f.js → index-c7bc83de.js} +6 -6
  233. package/build/{index-4dc41ef1.js → index-d414e4f7.js} +5 -3
  234. package/build/{index-1ebaa446.js → index-e23391ca.js} +16 -15
  235. package/build/{index-fcf16e35.js → index-e48cde73.js} +2 -2
  236. package/build/{index-9cc21262.js → index-f00131bf.js} +1 -1
  237. package/build/{index-7e8732ae.js → index-f0c0316f.js} +1 -1
  238. package/build/index-f373b62b.js +29 -0
  239. package/build/{index-66b34bd9.js → index-f477fee8.js} +96 -864
  240. package/build/{index-5006f129.js → index-f4bd7dd9.js} +6 -6
  241. package/build/{index-f3f648e1.js → index-f4c71c79.js} +17 -16
  242. package/build/{index-7024d536.js → index-f7918c25.js} +15 -14
  243. package/build/{index-9e92431c.js → index-f9aee5dd.js} +2 -2
  244. package/build/{index-92e82d0d.js → index-fa8957ac.js} +1 -1
  245. package/build/index.js +182 -162
  246. package/build/index.styles-07f26519.js +65 -0
  247. package/build/interfaces/types/Subot.d.ts +3 -3
  248. package/build/{labelSorting-60b0f16a.js → labelSorting-2d65cd86.js} +4 -4
  249. package/build/lead.js +22 -20
  250. package/build/{logoIcon-8e1ff0aa.js → logoIcon-026665b4.js} +2 -2
  251. package/build/mantine.js +20 -18
  252. package/build/misc.js +18 -18
  253. package/build/miscGetDynamicHealthTool.js +7 -7
  254. package/build/miscGetSocialList.js +8 -8
  255. package/build/miscScreenSizeContext.js +1 -1
  256. package/build/mobileBottomNavigation.js +27 -0
  257. package/build/mobileBottomNavigationIcon.js +18 -0
  258. package/build/molecules.js +76 -69
  259. package/build/moleculesArticleCard.js +93 -0
  260. package/build/moleculesArticleCardV2.js +180 -0
  261. package/build/navigation.js +40 -35
  262. package/build/navigationLogoutPopup.js +125 -0
  263. package/build/navigationProfileButton.js +51 -0
  264. package/build/onboardingV2.js +29 -27
  265. package/build/organisms.js +49 -44
  266. package/build/post-0759bdca.js +303 -0
  267. package/build/profileNavigation.js +450 -0
  268. package/build/progressBar.js +260 -0
  269. package/build/pwg.js +21 -19
  270. package/build/{routing-d764168d.js → routing-7ba14d2a.js} +1 -1
  271. package/build/subot.js +28 -26
  272. package/build/surveyOrPremiumBanner.js +30 -28
  273. package/build/surveyQuestionCard.js +10 -10
  274. package/build/{surveyThankyouCard-944ab001.js → surveyThankyouCard-6a2454d1.js} +5 -5
  275. package/build/together/components/molecules/popupFrame/index.d.ts +2 -1
  276. package/build/together.js +77 -68
  277. package/build/togetherApiUtils.js +4 -4
  278. package/build/togetherAtoms.js +29 -26
  279. package/build/togetherComponentGlobalContext.js +4 -4
  280. package/build/togetherMolecules.js +79 -70
  281. package/build/togetherMoleculesCardAuthor.js +49 -0
  282. package/build/togetherMoleculesPostImagePreview.js +29 -0
  283. package/build/togetherMoleculesProfileDetail.js +70 -0
  284. package/build/togetherOrganisms.js +53 -44
  285. package/build/togetherRichTextEditor.js +36 -0
  286. package/build/togetherShareBox.js +314 -0
  287. package/build/{treePopoverMenu-0cbe3fd0.js → treePopoverMenu-86c7db6d.js} +18 -17
  288. package/build/types-20cc07c9.js +52 -0
  289. package/build/types.js +2 -2
  290. package/build/{useCategory-32558796.js → useCategory-0f8c9201.js} +5 -5
  291. package/build/{useHealthToolCache-cbe4b1b4.js → useHealthToolCache-c0468424.js} +1 -1
  292. package/build/{useMantineLocale-992ae094.js → useMantineLocale-b8eca90b.js} +5 -5
  293. package/build/{usePlacesAutocomplete-c19d396b.js → usePlacesAutocomplete-1d139be6.js} +1 -1
  294. package/build/useTogetherAuthRequiredAction.js +4 -4
  295. package/build/{useTranslations-5d28e8df.js → useTranslations-4fb7a5ac.js} +1 -1
  296. package/build/{utils-d3353e9c.js → utils-14192273.js} +2 -2
  297. package/build/{utils-1a876a51.js → utils-1b9bc7e0.js} +3 -3
  298. package/build/utils-a4f75f1f.js +229 -0
  299. package/build/vaccination.js +24 -22
  300. package/package.json +1 -1
  301. package/build/esm/index-c7b92115.js +0 -5060
  302. package/build/esm/types-f387cdcf.js +0 -3433
  303. package/build/index-2ce324cf.js +0 -5123
  304. package/build/types-d798cef3.js +0 -3447
  305. /package/build/{BMI_BOYS.percentile.monthly-2fdec618.js → BMI_BOYS.percentile.monthly-b372ea44.js} +0 -0
  306. /package/build/{BMI_BOYS.percentile.weekly-4b1616c4.js → BMI_BOYS.percentile.weekly-74d9aa42.js} +0 -0
  307. /package/build/{BMI_BOYS.percentile.yearly-f7761749.js → BMI_BOYS.percentile.yearly-8983c077.js} +0 -0
  308. /package/build/{BMI_BOYS.zscore.monthly-6767b0d4.js → BMI_BOYS.zscore.monthly-87a6a1a1.js} +0 -0
  309. /package/build/{BMI_BOYS.zscore.weekly-5c57342b.js → BMI_BOYS.zscore.weekly-943afdf9.js} +0 -0
  310. /package/build/{BMI_BOYS.zscore.yearly-d970734e.js → BMI_BOYS.zscore.yearly-b60dee5d.js} +0 -0
  311. /package/build/{BMI_GIRLS.percentile.monthly-ba4d972d.js → BMI_GIRLS.percentile.monthly-a92a2367.js} +0 -0
  312. /package/build/{BMI_GIRLS.percentile.weekly-f73dacf3.js → BMI_GIRLS.percentile.weekly-81e2a447.js} +0 -0
  313. /package/build/{BMI_GIRLS.percentile.yearly-a5b59a8c.js → BMI_GIRLS.percentile.yearly-aec7fe9d.js} +0 -0
  314. /package/build/{BMI_GIRLS.zscore.monthly-110d6823.js → BMI_GIRLS.zscore.monthly-a6183959.js} +0 -0
  315. /package/build/{BMI_GIRLS.zscore.weekly-cfe97ba9.js → BMI_GIRLS.zscore.weekly-0bc8803a.js} +0 -0
  316. /package/build/{BMI_GIRLS.zscore.yearly-ab4ae640.js → BMI_GIRLS.zscore.yearly-a3098165.js} +0 -0
  317. /package/build/{ChevronDown-d37704eb.js → ChevronDown-c29d0fb5.js} +0 -0
  318. /package/build/{Close-1514c815.js → Close-b7d67405.js} +0 -0
  319. /package/build/{HEAD CIRCUM_BOYS.percentile.monthly-6c797045.js → HEAD CIRCUM_BOYS.percentile.monthly-d4fabdf2.js} +0 -0
  320. /package/build/{HEAD CIRCUM_BOYS.percentile.weekly-7ac501c0.js → HEAD CIRCUM_BOYS.percentile.weekly-32cbc60f.js} +0 -0
  321. /package/build/{HEAD CIRCUM_BOYS.percentile.yearly-2999cdb8.js → HEAD CIRCUM_BOYS.percentile.yearly-a37b8f8a.js} +0 -0
  322. /package/build/{HEAD CIRCUM_BOYS.zscore.monthly-7e3a78aa.js → HEAD CIRCUM_BOYS.zscore.monthly-c3f7634f.js} +0 -0
  323. /package/build/{HEAD CIRCUM_BOYS.zscore.weekly-2ea72789.js → HEAD CIRCUM_BOYS.zscore.weekly-71ccd3df.js} +0 -0
  324. /package/build/{HEAD CIRCUM_BOYS.zscore.yearly-826ab425.js → HEAD CIRCUM_BOYS.zscore.yearly-a49605c2.js} +0 -0
  325. /package/build/{HEAD CIRCUM_GIRLS.percentile.monthly-0f1636c1.js → HEAD CIRCUM_GIRLS.percentile.monthly-68c5f17b.js} +0 -0
  326. /package/build/{HEAD CIRCUM_GIRLS.percentile.weekly-b32da590.js → HEAD CIRCUM_GIRLS.percentile.weekly-09ab91dc.js} +0 -0
  327. /package/build/{HEAD CIRCUM_GIRLS.percentile.yearly-850c4e29.js → HEAD CIRCUM_GIRLS.percentile.yearly-f33be7ba.js} +0 -0
  328. /package/build/{HEAD CIRCUM_GIRLS.zscore.monthly-f942b53a.js → HEAD CIRCUM_GIRLS.zscore.monthly-283c0ef7.js} +0 -0
  329. /package/build/{HEAD CIRCUM_GIRLS.zscore.weekly-26daad32.js → HEAD CIRCUM_GIRLS.zscore.weekly-1feda657.js} +0 -0
  330. /package/build/{HEAD CIRCUM_GIRLS.zscore.yearly-0f331108.js → HEAD CIRCUM_GIRLS.zscore.yearly-bcba4238.js} +0 -0
  331. /package/build/{HEIGHT_BOYS.percentile.monthly-6bfc3799.js → HEIGHT_BOYS.percentile.monthly-977b0b64.js} +0 -0
  332. /package/build/{HEIGHT_BOYS.percentile.weekly-0ed4b053.js → HEIGHT_BOYS.percentile.weekly-ff1b517f.js} +0 -0
  333. /package/build/{HEIGHT_BOYS.percentile.yearly-cc4c343d.js → HEIGHT_BOYS.percentile.yearly-e0ed022d.js} +0 -0
  334. /package/build/{HEIGHT_BOYS.zscore.monthly-b2d384dc.js → HEIGHT_BOYS.zscore.monthly-397f6aa4.js} +0 -0
  335. /package/build/{HEIGHT_BOYS.zscore.weekly-b65aa792.js → HEIGHT_BOYS.zscore.weekly-dccfdd52.js} +0 -0
  336. /package/build/{HEIGHT_BOYS.zscore.yearly-0bae3840.js → HEIGHT_BOYS.zscore.yearly-76500a0f.js} +0 -0
  337. /package/build/{HEIGHT_GIRLS.percentile.monthly-34960fd2.js → HEIGHT_GIRLS.percentile.monthly-3a7aef92.js} +0 -0
  338. /package/build/{HEIGHT_GIRLS.percentile.weekly-949ca5b1.js → HEIGHT_GIRLS.percentile.weekly-99e3c1c3.js} +0 -0
  339. /package/build/{HEIGHT_GIRLS.percentile.yearly-4c40b714.js → HEIGHT_GIRLS.percentile.yearly-9f01d7d1.js} +0 -0
  340. /package/build/{HEIGHT_GIRLS.zscore.monthly-a3856728.js → HEIGHT_GIRLS.zscore.monthly-973ae30d.js} +0 -0
  341. /package/build/{HEIGHT_GIRLS.zscore.weekly-b39f321f.js → HEIGHT_GIRLS.zscore.weekly-18ae768b.js} +0 -0
  342. /package/build/{HEIGHT_GIRLS.zscore.yearly-f50c6d58.js → HEIGHT_GIRLS.zscore.yearly-dc42b61a.js} +0 -0
  343. /package/build/{Locale-e3b7ae56.js → Locale-e697d040.js} +0 -0
  344. /package/build/{Visible-c6736a66.js → Visible-8c2b5ab1.js} +0 -0
  345. /package/build/{WEIGHT_BOYS.percentile.monthly-685aabfc.js → WEIGHT_BOYS.percentile.monthly-3f17ac1f.js} +0 -0
  346. /package/build/{WEIGHT_BOYS.percentile.weekly-3c1a6d2f.js → WEIGHT_BOYS.percentile.weekly-8f2ebf77.js} +0 -0
  347. /package/build/{WEIGHT_BOYS.percentile.yearly-2bd65c8f.js → WEIGHT_BOYS.percentile.yearly-a9eff519.js} +0 -0
  348. /package/build/{WEIGHT_BOYS.zscore.monthly-bba8cd92.js → WEIGHT_BOYS.zscore.monthly-a108db0c.js} +0 -0
  349. /package/build/{WEIGHT_BOYS.zscore.weekly-7bdc0673.js → WEIGHT_BOYS.zscore.weekly-e21f46c5.js} +0 -0
  350. /package/build/{WEIGHT_BOYS.zscore.yearly-32f635e0.js → WEIGHT_BOYS.zscore.yearly-1309493f.js} +0 -0
  351. /package/build/{WEIGHT_GIRLS.percentile.monthly-ad305e84.js → WEIGHT_GIRLS.percentile.monthly-e6ad9d1e.js} +0 -0
  352. /package/build/{WEIGHT_GIRLS.percentile.weekly-92e552b6.js → WEIGHT_GIRLS.percentile.weekly-15e2f043.js} +0 -0
  353. /package/build/{WEIGHT_GIRLS.percentile.yearly-df0dd71c.js → WEIGHT_GIRLS.percentile.yearly-788c6b1a.js} +0 -0
  354. /package/build/{WEIGHT_GIRLS.zscore.monthly-8820671b.js → WEIGHT_GIRLS.zscore.monthly-ad9bc118.js} +0 -0
  355. /package/build/{WEIGHT_GIRLS.zscore.weekly-31d29b05.js → WEIGHT_GIRLS.zscore.weekly-027d92d0.js} +0 -0
  356. /package/build/{WEIGHT_GIRLS.zscore.yearly-f731d1e2.js → WEIGHT_GIRLS.zscore.yearly-2f942e3c.js} +0 -0
  357. /package/build/{animation-b224626d.js → animation-e179e2c5.js} +0 -0
  358. /package/build/{cart-149e990d.js → cart-bf783c3f.js} +0 -0
  359. /package/build/{constants-9c314450.js → constants-0f0f1c47.js} +0 -0
  360. /package/build/{constants-f9eca9ad.js → constants-7d64d5de.js} +0 -0
  361. /package/build/{constants-42eed92d.js → constants-f4bb9873.js} +0 -0
  362. /package/build/{dataTransform-104761fc.js → dataTransform-e07ba759.js} +0 -0
  363. /package/build/{doctor-d8f36158.js → doctor-40ef3864.js} +0 -0
  364. /package/build/esm/{BMI_BOYS.percentile.monthly-df1b3770.js → BMI_BOYS.percentile.monthly-bc6b17e9.js} +0 -0
  365. /package/build/esm/{BMI_BOYS.percentile.weekly-1d9595b1.js → BMI_BOYS.percentile.weekly-8daca1b6.js} +0 -0
  366. /package/build/esm/{BMI_BOYS.percentile.yearly-6bd2bb46.js → BMI_BOYS.percentile.yearly-391e1be2.js} +0 -0
  367. /package/build/esm/{BMI_BOYS.zscore.monthly-658792d1.js → BMI_BOYS.zscore.monthly-aec29c0d.js} +0 -0
  368. /package/build/esm/{BMI_BOYS.zscore.weekly-d3c4d378.js → BMI_BOYS.zscore.weekly-1ab0449c.js} +0 -0
  369. /package/build/esm/{BMI_BOYS.zscore.yearly-8ad375e2.js → BMI_BOYS.zscore.yearly-01a796dd.js} +0 -0
  370. /package/build/esm/{BMI_GIRLS.percentile.monthly-25f98c64.js → BMI_GIRLS.percentile.monthly-259b596a.js} +0 -0
  371. /package/build/esm/{BMI_GIRLS.percentile.weekly-d60b034d.js → BMI_GIRLS.percentile.weekly-c383c66f.js} +0 -0
  372. /package/build/esm/{BMI_GIRLS.percentile.yearly-0560df43.js → BMI_GIRLS.percentile.yearly-d62c0a28.js} +0 -0
  373. /package/build/esm/{BMI_GIRLS.zscore.monthly-2104651f.js → BMI_GIRLS.zscore.monthly-7625134f.js} +0 -0
  374. /package/build/esm/{BMI_GIRLS.zscore.weekly-37757497.js → BMI_GIRLS.zscore.weekly-0e939010.js} +0 -0
  375. /package/build/esm/{BMI_GIRLS.zscore.yearly-56872c59.js → BMI_GIRLS.zscore.yearly-a63cf9c5.js} +0 -0
  376. /package/build/esm/{ChevronDown-5633c5e8.js → ChevronDown-47009d66.js} +0 -0
  377. /package/build/esm/{Close-f541a904.js → Close-7ace7512.js} +0 -0
  378. /package/build/esm/{HEAD CIRCUM_BOYS.percentile.monthly-47e6539d.js → HEAD CIRCUM_BOYS.percentile.monthly-3a2beeac.js} +0 -0
  379. /package/build/esm/{HEAD CIRCUM_BOYS.percentile.weekly-594e065d.js → HEAD CIRCUM_BOYS.percentile.weekly-74d61bf1.js} +0 -0
  380. /package/build/esm/{HEAD CIRCUM_BOYS.percentile.yearly-d24f1cc6.js → HEAD CIRCUM_BOYS.percentile.yearly-f13c493e.js} +0 -0
  381. /package/build/esm/{HEAD CIRCUM_BOYS.zscore.monthly-94d82cb5.js → HEAD CIRCUM_BOYS.zscore.monthly-205ba143.js} +0 -0
  382. /package/build/esm/{HEAD CIRCUM_BOYS.zscore.weekly-cb0109d0.js → HEAD CIRCUM_BOYS.zscore.weekly-1e22609d.js} +0 -0
  383. /package/build/esm/{HEAD CIRCUM_BOYS.zscore.yearly-79a794c9.js → HEAD CIRCUM_BOYS.zscore.yearly-07a6cd70.js} +0 -0
  384. /package/build/esm/{HEAD CIRCUM_GIRLS.percentile.monthly-89615b43.js → HEAD CIRCUM_GIRLS.percentile.monthly-6843b424.js} +0 -0
  385. /package/build/esm/{HEAD CIRCUM_GIRLS.percentile.weekly-29d9184f.js → HEAD CIRCUM_GIRLS.percentile.weekly-0602fcca.js} +0 -0
  386. /package/build/esm/{HEAD CIRCUM_GIRLS.percentile.yearly-140da49d.js → HEAD CIRCUM_GIRLS.percentile.yearly-c47a7e80.js} +0 -0
  387. /package/build/esm/{HEAD CIRCUM_GIRLS.zscore.monthly-fe41d0e8.js → HEAD CIRCUM_GIRLS.zscore.monthly-35359b2d.js} +0 -0
  388. /package/build/esm/{HEAD CIRCUM_GIRLS.zscore.weekly-c6193e75.js → HEAD CIRCUM_GIRLS.zscore.weekly-e60d4541.js} +0 -0
  389. /package/build/esm/{HEAD CIRCUM_GIRLS.zscore.yearly-7018fed4.js → HEAD CIRCUM_GIRLS.zscore.yearly-776abe04.js} +0 -0
  390. /package/build/esm/{HEIGHT_BOYS.percentile.monthly-fae5e6a0.js → HEIGHT_BOYS.percentile.monthly-72427471.js} +0 -0
  391. /package/build/esm/{HEIGHT_BOYS.percentile.weekly-ddc33aee.js → HEIGHT_BOYS.percentile.weekly-9002aef8.js} +0 -0
  392. /package/build/esm/{HEIGHT_BOYS.percentile.yearly-9e3064f0.js → HEIGHT_BOYS.percentile.yearly-57e7b44e.js} +0 -0
  393. /package/build/esm/{HEIGHT_BOYS.zscore.monthly-7c9e0bb8.js → HEIGHT_BOYS.zscore.monthly-e38229ab.js} +0 -0
  394. /package/build/esm/{HEIGHT_BOYS.zscore.weekly-50b0a6a0.js → HEIGHT_BOYS.zscore.weekly-0de1c25b.js} +0 -0
  395. /package/build/esm/{HEIGHT_BOYS.zscore.yearly-afb6c4a2.js → HEIGHT_BOYS.zscore.yearly-79fd59a0.js} +0 -0
  396. /package/build/esm/{HEIGHT_GIRLS.percentile.monthly-5c7487f0.js → HEIGHT_GIRLS.percentile.monthly-4b85547a.js} +0 -0
  397. /package/build/esm/{HEIGHT_GIRLS.percentile.weekly-33465e14.js → HEIGHT_GIRLS.percentile.weekly-c56f6c67.js} +0 -0
  398. /package/build/esm/{HEIGHT_GIRLS.percentile.yearly-ae62b279.js → HEIGHT_GIRLS.percentile.yearly-0ab407d8.js} +0 -0
  399. /package/build/esm/{HEIGHT_GIRLS.zscore.monthly-fd13c492.js → HEIGHT_GIRLS.zscore.monthly-bc1b72b1.js} +0 -0
  400. /package/build/esm/{HEIGHT_GIRLS.zscore.weekly-f509ffbe.js → HEIGHT_GIRLS.zscore.weekly-ad1be5c9.js} +0 -0
  401. /package/build/esm/{HEIGHT_GIRLS.zscore.yearly-bf3a867b.js → HEIGHT_GIRLS.zscore.yearly-f66a912e.js} +0 -0
  402. /package/build/esm/{Locale-81beb37e.js → Locale-ecfc005f.js} +0 -0
  403. /package/build/esm/{Visible-3d8c22f1.js → Visible-6cf48849.js} +0 -0
  404. /package/build/esm/{WEIGHT_BOYS.percentile.monthly-4db4c32c.js → WEIGHT_BOYS.percentile.monthly-c6ff1c19.js} +0 -0
  405. /package/build/esm/{WEIGHT_BOYS.percentile.weekly-5321689a.js → WEIGHT_BOYS.percentile.weekly-4da177a7.js} +0 -0
  406. /package/build/esm/{WEIGHT_BOYS.percentile.yearly-0c2aee80.js → WEIGHT_BOYS.percentile.yearly-9dd4d8d7.js} +0 -0
  407. /package/build/esm/{WEIGHT_BOYS.zscore.monthly-ddf307e5.js → WEIGHT_BOYS.zscore.monthly-824c2f6d.js} +0 -0
  408. /package/build/esm/{WEIGHT_BOYS.zscore.weekly-be1d57ac.js → WEIGHT_BOYS.zscore.weekly-d20f3e4a.js} +0 -0
  409. /package/build/esm/{WEIGHT_BOYS.zscore.yearly-6dab88ff.js → WEIGHT_BOYS.zscore.yearly-727beeda.js} +0 -0
  410. /package/build/esm/{WEIGHT_GIRLS.percentile.monthly-a666fe8a.js → WEIGHT_GIRLS.percentile.monthly-a2813cfb.js} +0 -0
  411. /package/build/esm/{WEIGHT_GIRLS.percentile.weekly-cd85042c.js → WEIGHT_GIRLS.percentile.weekly-5f11b917.js} +0 -0
  412. /package/build/esm/{WEIGHT_GIRLS.percentile.yearly-f22705ec.js → WEIGHT_GIRLS.percentile.yearly-50e69a87.js} +0 -0
  413. /package/build/esm/{WEIGHT_GIRLS.zscore.monthly-9f3f1083.js → WEIGHT_GIRLS.zscore.monthly-401c7b03.js} +0 -0
  414. /package/build/esm/{WEIGHT_GIRLS.zscore.weekly-7dcf0ba5.js → WEIGHT_GIRLS.zscore.weekly-c8c05886.js} +0 -0
  415. /package/build/esm/{WEIGHT_GIRLS.zscore.yearly-c658040c.js → WEIGHT_GIRLS.zscore.yearly-95f19286.js} +0 -0
  416. /package/build/esm/{animation-db89f033.js → animation-e6680d35.js} +0 -0
  417. /package/build/esm/{cart-47013af9.js → cart-bf2cc2ab.js} +0 -0
  418. /package/build/esm/{constants-f9614464.js → constants-7628355c.js} +0 -0
  419. /package/build/esm/{constants-247d5eb0.js → constants-785ee28c.js} +0 -0
  420. /package/build/esm/{constants-410be40f.js → constants-ce2232f9.js} +0 -0
  421. /package/build/esm/{dataTransform-f9e5b4ec.js → dataTransform-65f0e010.js} +0 -0
  422. /package/build/esm/{doctor-88e78d2c.js → doctor-e9dc9ff4.js} +0 -0
  423. /package/build/esm/{index-fcd9b927.js → index-0b230567.js} +0 -0
  424. /package/build/esm/{index-5f214b71.js → index-46c00291.js} +0 -0
  425. /package/build/esm/{index-6dd5a329.js → index-92017dfa.js} +0 -0
  426. /package/build/esm/{index-907fffe6.js → index-c1527254.js} +0 -0
  427. /package/build/esm/{index-24f2f569.js → index-d4eef69b.js} +0 -0
  428. /package/build/esm/{index-c3d6b2ed.js → index-d531588f.js} +0 -0
  429. /package/build/esm/{index-0ca51fbb.js → index-efcf28a7.js} +0 -0
  430. /package/build/esm/{index-6f44d928.js → index-fedbbf85.js} +0 -0
  431. /package/build/esm/{localizeNumberFormat-be70a31e.js → localizeNumberFormat-636f4afc.js} +0 -0
  432. /package/build/esm/{number-7e3f376a.js → number-4add588d.js} +0 -0
  433. /package/build/esm/{other-811b7d93.js → other-f8b0155f.js} +0 -0
  434. /package/build/esm/{paths-650d5eee.js → paths-8c6b2942.js} +0 -0
  435. /package/build/esm/{translationsContext-0cbb21e6.js → translationsContext-982b80f4.js} +0 -0
  436. /package/build/esm/{tslib.es6-3970c414.js → tslib.es6-fd8cab49.js} +0 -0
  437. /package/build/esm/{types-78bfaf40.js → types-795b39db.js} +0 -0
  438. /package/build/esm/{useIsInit-3f7af1fd.js → useIsInit-b060587e.js} +0 -0
  439. /package/build/esm/{useOutsideClick-2fae5fb5.js → useOutsideClick-9dd24b21.js} +0 -0
  440. /package/build/esm/{useScrollbarSize-2a7e6dd2.js → useScrollbarSize-63b3d369.js} +0 -0
  441. /package/build/esm/{useUniqueId-d714426d.js → useUniqueId-d61a7b61.js} +0 -0
  442. /package/build/esm/{utils-cee25689.js → utils-1dbd61fa.js} +0 -0
  443. /package/build/{index-1d528960.js → index-0e1519d2.js} +0 -0
  444. /package/build/{index-9f501aac.js → index-3a582f5d.js} +0 -0
  445. /package/build/{index-20a5cee0.js → index-7a8c6b41.js} +0 -0
  446. /package/build/{index-41a348a2.js → index-86f9afd6.js} +0 -0
  447. /package/build/{index-e327613c.js → index-96be5ce0.js} +0 -0
  448. /package/build/{index-32917720.js → index-b8a5acbb.js} +0 -0
  449. /package/build/{index-186f9324.js → index-db2b38f4.js} +0 -0
  450. /package/build/{index-27f25094.js → index-f8017859.js} +0 -0
  451. /package/build/{localizeNumberFormat-a5804ea2.js → localizeNumberFormat-9697460d.js} +0 -0
  452. /package/build/{normalizeLink-2878a2ce.js → normalizeLink-3ec047d7.js} +0 -0
  453. /package/build/{number-35662113.js → number-3ffc7553.js} +0 -0
  454. /package/build/{other-a7f01b3d.js → other-5c1524b3.js} +0 -0
  455. /package/build/{paths-488dafd4.js → paths-f15bee7b.js} +0 -0
  456. /package/build/{translationsContext-951038ad.js → translationsContext-9b528bb0.js} +0 -0
  457. /package/build/{tslib.es6-145af9ce.js → tslib.es6-5d65f18f.js} +0 -0
  458. /package/build/{types-aeea2cc2.js → types-4b87fdbb.js} +0 -0
  459. /package/build/{useIsInit-0c37752a.js → useIsInit-d6139b45.js} +0 -0
  460. /package/build/{useOutsideClick-aa477d22.js → useOutsideClick-b5ae0665.js} +0 -0
  461. /package/build/{useScrollbarSize-01b12b72.js → useScrollbarSize-ad6c0522.js} +0 -0
  462. /package/build/{useUniqueId-17c2097b.js → useUniqueId-5fc9f536.js} +0 -0
  463. /package/build/{utils-a1cfbdac.js → utils-97ffdcb1.js} +0 -0
@@ -1,3447 +0,0 @@
1
- 'use strict';
2
-
3
- var tslib_es6 = require('./tslib.es6-145af9ce.js');
4
- var React = require('react');
5
- var react = require('@emotion/react');
6
- var useTranslations = require('./useTranslations-5d28e8df.js');
7
- var debounce = require('lodash/debounce');
8
- var constants = require('./constants-42eed92d.js');
9
- var styled = require('@emotion/styled');
10
- var index$1 = require('./index-6ce119f5.js');
11
- var index$2 = require('./index-2de1a14d.js');
12
- var miscTheme = require('./miscTheme.js');
13
- var shuffle = require('lodash/shuffle');
14
- var useOutsideClick = require('./useOutsideClick-aa477d22.js');
15
- var utils = require('./utils-a1cfbdac.js');
16
- var Skeleton = require('react-loading-skeleton');
17
- var paths = require('./paths-488dafd4.js');
18
- var core = require('@mantine/core');
19
- var index = require('./index-e4004288.js');
20
- var miscCookieHelper = require('./miscCookieHelper.js');
21
- var index$3 = require('./index-20a5cee0.js');
22
- var core$1 = require('@hhgtech/icons/core');
23
- var ChevronDown = require('./ChevronDown-d37704eb.js');
24
- var formatString = require('string-format');
25
- var constantsDomainLocales = require('./constantsDomainLocales.js');
26
-
27
- function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
28
-
29
- var React__default = /*#__PURE__*/_interopDefault(React);
30
- var debounce__default = /*#__PURE__*/_interopDefault(debounce);
31
- var styled__default = /*#__PURE__*/_interopDefault(styled);
32
- var shuffle__default = /*#__PURE__*/_interopDefault(shuffle);
33
- var Skeleton__default = /*#__PURE__*/_interopDefault(Skeleton);
34
- var formatString__default = /*#__PURE__*/_interopDefault(formatString);
35
-
36
- function useGeolocation() {
37
- const [permission, setPermission] = React.useState(() => {
38
- if (typeof window === 'undefined') {
39
- return 'unset';
40
- }
41
- if (miscCookieHelper.getCookie(index.USER_GEOLOCATION_COORDINATES_COOKIE)) {
42
- return 'granted';
43
- }
44
- const blocked = !location.protocol.includes('https') && location.hostname !== 'localhost';
45
- if (!navigator.geolocation || blocked) {
46
- return 'denied';
47
- }
48
- return 'unset';
49
- });
50
- const [coordinates, setCoordinates] = React.useState(() => {
51
- if (typeof window === 'undefined') {
52
- return null;
53
- }
54
- const cookie = miscCookieHelper.getCookie(index.USER_GEOLOCATION_COORDINATES_COOKIE);
55
- if (cookie) {
56
- try {
57
- return JSON.parse(cookie);
58
- }
59
- catch (err) {
60
- console.log(err);
61
- }
62
- }
63
- return null;
64
- });
65
- const request = React.useCallback(function request() {
66
- // setPermission()
67
- if (navigator.geolocation) {
68
- navigator.geolocation.getCurrentPosition((position) => {
69
- const gps = {
70
- lat: `${Math.round(position.coords.latitude * 10000000) / 10000000}`,
71
- lng: `${Math.round(position.coords.longitude * 10000000) / 10000000}`,
72
- };
73
- miscCookieHelper.setCookie(index.USER_GEOLOCATION_COORDINATES_COOKIE, JSON.stringify(gps), {
74
- minutes: 15,
75
- });
76
- setCoordinates(gps);
77
- setPermission('granted');
78
- }, () => {
79
- miscCookieHelper.deleteCookie(index.USER_GEOLOCATION_COORDINATES_COOKIE);
80
- setPermission('denied');
81
- });
82
- }
83
- }, []);
84
- return React.useMemo(() => ({
85
- geoLocationPermission: permission,
86
- geoLocationCoordinates: coordinates,
87
- requestGeoLocation: request,
88
- }), [permission, coordinates]);
89
- }
90
-
91
- const StyledSearchBarWrapper$1 = styled__default["default"].div ``;
92
- const StyledSearchBarMobileWrapper = styled__default["default"].div `
93
- --searchbar-z-index: 305;
94
- &[data-is-modal='true'] {
95
- position: fixed;
96
- left: 0;
97
- right: 0;
98
- top: 0;
99
- height: var(--mobile-care-searchbar-height, 100%);
100
- overflow-y: auto;
101
- -webkit-overflow-scrolling: touch;
102
- background-color: white;
103
- z-index: var(--searchbar-z-index);
104
- }
105
- `;
106
- const StyledSearchBarMobileModalHeader = styled__default["default"].section ``;
107
- const StyledHiddenInputMobile = styled__default["default"].input `
108
- position: fixed;
109
- left: -100%;
110
- top: -100%;
111
- `;
112
- const StyledInput = styled__default["default"](index$1.Input) `
113
- #booking-search-bar & {
114
- input {
115
- font-size: 16px;
116
- }
117
- }
118
- `;
119
-
120
- const ClearIcon = ({ className, color }) => (React__default["default"].createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
121
- React__default["default"].createElement("rect", { x: "4", y: "4", width: "16", height: "16", rx: "8", fill: "white" }),
122
- React__default["default"].createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM8.29289 8.29289C8.68342 7.90237 9.31658 7.90237 9.70711 8.29289L12 10.5858L14.2929 8.29289C14.6834 7.90237 15.3166 7.90237 15.7071 8.29289C16.0976 8.68342 16.0976 9.31658 15.7071 9.70711L13.4142 12L15.7071 14.2929C16.0976 14.6834 16.0976 15.3166 15.7071 15.7071C15.3166 16.0976 14.6834 16.0976 14.2929 15.7071L12 13.4142L9.70711 15.7071C9.31658 16.0976 8.68342 16.0976 8.29289 15.7071C7.90237 15.3166 7.90237 14.6834 8.29289 14.2929L10.5858 12L8.29289 9.70711C7.90237 9.31658 7.90237 8.68342 8.29289 8.29289Z", fill: color || 'currentColor' })));
123
- const CloseIcon = ({ className, color }) => (React__default["default"].createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
124
- React__default["default"].createElement("path", { d: "M18 6L6 18", stroke: color || 'currentColor', strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }),
125
- React__default["default"].createElement("path", { d: "M6 6L18 18", stroke: color || 'currentColor', strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })));
126
- const PinIcon = ({ className, color }) => (React__default["default"].createElement("svg", { width: "14", height: "20", viewBox: "0 0 14 20", className: className },
127
- React__default["default"].createElement("path", { d: "M7 0C3.134 0 0 3.134 0 7C0 10.966 4.404 16.82 6.226 19.071C6.626 19.565 7.374 19.565 7.774 19.071C9.596 16.82 14 10.966 14 7C14 3.134 10.866 0 7 0ZM7 9.5C5.619 9.5 4.5 8.381 4.5 7C4.5 5.619 5.619 4.5 7 4.5C8.381 4.5 9.5 5.619 9.5 7C9.5 8.381 8.381 9.5 7 9.5Z", fill: color || 'currentColor' })));
128
- const MagnifierIcon = ({ className, color }) => (React__default["default"].createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
129
- React__default["default"].createElement("path", { d: "M11 18C14.866 18 18 14.866 18 11C18 7.13401 14.866 4 11 4C7.13401 4 4 7.13401 4 11C4 14.866 7.13401 18 11 18Z", stroke: color || 'currentColor', strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
130
- React__default["default"].createElement("path", { d: "M20 20L16 16", stroke: color || 'currentColor', strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })));
131
- const DefaultThumbnailAny = ({ width, height, }) => (React__default["default"].createElement("svg", { width: width || 30, height: height || 30, viewBox: "0 0 30 30", fill: "none" },
132
- React__default["default"].createElement("circle", { cx: "15", cy: "15", r: "15", fill: "#F7F9FC" })));
133
- const DefaultThumbnailDoctor = ({ width, height, }) => (React__default["default"].createElement("svg", { width: width || 32, height: height || 32, viewBox: "0 0 32 32", fill: "none" },
134
- React__default["default"].createElement("g", { clipPath: "url(#clip0_14712_400114)" },
135
- React__default["default"].createElement("rect", { width: "32", height: "32", rx: "16", fill: "#E4E8EC" }),
136
- React__default["default"].createElement("path", { d: "M22.065 9.58305C22.1108 9.80952 22.1431 10.0396 22.1614 10.2722C22.3769 13.0522 22.5858 16.1276 22.5727 17.618C22.5306 20.5688 19.708 21.1325 19.4564 21.1769L19.4495 21.5357L19.5228 23.9014C20.8688 23.9341 22.203 24.1759 23.4772 24.6196C24.5264 24.9739 25.4827 25.5591 26.2757 26.332C27.0688 27.105 27.6783 28.0461 28.0594 29.0858L31.9886 39.2068C31.91 39.3048 30.6939 39.6356 29.4888 39.944C30.1695 42.3315 30.4582 44.8142 30.3432 47.2953C30.2991 48.2666 30.1816 49.264 29.7245 50.1211C29.4508 50.6342 29.0319 51.0912 28.5296 51.3753C28.5099 51.4347 28.4864 51.4928 28.4593 51.5495C28.4293 51.6146 28.3908 51.6756 28.3448 51.7307C28.3293 51.7772 28.3232 51.8406 28.3162 51.9135C28.3004 52.0779 28.2799 52.2909 28.1362 52.4685C28.001 52.6373 27.8519 52.7945 27.6905 52.9386C27.6905 52.9386 27.092 52.9667 26.4133 52.9845L26.458 58.4088H5.7492L6.30965 52.9523L5.66093 53.1637C5.07664 53.3528 4.45628 53.4028 3.84925 53.3099C3.24222 53.2169 2.66526 52.9835 2.1643 52.6283C1.61489 52.2388 1.17445 51.715 0.884966 51.1068C0.595484 50.4987 0.46662 49.8266 0.510669 49.1545L0.644528 47.1369L1.41503 38.3366L1.81323 38.4135L-0.914307 37.8437L-0.402886 36.5663C-0.407359 36.5645 -0.411803 36.5627 -0.416214 36.5608C-0.410804 36.56 -0.40538 36.5594 -0.399946 36.5589L2.05995 30.4146C3.00034 28.0825 4.7421 26.1624 6.97187 24.9999C8.56171 24.176 10.3028 23.6861 12.0882 23.5597L11.788 16.5865C11.1882 16.6507 10.0095 16.5266 9.96087 14.954C9.91229 13.3824 11.0457 13.3171 11.6507 13.3961L11.6445 13.2523C11.5785 12.8433 11.5088 12.439 11.4577 12.2132C11.3782 11.8628 11.2611 11.4953 11.1419 11.1207C10.8794 10.2967 10.6061 9.43855 10.697 8.65293C10.697 8.65293 10.6909 8.00438 11.4565 7.24044C11.3707 6.86644 11.3686 6.47786 11.4507 6.10258C11.5366 5.70965 11.7125 5.34199 11.9645 5.02848C12.2165 4.71497 12.5377 4.46414 12.9029 4.29569C13.2682 4.12725 13.6675 4.04577 14.0696 4.05766C14.2277 4.06393 14.3849 4.08493 14.5418 4.10589C14.7932 4.13945 15.0439 4.17294 15.2971 4.14581C15.7708 4.09409 16.177 3.83884 16.5862 3.58167C16.8357 3.42492 17.0863 3.26745 17.354 3.15494C17.9119 2.93744 18.5266 2.91281 19.1002 3.08497C19.6738 3.25713 20.1733 3.61619 20.5192 4.105C20.5943 4.21716 20.6621 4.33678 20.7298 4.45631C20.9035 4.76299 21.077 5.06915 21.373 5.24769C21.5927 5.38236 21.8482 5.42658 22.1057 5.47114C22.2633 5.49842 22.4216 5.52582 22.5728 5.57417C23.0267 5.71015 23.3999 6.0411 23.6319 6.45436C23.6327 6.40753 23.6317 6.36062 23.629 6.31374C23.6502 6.3657 23.6623 6.42092 23.6649 6.47698C23.6661 6.49165 23.667 6.50632 23.6677 6.521C23.8246 6.82609 23.9058 7.17114 23.8885 7.51347C23.8544 7.93447 23.7053 8.33801 23.4574 8.68001C23.2096 9.02201 22.8725 9.28933 22.483 9.45278C22.3469 9.50712 22.2071 9.55061 22.065 9.58305Z", fill: "white" })),
137
- React__default["default"].createElement("defs", null,
138
- React__default["default"].createElement("clipPath", { id: "clip0_14712_400114" },
139
- React__default["default"].createElement("rect", { width: "32", height: "32", rx: "16", fill: "white" })))));
140
- const DefaultThumbnailService = ({ width, height, }) => (React__default["default"].createElement("svg", { width: width || 30, height: height || 30, viewBox: "0 0 30 30", fill: "none" },
141
- React__default["default"].createElement("circle", { cx: "15", cy: "15", r: "15", fill: "#F7F9FC" }),
142
- React__default["default"].createElement("path", { d: "M14.9998 6.66663C12.2752 6.66663 9.85335 7.97848 8.33317 9.99996H10.5988C11.8 8.94527 13.3625 8.33329 14.9998 8.33329C16.6372 8.33329 18.1997 8.94527 19.4009 9.99996H21.6665C20.1463 7.97848 17.7244 6.66663 14.9998 6.66663ZM7.7863 10.8333C7.07666 13.0403 6.6665 15.5989 6.6665 18.3333C6.6665 20.0846 6.82601 21.7675 7.13525 23.3333H22.8644C23.1737 21.7675 23.3332 20.0846 23.3332 18.3333C23.3332 15.5989 22.923 13.0403 22.2134 10.8333H7.7863ZM14.9998 13.3333C17.3013 13.3333 19.1665 15.1985 19.1665 17.5C19.1665 19.8014 17.3013 21.6666 14.9998 21.6666C12.6984 21.6666 10.8332 19.8014 10.8332 17.5C10.8332 15.1985 12.6984 13.3333 14.9998 13.3333ZM14.1665 15V16.6666H12.4998V18.3333H14.1665V20H15.8332V18.3333H17.4998V16.6666H15.8332V15H14.1665Z", fill: "#BFC5CC" })));
143
-
144
- const StyledLiSkeleton$1 = styled__default["default"].li `
145
- display: flex;
146
- align-items: center;
147
- gap: 12px;
148
- padding: 8px 16px;
149
-
150
- > :first-child {
151
- flex: 1;
152
- }
153
-
154
- > :nth-child(2) {
155
- flex: 6;
156
- }
157
-
158
- & + li::before {
159
- content: '';
160
- position: absolute;
161
- left: 18px;
162
- right: 18px;
163
- top: 0;
164
- height: 1px;
165
- background-color: ${miscTheme.theme.colors.neutral100};
166
- }
167
- `;
168
- const LiSkeleton = ({ count, className }) => {
169
- return (React__default["default"].createElement(React__default["default"].Fragment, null, [...Array(count)].map((__v, i) => (React__default["default"].createElement(StyledLiSkeleton$1, { className: className, key: i },
170
- React__default["default"].createElement(Skeleton__default["default"], { count: 1, height: 32 }),
171
- React__default["default"].createElement(Skeleton__default["default"], { count: 1, height: 24 }))))));
172
- };
173
-
174
- const checkMarkIconUrl = `url("data:image/svg+xml,%3Csvg width='19' height='14' viewBox='0 0 19 14' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.9803 0.990669C16.7205 0.99841 16.4739 1.10699 16.2928 1.2934L5.99984 11.5864L2.70687 8.2934C2.61473 8.19743 2.50436 8.12081 2.38223 8.06802C2.2601 8.01524 2.12867 7.98735 1.99563 7.986C1.86259 7.98464 1.73061 8.00985 1.60743 8.06014C1.48426 8.11043 1.37235 8.18479 1.27827 8.27887C1.1842 8.37295 1.10983 8.48485 1.05954 8.60803C1.00926 8.73121 0.98405 8.86318 0.985403 8.99622C0.986757 9.12926 1.01464 9.26069 1.06743 9.38282C1.12021 9.50495 1.19684 9.61532 1.29281 9.70747L5.29281 13.7075C5.48035 13.8949 5.73467 14.0002 5.99984 14.0002C6.26501 14.0002 6.51933 13.8949 6.70687 13.7075L17.7069 2.70747C17.8514 2.567 17.9501 2.38616 17.99 2.18864C18.03 1.99112 18.0093 1.78614 17.9308 1.60055C17.8523 1.41497 17.7195 1.25744 17.5499 1.14861C17.3803 1.03978 17.1817 0.984729 16.9803 0.990669Z' fill='%232685F1'/%3E%3C/svg%3E%0A")`;
175
- const StyledLocationResultsWrapper = styled__default["default"].div `
176
- display: flex;
177
- position: absolute;
178
- top: 48px;
179
- min-width: 100%;
180
- box-shadow: 0px 24px 32px rgba(0, 0, 0, 0.04),
181
- 0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
182
- 0px 0px 1px rgba(0, 0, 0, 0.04);
183
- border-radius: ${miscTheme.theme.borderRadius};
184
- background-color: white;
185
- z-index: 30;
186
-
187
- ${utils.MediaQueries.tdDown} {
188
- position: relative;
189
- top: 0;
190
- box-shadow: initial;
191
- }
192
- `;
193
- const StyledLocationResultsList = styled__default["default"].ul `
194
- width: 100%;
195
- max-height: 600px;
196
- overflow-y: auto;
197
- `;
198
- const StyledPinIcon$1 = styled__default["default"](PinIcon) `
199
- width: 12px;
200
- height: 18px;
201
- `;
202
- const StyledLocationItem$1 = styled__default["default"].li `
203
- position: relative;
204
- cursor: pointer;
205
- padding: 12px 18px;
206
- display: flex;
207
- align-items: center;
208
- gap: 14px;
209
- overflow: hidden;
210
-
211
- ${({ isSelected }) => isSelected &&
212
- `
213
- &::after {
214
- content: ${checkMarkIconUrl};
215
- top: 50%;
216
- right: 18px;
217
- position: absolute;
218
- transform: translateY(-50%);
219
- }
220
- `}
221
-
222
- & + li::before {
223
- content: '';
224
- position: absolute;
225
- left: 18px;
226
- right: 18px;
227
- top: 0;
228
- height: 1px;
229
- background-color: ${miscTheme.theme.colors.neutral100};
230
- }
231
-
232
- &:not([data-is-denied='true']):hover {
233
- background-color: ${miscTheme.theme.colors.neutral50};
234
- }
235
-
236
- &:last-child:hover {
237
- border-bottom-right-radius: 6px;
238
- border-bottom-left-radius: 6px;
239
- }
240
-
241
- &:first-child:hover {
242
- border-top-right-radius: 6px;
243
- border-top-left-radius: 6px;
244
- }
245
-
246
- &[data-is-denied='true'] {
247
- cursor: not-allowed;
248
- }
249
- `;
250
- const StyledLiSkeleton = styled__default["default"](LiSkeleton) `
251
- &:first-child {
252
- padding-top: 18px;
253
- }
254
- `;
255
-
256
- const LocationResults = ({ cities, isLoading, onLocationClick, selectedLocation, }) => {
257
- const { t, locale } = useTranslations.useTranslations();
258
- const renderContent = () => {
259
- if (isLoading) {
260
- return React__default["default"].createElement(StyledLiSkeleton, { count: 5 });
261
- }
262
- if (!cities || cities.length < 1) {
263
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
264
- React__default["default"].createElement(StyledLocationItem$1, { "data-is-denied": "true" },
265
- React__default["default"].createElement(index$2.Text, { size: "sm", color: "#ccc" }, t('booking.searchBar.noResults')))));
266
- }
267
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
268
- React__default["default"].createElement(StyledLocationItem$1, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
269
- var _a;
270
- if (onLocationClick) {
271
- onLocationClick({
272
- name: t('booking.searchBar.allLocations'),
273
- id: constants.ID_OPTION_ALL_LOCATION,
274
- slug: (_a = constants.LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
275
- });
276
- }
277
- } },
278
- React__default["default"].createElement(StyledPinIcon$1, { color: miscTheme.theme.colors.neutral400 }),
279
- React__default["default"].createElement(index$2.Text, { size: "md" }, t('booking.searchBar.allLocations'))),
280
- cities.map((city) => (React__default["default"].createElement(StyledLocationItem$1, { key: city.id, onClick: (evt) => {
281
- evt.nativeEvent.stopImmediatePropagation();
282
- if (onLocationClick) {
283
- onLocationClick(city);
284
- }
285
- }, role: "button", tabIndex: 0, "aria-label": `Select ${city.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === city.id },
286
- React__default["default"].createElement(StyledPinIcon$1, { color: miscTheme.theme.colors.neutral400 }),
287
- React__default["default"].createElement(index$2.Text, { size: "md" }, city.name))))));
288
- };
289
- return (React__default["default"].createElement(StyledLocationResultsWrapper, { "data-testid": "location-search-results" },
290
- React__default["default"].createElement(StyledLocationResultsList, null, renderContent())));
291
- };
292
-
293
- const EVENT_NAMES = {
294
- TYPE_CHARACTER: 'TYPE_CHARACTER',
295
- REMOVE_CHARACTER: 'REMOVE_CHARACTER',
296
- REMOVE_ALL: 'REMOVE_ALL',
297
- REMOVE_LAST_VISIBLE_NODE: 'REMOVE_LAST_VISIBLE_NODE',
298
- PAUSE_FOR: 'PAUSE_FOR',
299
- CHANGE_DELETE_SPEED: 'CHANGE_DELETE_SPEED',
300
- CHANGE_DELAY: 'CHANGE_DELAY',
301
- PASTE_STRING: 'PASTE_STRING',
302
- };
303
- const getRandomInteger = (min, max) => {
304
- return Math.floor(Math.random() * (max - min + 1)) + min;
305
- };
306
- const VISIBLE_NODE_TYPES = {
307
- TEXT_NODE: 'TEXT_NODE',
308
- };
309
- class Typewriter {
310
- constructor(options) {
311
- this.state = {
312
- lastFrameTime: null,
313
- pauseUntil: null,
314
- eventQueue: [],
315
- eventLoop: null,
316
- eventLoopPaused: false,
317
- reverseCalledEvents: [],
318
- calledEvents: [],
319
- visibleNodes: [],
320
- initialOptions: null,
321
- };
322
- this.options = {
323
- strings: null,
324
- delay: 'natural',
325
- pauseFor: 1500,
326
- deleteSpeed: 'natural',
327
- loop: false,
328
- autoStart: false,
329
- stringSplitter: null,
330
- onCreateTextNode: null,
331
- onRemoveNode: null,
332
- };
333
- this.start = () => {
334
- this.state.eventLoopPaused = false;
335
- this.runEventLoop();
336
- return this;
337
- };
338
- this.pause = () => {
339
- this.state.eventLoopPaused = true;
340
- return this;
341
- };
342
- this.stop = () => {
343
- if (this.state.eventLoop) {
344
- window.cancelAnimationFrame(this.state.eventLoop);
345
- this.state.eventLoop = null;
346
- }
347
- return this;
348
- };
349
- this.pauseFor = (ms) => {
350
- this.addEventToQueue(EVENT_NAMES.PAUSE_FOR, { ms });
351
- return this;
352
- };
353
- this.typeOutAllStrings = () => {
354
- if (typeof this.options.strings === 'string') {
355
- this.typeString(this.options.strings).pauseFor(this.options.pauseFor);
356
- return this;
357
- }
358
- this.options.strings.forEach((string) => {
359
- this.typeString(string)
360
- .pauseFor(this.options.pauseFor)
361
- .deleteAll(this.options.deleteSpeed);
362
- });
363
- return this;
364
- };
365
- this.typeString = (string, node = null) => {
366
- if (string) {
367
- const { stringSplitter } = this.options || {};
368
- const characters = typeof stringSplitter === 'function'
369
- ? stringSplitter(string)
370
- : string.split('');
371
- this.typeCharacters(characters, node);
372
- }
373
- return this;
374
- };
375
- this.pasteString = (string, node = null) => {
376
- if (string) {
377
- this.addEventToQueue(EVENT_NAMES.PASTE_STRING, {
378
- character: string,
379
- node,
380
- });
381
- }
382
- return this;
383
- };
384
- this.deleteAll = (speed = 'natural') => {
385
- this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, { speed });
386
- return this;
387
- };
388
- this.changeDeleteSpeed = (speed) => {
389
- if (!speed) {
390
- throw new Error('Must provide new delete speed');
391
- }
392
- this.addEventToQueue(EVENT_NAMES.CHANGE_DELETE_SPEED, { speed });
393
- return this;
394
- };
395
- this.changeDelay = (delay) => {
396
- if (!delay) {
397
- throw new Error('Must provide new delay');
398
- }
399
- this.addEventToQueue(EVENT_NAMES.CHANGE_DELAY, { delay });
400
- return this;
401
- };
402
- this.deleteChars = (amount) => {
403
- if (!amount) {
404
- throw new Error('Must provide amount of characters to delete');
405
- }
406
- for (let i = 0; i < amount; i++) {
407
- this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
408
- }
409
- return this;
410
- };
411
- this.typeCharacters = (characters, node = null) => {
412
- if (!characters || !Array.isArray(characters)) {
413
- throw new Error('Characters must be an array');
414
- }
415
- characters.forEach((character) => {
416
- this.addEventToQueue(EVENT_NAMES.TYPE_CHARACTER, { character, node });
417
- });
418
- return this;
419
- };
420
- this.removeCharacters = (characters) => {
421
- if (!characters || !Array.isArray(characters)) {
422
- throw new Error('Characters must be an array');
423
- }
424
- characters.forEach(() => {
425
- this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
426
- });
427
- return this;
428
- };
429
- this.addEventToQueue = (eventName, eventArgs, prepend = false) => {
430
- return this.addEventToStateProperty(eventName, eventArgs, prepend, 'eventQueue');
431
- };
432
- this.addReverseCalledEvent = (eventName, eventArgs, prepend = false) => {
433
- const { loop } = this.options;
434
- if (!loop) {
435
- return this;
436
- }
437
- return this.addEventToStateProperty(eventName, eventArgs, prepend, 'reverseCalledEvents');
438
- };
439
- this.addEventToStateProperty = (eventName, eventArgs, prepend = false, property) => {
440
- const eventItem = {
441
- eventName,
442
- eventArgs: eventArgs || {},
443
- };
444
- if (prepend) {
445
- this.state[property] = [eventItem, ...this.state[property]];
446
- }
447
- else {
448
- this.state[property] = [...this.state[property], eventItem];
449
- }
450
- return this;
451
- };
452
- this.runEventLoop = () => {
453
- if (!this.state.lastFrameTime) {
454
- this.state.lastFrameTime = Date.now();
455
- }
456
- // Setup variables to calculate if this frame should run
457
- const nowTime = Date.now();
458
- const delta = nowTime - this.state.lastFrameTime;
459
- if (!this.state.eventQueue.length) {
460
- if (!this.options.loop) {
461
- return;
462
- }
463
- // Reset event queue if we are looping
464
- this.state.eventQueue = [...this.state.calledEvents];
465
- this.state.calledEvents = [];
466
- this.options = Object.assign({}, this.state.initialOptions);
467
- }
468
- // Request next frame
469
- this.state.eventLoop = window.requestAnimationFrame(this.runEventLoop);
470
- // Check if event loop is paused
471
- if (this.state.eventLoopPaused) {
472
- return;
473
- }
474
- // Check if state has pause until time
475
- if (this.state.pauseUntil) {
476
- // Check if event loop should be paused
477
- if (nowTime < this.state.pauseUntil) {
478
- return;
479
- }
480
- // Reset pause time
481
- this.state.pauseUntil = null;
482
- }
483
- // Make a clone of event queue
484
- const eventQueue = [...this.state.eventQueue];
485
- // Get first event from queue
486
- const currentEvent = eventQueue.shift();
487
- // Setup delay variable
488
- let delay = 0;
489
- // Check if frame should run or be
490
- // skipped based on fps interval
491
- if (currentEvent.eventName === EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE ||
492
- currentEvent.eventName === EVENT_NAMES.REMOVE_CHARACTER) {
493
- delay =
494
- this.options.deleteSpeed === 'natural'
495
- ? getRandomInteger(40, 80)
496
- : this.options.deleteSpeed;
497
- }
498
- else {
499
- delay =
500
- this.options.delay === 'natural'
501
- ? getRandomInteger(120, 160)
502
- : this.options.delay;
503
- }
504
- if (delta <= delay) {
505
- return;
506
- }
507
- // Get current event args
508
- const { eventName, eventArgs } = currentEvent;
509
- // Run item from event loop
510
- switch (eventName) {
511
- case EVENT_NAMES.PASTE_STRING:
512
- case EVENT_NAMES.TYPE_CHARACTER: {
513
- const { character } = eventArgs;
514
- const textNode = document.createTextNode(character);
515
- let textNodeToUse = textNode;
516
- if (this.options.onCreateTextNode &&
517
- typeof this.options.onCreateTextNode === 'function') {
518
- textNodeToUse = this.options.onCreateTextNode(character, textNode);
519
- }
520
- this.state.visibleNodes = [
521
- ...this.state.visibleNodes,
522
- {
523
- type: VISIBLE_NODE_TYPES.TEXT_NODE,
524
- character,
525
- node: textNodeToUse,
526
- },
527
- ];
528
- break;
529
- }
530
- case EVENT_NAMES.REMOVE_CHARACTER: {
531
- eventQueue.unshift({
532
- eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
533
- eventArgs: { removingCharacterNode: true },
534
- });
535
- break;
536
- }
537
- case EVENT_NAMES.PAUSE_FOR: {
538
- const { ms } = currentEvent.eventArgs;
539
- this.state.pauseUntil = Date.now() + parseInt(ms);
540
- break;
541
- }
542
- case EVENT_NAMES.REMOVE_ALL: {
543
- const { visibleNodes } = this.state;
544
- const { speed } = eventArgs;
545
- const removeAllEventItems = [];
546
- if (speed) {
547
- removeAllEventItems.push({
548
- eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
549
- eventArgs: { speed, temp: true },
550
- });
551
- }
552
- for (let i = 0, length = visibleNodes.length; i < length; i++) {
553
- removeAllEventItems.push({
554
- eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
555
- eventArgs: { removingCharacterNode: false },
556
- });
557
- }
558
- if (speed) {
559
- removeAllEventItems.push({
560
- eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
561
- eventArgs: { speed: this.options.deleteSpeed, temp: true },
562
- });
563
- }
564
- eventQueue.unshift(...removeAllEventItems);
565
- break;
566
- }
567
- case EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE: {
568
- if (this.state.visibleNodes.length) {
569
- const { node, character } = this.state.visibleNodes.pop();
570
- if (this.options.onRemoveNode &&
571
- typeof this.options.onRemoveNode === 'function') {
572
- this.options.onRemoveNode({
573
- node,
574
- character,
575
- });
576
- }
577
- if (node) {
578
- node.parentNode.removeChild(node);
579
- }
580
- }
581
- break;
582
- }
583
- case EVENT_NAMES.CHANGE_DELETE_SPEED: {
584
- this.options.deleteSpeed = currentEvent.eventArgs.speed;
585
- break;
586
- }
587
- case EVENT_NAMES.CHANGE_DELAY: {
588
- this.options.delay = currentEvent.eventArgs.delay;
589
- break;
590
- }
591
- }
592
- // Add que item to called queue if we are looping
593
- if (this.options.loop) {
594
- if (currentEvent.eventName !== EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE &&
595
- !(currentEvent.eventArgs && currentEvent.eventArgs.temp)) {
596
- this.state.calledEvents = [...this.state.calledEvents, currentEvent];
597
- }
598
- }
599
- // Replace state event queue with cloned queue
600
- this.state.eventQueue = eventQueue;
601
- // Set last frame time so it can be used to calculate next frame
602
- this.state.lastFrameTime = nowTime;
603
- };
604
- if (options) {
605
- this.options = Object.assign(Object.assign({}, this.options), options);
606
- }
607
- this.state.initialOptions = Object.assign({}, this.options);
608
- this.init();
609
- }
610
- init() {
611
- this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, null, true);
612
- if (this.options.autoStart === true && this.options.strings) {
613
- this.typeOutAllStrings().start();
614
- }
615
- }
616
- }
617
-
618
- function useAnimatedPlaceholder({ inputRef, wrapperRef, disabled, }) {
619
- const { t, locale } = useTranslations.useTranslations();
620
- const values = React.useMemo(() => {
621
- if (disabled) {
622
- return [];
623
- }
624
- const shuffleKeys = [
625
- 'booking.searchBar.placeholder.hospital',
626
- 'booking.searchBar.placeholder.doctor',
627
- ];
628
- if (locale !== 'zh-TW') {
629
- shuffleKeys.push('booking.searchBar.placeholder.specialty', 'booking.searchBar.placeholder.service');
630
- }
631
- return shuffle__default["default"](shuffleKeys).map((s) => t(s));
632
- }, [t, locale]);
633
- React.useEffect(() => {
634
- if (disabled) {
635
- return;
636
- }
637
- const input = getInput();
638
- if (input) {
639
- input.placeholder = '';
640
- new Typewriter({
641
- strings: values,
642
- autoStart: true,
643
- loop: true,
644
- delay: 32,
645
- deleteSpeed: 32,
646
- pauseFor: 1500,
647
- onCreateTextNode: customNodeCreator,
648
- onRemoveNode: onRemoveNode,
649
- });
650
- }
651
- }, [inputRef, wrapperRef]);
652
- function customNodeCreator(character) {
653
- const input = getInput();
654
- if (input) {
655
- input.placeholder = input.placeholder + character;
656
- }
657
- return null;
658
- }
659
- function onRemoveNode() {
660
- const input = getInput();
661
- if (input) {
662
- input.placeholder = input.placeholder.slice(0, -1);
663
- }
664
- }
665
- function getInput() {
666
- if (inputRef && inputRef.current) {
667
- return inputRef.current;
668
- }
669
- else if (wrapperRef && wrapperRef.current) {
670
- return wrapperRef.current.querySelector('input') || null;
671
- }
672
- return null;
673
- }
674
- return;
675
- }
676
-
677
- const StyledFakeInputSearchMobile = styled__default["default"].div `
678
- user-select: none;
679
- input {
680
- pointer-events: none;
681
- background-color: white;
682
- }
683
- `;
684
- function MobileFakeInput({ focused, value = '', onClick, trackingAttributes, inputSearchPlaceholder, }) {
685
- const { t } = useTranslations.useTranslations();
686
- const wrapperRef = React.useRef(null);
687
- useAnimatedPlaceholder({ wrapperRef, disabled: !!inputSearchPlaceholder });
688
- const gaAttributes = React.useMemo(() => {
689
- if (trackingAttributes) {
690
- return {
691
- 'data-event-category': trackingAttributes.dataEventCategory,
692
- 'data-event-action': trackingAttributes.dataEventAction,
693
- 'data-event-label': trackingAttributes.dataEventLabel,
694
- };
695
- }
696
- else {
697
- return {};
698
- }
699
- }, [trackingAttributes]);
700
- return (React__default["default"].createElement(StyledFakeInputSearchMobile, Object.assign({ onClick: () => onClick && onClick(), ref: wrapperRef }, gaAttributes),
701
- React__default["default"].createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, name: "booking-search-placeholder", displayIcon: React__default["default"].createElement(MagnifierIcon, { color: miscTheme.theme.colors.gray400 }), placeholder: t('booking.searchBar.searchInput.placeholder'), value: value, size: "md" })));
702
- }
703
-
704
- const StyledTopBar = styled__default["default"].header `
705
- display: flex;
706
- height: 64px;
707
- align-items: center;
708
- justify-content: space-between;
709
- margin: 0 auto;
710
- position: sticky;
711
- z-index: 99;
712
- background-color: white;
713
- top: 0;
714
- left: 0;
715
- `;
716
- const StyledTopBarHeaderRight = styled__default["default"].div `
717
- display: inline-flex;
718
- flex: 1;
719
- justify-content: flex-end;
720
- cursor: pointer;
721
- text-decoration: underline;
722
- `;
723
- const StyledTopBarIcon = styled__default["default"].div `
724
- display: flex;
725
- align-items: center;
726
- margin-left: 16px;
727
- cursor: pointer;
728
- `;
729
- const StyledTopbarHeading = styled__default["default"].div `
730
- width: 100%;
731
- margin-left: 24px;
732
- `;
733
- const StyledTopbarHeadingText = styled__default["default"](index$2.Text) `
734
- color: ${miscTheme.theme.colors.secondaryDark};
735
- text-align: start;
736
- `;
737
-
738
- const MobileTopBar = ({ className, onLeftClick, headingText, onRightClick, iconLeft, textRight, }) => {
739
- return (React__default["default"].createElement(StyledTopBar, { className: className },
740
- React__default["default"].createElement(StyledTopBarIcon, { onClick: onLeftClick }, iconLeft || React__default["default"].createElement(CloseIcon, { color: miscTheme.theme.colors.gray800 })),
741
- React__default["default"].createElement(StyledTopbarHeading, null,
742
- React__default["default"].createElement(StyledTopbarHeadingText, { size: "md", weight: "bold" }, headingText)),
743
- React__default["default"].createElement(StyledTopBarHeaderRight, { onClick: onRightClick }, textRight && React__default["default"].createElement("p", null, textRight))));
744
- };
745
-
746
- const SEARCH_KEYWORD_MIN_LENGTH$1 = {
747
- 'en-PH': 3,
748
- 'tl-PH': 2,
749
- 'id-ID': 3,
750
- 'vi-VN': 2,
751
- 'zh-TW': 0,
752
- 'ms-MY': 2,
753
- };
754
-
755
- const initialState$1 = {
756
- isMobile: false,
757
- isDebug: false,
758
- navigateTo: null,
759
- geoLocationPermission: 'unset',
760
- geoLocationCoordinates: null,
761
- focused: 'none',
762
- searchLocationKeywords: '',
763
- searchKeywords: '',
764
- selectedLocation: null,
765
- defaultCity: null,
766
- initialCities: [],
767
- cities: [],
768
- searchResults: [],
769
- initialSearchResults: [],
770
- isLoadingCities: false,
771
- isLoadingSearchResults: false,
772
- isMobileModalOpened: false,
773
- initialSelectedCity: null,
774
- autoCompleteDisabled: false,
775
- inputSearchPlaceholder: '',
776
- locale: 'vi-VN',
777
- };
778
- var ActionTypes$1;
779
- (function (ActionTypes) {
780
- ActionTypes["NavigateTo"] = "navigate to url";
781
- ActionTypes["ClickOutsideInputLocation"] = "click outside input location";
782
- ActionTypes["ClickOutsideInputSearch"] = "click outside input search";
783
- ActionTypes["SelectCurrentLocation"] = "select current location";
784
- ActionTypes["FocusInputLocation"] = "focus input location";
785
- ActionTypes["FocusInputSearch"] = "focus input search";
786
- ActionTypes["ChangeInputLocation"] = "change input location";
787
- ActionTypes["ChangeInputSearch"] = "change input search";
788
- ActionTypes["ClearInputLocation"] = "clear input location";
789
- ActionTypes["ClearInputSearch"] = "clear input search";
790
- ActionTypes["SelectLocation"] = "select location";
791
- ActionTypes["FetchCitiesStart"] = "fetch cities start";
792
- ActionTypes["FetchCitiesFinish"] = "fetch cities finish";
793
- ActionTypes["FetchSearchResultsStart"] = "fetch search results start";
794
- ActionTypes["FetchSearchResultsComplete"] = "fetch search results complete";
795
- ActionTypes["FetchSearchResultsFinish"] = "fetch search results finish";
796
- ActionTypes["FetchCitiesByGeoIpComplete"] = "fetch cities by geo IP finish";
797
- ActionTypes["FetchCitiesByKeywordComplete"] = "fetch cities by keyword finish";
798
- ActionTypes["DisplayInitialCities"] = "display initial cities";
799
- ActionTypes["DisplayInitialSearchResults"] = "display initial search results";
800
- ActionTypes["GrantGeoLocationPermission"] = "grant geolocation permission";
801
- ActionTypes["DenyGeoLocationPermission"] = "deny geolocation permission";
802
- ActionTypes["OpenMobileModal"] = "open mobile modal";
803
- ActionTypes["CloseMobileModal"] = "close mobile modal";
804
- ActionTypes["UpdateInitialSearchValue"] = "update initial search value";
805
- ActionTypes["SelectSearchResult"] = "select search result";
806
- ActionTypes["SetInputSearchPlaceholder"] = "set input search placeholder";
807
- })(ActionTypes$1 || (ActionTypes$1 = {}));
808
- function resetSearchLocationKeywords$1(state) {
809
- const { selectedLocation, searchLocationKeywords } = state;
810
- if (selectedLocation && searchLocationKeywords !== selectedLocation.name) {
811
- return Object.assign(Object.assign({}, state), { searchLocationKeywords: selectedLocation.name });
812
- }
813
- return state;
814
- }
815
- function reducer$1(state, action) {
816
- var _a;
817
- if (state.isDebug) {
818
- console.log('bookingSearchBar', { action, state });
819
- }
820
- switch (action.type) {
821
- case ActionTypes$1.NavigateTo:
822
- return Object.assign(Object.assign({}, state), { navigateTo: action.payload, focused: 'none', isMobileModalOpened: false });
823
- case ActionTypes$1.ClickOutsideInputLocation: {
824
- if (state.isMobile || state.focused !== 'location') {
825
- return state;
826
- }
827
- return resetSearchLocationKeywords$1(Object.assign(Object.assign({}, state), { focused: 'none' }));
828
- }
829
- case ActionTypes$1.ClickOutsideInputSearch: {
830
- if (state.isMobile || state.focused !== 'search') {
831
- return state;
832
- }
833
- return Object.assign(Object.assign({}, state), { focused: 'none' });
834
- }
835
- case ActionTypes$1.FocusInputLocation: {
836
- const nextState = Object.assign(Object.assign({}, state), { focused: 'location' });
837
- if (((_a = state.selectedLocation) === null || _a === void 0 ? void 0 : _a.id) === constants.ID_OPTION_CURRENT_LOCATION) {
838
- nextState.searchLocationKeywords = '';
839
- }
840
- return nextState;
841
- }
842
- case ActionTypes$1.FocusInputSearch:
843
- const nextState = Object.assign(Object.assign({}, state), { focused: 'search' });
844
- if (state.isMobile) {
845
- return resetSearchLocationKeywords$1(nextState);
846
- }
847
- return nextState;
848
- case ActionTypes$1.ChangeInputLocation:
849
- return Object.assign(Object.assign({}, state), { searchLocationKeywords: action.payload });
850
- case ActionTypes$1.ChangeInputSearch: {
851
- const keyword = action.payload;
852
- return Object.assign(Object.assign({}, state), { searchKeywords: keyword, isLoadingSearchResults: keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale] });
853
- }
854
- case ActionTypes$1.SelectCurrentLocation:
855
- return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
856
- case ActionTypes$1.ClearInputLocation:
857
- return Object.assign(Object.assign({}, state), { focused: 'location', cities: state.initialCities, searchLocationKeywords: '' });
858
- case ActionTypes$1.ClearInputSearch:
859
- return Object.assign(Object.assign({}, state), { focused: 'search', searchKeywords: '' });
860
- case ActionTypes$1.SelectLocation:
861
- return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
862
- case ActionTypes$1.SelectSearchResult:
863
- return Object.assign(Object.assign({}, state), { searchKeywords: action.payload.name, isMobileModalOpened: false, focused: 'none', navigateTo: action.payload.url });
864
- case ActionTypes$1.FetchCitiesStart:
865
- return Object.assign(Object.assign({}, state), { isLoadingCities: true });
866
- case ActionTypes$1.FetchCitiesFinish:
867
- return Object.assign(Object.assign({}, state), { isLoadingCities: false });
868
- case ActionTypes$1.FetchSearchResultsStart:
869
- return Object.assign(Object.assign({}, state), { isLoadingSearchResults: true });
870
- case ActionTypes$1.FetchSearchResultsFinish:
871
- return Object.assign(Object.assign({}, state), { isLoadingSearchResults: false });
872
- case ActionTypes$1.FetchSearchResultsComplete: {
873
- const nextState = Object.assign(Object.assign({}, state), { searchResults: action.payload });
874
- if (state.initialSearchResults.length === 0) {
875
- nextState.initialSearchResults = action.payload;
876
- }
877
- return nextState;
878
- }
879
- case ActionTypes$1.FetchCitiesByGeoIpComplete: {
880
- let { cities } = action.payload;
881
- const { default: defaultCity } = action.payload;
882
- cities = cities.filter((c) => c.id !== defaultCity.id);
883
- cities.unshift(defaultCity);
884
- if (state.initialSelectedCity &&
885
- !cities.find((c) => c.id === state.initialSelectedCity.id)) {
886
- cities.unshift(state.initialSelectedCity);
887
- }
888
- const nextState = Object.assign(Object.assign({}, state), { defaultCity, initialCities: cities, cities });
889
- if (state.geoLocationPermission === 'denied' &&
890
- !state.initialSelectedCity) {
891
- nextState.selectedLocation = defaultCity;
892
- nextState.searchLocationKeywords = defaultCity.name;
893
- }
894
- return nextState;
895
- }
896
- case ActionTypes$1.FetchCitiesByKeywordComplete:
897
- return Object.assign(Object.assign({}, state), { cities: action.payload });
898
- case ActionTypes$1.DisplayInitialCities:
899
- return Object.assign(Object.assign({}, state), { cities: state.initialCities });
900
- case ActionTypes$1.DisplayInitialSearchResults:
901
- return Object.assign(Object.assign({}, state), { searchResults: state.initialSearchResults, isLoadingSearchResults: false });
902
- case ActionTypes$1.GrantGeoLocationPermission:
903
- return Object.assign(Object.assign({}, state), { geoLocationPermission: 'granted', geoLocationCoordinates: action.payload });
904
- case ActionTypes$1.DenyGeoLocationPermission:
905
- return Object.assign(Object.assign({}, state), { geoLocationPermission: 'denied', geoLocationCoordinates: null });
906
- case ActionTypes$1.OpenMobileModal:
907
- return Object.assign(Object.assign({}, state), { isMobileModalOpened: true });
908
- case ActionTypes$1.CloseMobileModal:
909
- return Object.assign(Object.assign({}, state), { isMobileModalOpened: false });
910
- case ActionTypes$1.UpdateInitialSearchValue:
911
- return Object.assign(Object.assign({}, state), { searchKeywords: action.payload });
912
- case ActionTypes$1.SetInputSearchPlaceholder:
913
- return Object.assign(Object.assign({}, state), { inputSearchPlaceholder: action.payload });
914
- default:
915
- return state;
916
- }
917
- }
918
-
919
- const StyledSearchBarInputsWrapper = styled__default["default"].div `
920
- display: flex;
921
- gap: 16px;
922
- ${utils.MediaQueries.mbDown} {
923
- flex-direction: column;
924
- padding: 14px;
925
- background-color: ${miscTheme.theme.colors.primary50};
926
-
927
- input {
928
- filter: drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.04))
929
- drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.06))
930
- drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.04));
931
- }
932
- }
933
-
934
- input {
935
- background-color: white;
936
- }
937
- `;
938
- const StyledInputWrapper = styled__default["default"].div `
939
- position: relative;
940
- `;
941
- const StyledInputLocationWrapper = styled__default["default"](StyledInputWrapper) `
942
- flex: 1;
943
- `;
944
- const StyledInputSearchWrapper = styled__default["default"](StyledInputWrapper) `
945
- flex: 2;
946
- `;
947
- const StyledClearIcon = styled__default["default"](ClearIcon) `
948
- display: none;
949
- &.shown {
950
- display: block;
951
- }
952
- `;
953
-
954
- const SearchIcon = () => (React__default["default"].createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
955
- React__default["default"].createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.97887 8.15493C2.97887 5.29627 5.29627 2.97887 8.15493 2.97887C11.0136 2.97887 13.331 5.29627 13.331 8.15493C13.331 11.0136 11.0136 13.331 8.15493 13.331C5.29627 13.331 2.97887 11.0136 2.97887 8.15493ZM8.15493 1.5C4.47951 1.5 1.5 4.47951 1.5 8.15493C1.5 11.8303 4.47951 14.8099 8.15493 14.8099C9.72624 14.8099 11.1704 14.2653 12.3089 13.3546L15.2377 16.2834C15.5265 16.5722 15.9947 16.5722 16.2834 16.2834C16.5722 15.9947 16.5722 15.5265 16.2834 15.2377L13.3546 12.3089C14.2653 11.1704 14.8099 9.72624 14.8099 8.15493C14.8099 4.47951 11.8303 1.5 8.15493 1.5Z", fill: "white" })));
956
- const StyledSearchIcon = styled__default["default"].button `
957
- min-height: 100%;
958
- border-radius: 6px;
959
- background-color: ${miscTheme.theme.colors.primaryBase};
960
- display: flex;
961
- justify-content: center;
962
- align-items: center;
963
- gap: 11px;
964
- cursor: pointer;
965
- flex: 0.3;
966
-
967
- ${utils.MediaQueries.mbDown} {
968
- --margin: 16px;
969
- min-height: 44px;
970
- margin: var(--margin);
971
- width: calc(100% - var(--margin) * 2);
972
- position: absolute;
973
- bottom: 0;
974
- }
975
-
976
- &:hover {
977
- background-color: ${miscTheme.theme.colors.primaryHover};
978
- }
979
-
980
- &:active {
981
- background-color: ${miscTheme.theme.colors.primaryActive};
982
- }
983
-
984
- &:focus-visible {
985
- outline: 1px solid black;
986
- }
987
- `;
988
- const StyledText$1 = styled__default["default"](index$2.Text) `
989
- font-weight: ${miscTheme.theme.sizes.fwSemiBold};
990
- `;
991
- const SearchButton = ({ onClick }) => {
992
- const { t } = useTranslations.useTranslations();
993
- const title = t('booking.searchBar.searchButton');
994
- return (React__default["default"].createElement(StyledSearchIcon, { onClick: onClick, title: title },
995
- React__default["default"].createElement(SearchIcon, null),
996
- React__default["default"].createElement(StyledText$1, { size: "s3", color: "white" }, title)));
997
- };
998
-
999
- function SearchInputs$1({ isMobile, state, dispatch, debouncedFetchCitiesByKeyword, debouncedFetchSearchResults, focusLocationInput, focusSearchInput, renderLocationResults, renderSearchResults, locationTrackingAttributes, trackingAttributes, onSearch, initalSearchValue, }) {
1000
- const inputLocationWrapperRef = React.useRef(null);
1001
- const inputSearchWrapperRef = React.useRef(null);
1002
- const { focused, searchLocationKeywords, geoLocationPermission, selectedLocation, searchKeywords, inputSearchPlaceholder, } = state;
1003
- const { t } = useTranslations.useTranslations();
1004
- useAnimatedPlaceholder({
1005
- wrapperRef: inputSearchWrapperRef,
1006
- disabled: !!inputSearchPlaceholder,
1007
- });
1008
- useOutsideClick.useOutsideClick(inputLocationWrapperRef, () => {
1009
- if (!isMobile) {
1010
- dispatch({ type: ActionTypes$1.ClickOutsideInputLocation });
1011
- }
1012
- });
1013
- useOutsideClick.useOutsideClick(inputSearchWrapperRef, () => {
1014
- if (!isMobile) {
1015
- dispatch({ type: ActionTypes$1.ClickOutsideInputSearch });
1016
- }
1017
- });
1018
- function handleLocationInputClear() {
1019
- dispatch({ type: ActionTypes$1.ClearInputLocation });
1020
- debouncedFetchCitiesByKeyword.cancel();
1021
- focusLocationInput();
1022
- }
1023
- function handleSearchInputClear() {
1024
- dispatch({ type: ActionTypes$1.ClearInputSearch });
1025
- debouncedFetchSearchResults.cancel();
1026
- debouncedFetchSearchResults('', state);
1027
- focusSearchInput();
1028
- }
1029
- const searchInputPinIconColor = React.useMemo(() => {
1030
- if (geoLocationPermission === 'granted' &&
1031
- (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === constants.ID_OPTION_CURRENT_LOCATION) {
1032
- return miscTheme.theme.colors.primaryBase;
1033
- }
1034
- else {
1035
- return miscTheme.theme.colors.gray400;
1036
- }
1037
- }, [geoLocationPermission, selectedLocation]);
1038
- const handleSearchInputChange = React.useCallback(function handleSearchInputChange(value) {
1039
- dispatch({ type: ActionTypes$1.ChangeInputSearch, payload: value });
1040
- if (typeof onSearch === 'function') {
1041
- return;
1042
- }
1043
- if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale] ||
1044
- initalSearchValue) {
1045
- debouncedFetchSearchResults(value.trim(), state);
1046
- }
1047
- else {
1048
- debouncedFetchSearchResults.cancel();
1049
- dispatch({ type: ActionTypes$1.DisplayInitialSearchResults });
1050
- }
1051
- }, [dispatch, state]);
1052
- const handleSearchLocationInputChange = React.useCallback(function handleSearchLocationInputChange(value) {
1053
- dispatch({ type: ActionTypes$1.ChangeInputLocation, payload: value });
1054
- if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale]) {
1055
- debouncedFetchCitiesByKeyword(value.trim());
1056
- }
1057
- else {
1058
- debouncedFetchCitiesByKeyword.cancel();
1059
- dispatch({ type: ActionTypes$1.DisplayInitialCities });
1060
- }
1061
- }, [debouncedFetchCitiesByKeyword, dispatch]);
1062
- const handleKeyPress = (e) => {
1063
- if (state.autoCompleteDisabled && e.key === 'Enter' && onSearch) {
1064
- onSearch({
1065
- cityId: state.selectedLocation.id,
1066
- keyword: searchKeywords,
1067
- });
1068
- }
1069
- };
1070
- return (React__default["default"].createElement(StyledSearchBarInputsWrapper, null,
1071
- React__default["default"].createElement(StyledInputLocationWrapper, { ref: inputLocationWrapperRef },
1072
- React__default["default"].createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, placeholder: t('booking.searchBar.locationPlaceholder'), autoComplete: "off", name: "search-location", displayIcon: React__default["default"].createElement(PinIcon, { className: "location-pin-icon", color: searchInputPinIconColor }), actionIcon: React__default["default"].createElement(StyledClearIcon, { color: miscTheme.theme.colors.gray300, className: searchLocationKeywords !== '' ? 'shown' : '' }), onActionClick: handleLocationInputClear, value: searchLocationKeywords, onChange: handleSearchLocationInputChange, onFocus: () => dispatch({ type: ActionTypes$1.FocusInputLocation }), size: "md", trackingAttributes: locationTrackingAttributes }),
1073
- !isMobile && renderLocationResults()),
1074
- React__default["default"].createElement(StyledInputSearchWrapper, { ref: inputSearchWrapperRef },
1075
- React__default["default"].createElement(StyledInput, { placeholder: inputSearchPlaceholder ||
1076
- t('booking.searchBar.searchInput.placeholder'), autoComplete: "off", name: "search-results", actionIcon: React__default["default"].createElement(StyledClearIcon, { color: miscTheme.theme.colors.gray300, className: searchKeywords !== '' ? 'shown' : '' }), onActionClick: handleSearchInputClear, value: searchKeywords, onChange: handleSearchInputChange, onFocus: () => dispatch({ type: ActionTypes$1.FocusInputSearch }), inputClassName: focused === 'search' ? 'focused' : undefined, size: "md", trackingAttributes: trackingAttributes, onKeyPress: handleKeyPress, enterKeyHint: state.autoCompleteDisabled ? 'search' : undefined }),
1077
- !isMobile && renderSearchResults()),
1078
- state.autoCompleteDisabled && !state.isMobile && (React__default["default"].createElement(SearchButton, { onClick: () => {
1079
- onSearch({
1080
- cityId: state.selectedLocation.id,
1081
- keyword: searchKeywords,
1082
- });
1083
- } }))));
1084
- }
1085
-
1086
- const DoctorIcon$1 = () => (React__default["default"].createElement("svg", { width: "14", height: "18", viewBox: "0 0 14 18" },
1087
- React__default["default"].createElement("path", { d: "M7 .667c-1.702 0-3.36.146-4.48.365a1.67 1.67 0 0 0-1.353 1.64v2.162c0 .459.374.833.833.833h10a.835.835 0 0 0 .833-.833V2.698c0-.804-.566-1.487-1.354-1.64C10.356.84 8.693.667 7 .667m-.833.833h1.666v.834h.834V4h-.834v.834H6.167V4h-.834V2.334h.834zm-4.74 5a8 8 0 0 0-.234 1.276c-.046.404-.137 1.478-.13 1.589a1.94 1.94 0 0 0-.73 1.536c0 .935.645 1.735 1.51 1.928.902 2.19 2.71 4.505 5.157 4.505s4.255-2.338 5.156-4.532a1.935 1.935 0 0 0 1.51-1.9 1.94 1.94 0 0 0-.729-1.537c.007-.11-.08-1.205-.13-1.615a8.4 8.4 0 0 0-.234-1.25H5.359c1.169 1.706 3.916.687 5.678 1.12.537 1.172.13 2.813.13 2.813l.65.208c.095.03.183.114.183.26 0 .157-.114.293-.312.287l-.678-.104-.234.65C9.966 14.05 8.413 15.668 7 15.668s-2.965-1.618-3.776-3.932l-.26-.651-.704.104c-.143 0-.26-.13-.26-.287a.26.26 0 0 1 .182-.26l.651-.208c-.1.12-.423-1.729 0-2.396.759-.524 1.394-.16 2.292-1.537zm3.75 2.552c-.605 0-1.094.502-1.094 1.12s.489 1.12 1.094 1.12 1.094-.501 1.094-1.12c0-.618-.488-1.12-1.094-1.12m3.646 0c-.606 0-1.094.502-1.094 1.12s.488 1.12 1.094 1.12c.605 0 1.094-.501 1.094-1.12 0-.618-.489-1.12-1.094-1.12", fill: "#9AA2AC" })));
1088
- const ServiceIcon$1 = () => (React__default["default"].createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
1089
- React__default["default"].createElement("path", { d: "M9 .667A8.33 8.33 0 0 0 2.333 4H4.6A6.7 6.7 0 0 1 9 2.334c1.637 0 3.2.612 4.401 1.666h2.266A8.33 8.33 0 0 0 9 .667M1.786 4.834c-.71 2.207-1.12 4.765-1.12 7.5 0 1.751.16 3.434.47 5h15.729c.309-1.566.468-3.249.468-5 0-2.735-.41-5.293-1.12-7.5zM9 7.334a4.166 4.166 0 1 1 0 8.332 4.166 4.166 0 0 1 0-8.332M8.167 9v1.667H6.5v1.667h1.667V14h1.666v-1.666H11.5v-1.667H9.833V9z", fill: "#9AA2AC" })));
1090
- const HospitalIcon$1 = () => (React__default["default"].createElement("svg", { width: "16", height: "17", viewBox: "0 0 16 17" },
1091
- React__default["default"].createElement("path", { d: "M8 .667.5 5.635v9.199c0 .92.746 1.666 1.667 1.666h11.666c.921 0 1.667-.745 1.667-1.666V5.635zm3.333 10h-2.5v2.5H7.167v-2.5h-2.5V9h2.5V6.5h1.666V9h2.5z", fill: "#9AA2AC" })));
1092
- const SpecialtyIcon$1 = () => (React__default["default"].createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" },
1093
- React__default["default"].createElement("path", { d: "M3.833.5a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667M10.5.5c-.92 0-1.667.746-1.667 1.667V5.5c0 .92.746 1.667 1.667 1.667h3.333c.921 0 1.667-.746 1.667-1.667V2.167C15.5 1.246 14.754.5 13.833.5zM3.833 8.833a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667m8.334 0a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667", fill: "#9AA2AC" })));
1094
-
1095
- const StyledTypeHeader = styled__default["default"].header `
1096
- display: flex;
1097
- justify-content: space-between;
1098
- padding: 12px 24px;
1099
- background-color: ${miscTheme.theme.colors.neutral50};
1100
- box-shadow: inset 0px 1px 0px #e4e8ec;
1101
- `;
1102
- const StyledInfoWrapper = styled__default["default"].div `
1103
- display: grid;
1104
- flex: 2;
1105
- align-items: center;
1106
- gap: 16px;
1107
- grid-template-columns: 16px 1fr;
1108
- `;
1109
- const StyledTypeName = styled__default["default"].p `
1110
- color: ${miscTheme.theme.colors.neutral800};
1111
- font-size: 14px;
1112
- font-weight: ${miscTheme.theme.sizes.fwSemiBold};
1113
- letter-spacing: -0.2px;
1114
- line-height: 22px;
1115
- `;
1116
- const StyledSeeMoreButton = styled__default["default"].button `
1117
- flex: 1;
1118
- cursor: pointer;
1119
- text-align: end;
1120
- `;
1121
- const StyledResultsContainer = styled__default["default"].section `
1122
- padding: 12px 16px;
1123
- --rowGap: 16px;
1124
- --graphicSize: 32px;
1125
-
1126
- ${utils.MediaQueries.tdUp} {
1127
- --rowGap: 8px;
1128
- }
1129
- `;
1130
- const StyledItemsWrapper = styled__default["default"].ul `
1131
- --gap: 16px;
1132
- ${utils.MediaQueries.tdUp} {
1133
- --gap: 8px;
1134
- }
1135
-
1136
- display: grid;
1137
- overflow: hidden;
1138
- gap: var(--gap);
1139
- transition: max-height 0.8s ease-out;
1140
-
1141
- ${({ isMore }) => isMore &&
1142
- `
1143
- height: auto;
1144
- max-height: 0;
1145
- margin-top: var(--gap);
1146
- `}
1147
-
1148
- ${({ isShown }) => isShown &&
1149
- `
1150
- max-height: 600px;
1151
- `}
1152
-
1153
- @media (prefers-reduced-motion) {
1154
- transition: none;
1155
- }
1156
-
1157
- ${utils.MediaQueries.tdUp} {
1158
- grid-template-columns: 1fr 1fr;
1159
- }
1160
- `;
1161
- const StyledSeeMore = styled__default["default"](index$2.Text) `
1162
- margin-top: 12px;
1163
- margin-bottom: 8px;
1164
- cursor: pointer;
1165
- text-align: start;
1166
- text-transform: capitalize;
1167
- `;
1168
-
1169
- const StyledResult = styled__default["default"].li `
1170
- display: flex;
1171
- align-items: center;
1172
- gap: var(--rowGap);
1173
- cursor: pointer;
1174
- &.not-nav {
1175
- cursor: default;
1176
- }
1177
- `;
1178
- const StyledRoundedIconWrapper = styled__default["default"].div `
1179
- --wrapper-size: var(--graphicSize);
1180
- border-radius: calc(var(--wrapper-size) / 2);
1181
- background-color: var(--neutral50);
1182
- width: var(--wrapper-size);
1183
- height: var(--wrapper-size);
1184
- aspect-ratio: 1/1;
1185
- overflow: hidden;
1186
-
1187
- ${({ type }) => type &&
1188
- type === 'doctors' &&
1189
- `
1190
- border-radius: calc(var(--graphicSize) / 2);
1191
- `}
1192
-
1193
- img {
1194
- width: var(--graphicSize);
1195
- height: var(--graphicSize);
1196
- ${({ type }) => type && type === 'doctors'
1197
- ? `
1198
-
1199
- object-fit: cover;
1200
- `
1201
- : `
1202
- object-fit: contain;
1203
- `}
1204
- }
1205
-
1206
- &:focus-visible {
1207
- outline: 1px solid ${miscTheme.theme.colors.gray600};
1208
- }
1209
- `;
1210
- const StyledText = styled__default["default"](index$2.Text) `
1211
- line-height: 22px;
1212
- letter-spacing: -0.2px;
1213
-
1214
- ${utils.MediaQueries.tdUp} {
1215
- &[data-size='p3'] {
1216
- font-size: 14px;
1217
- }
1218
- }
1219
- `;
1220
- const StyledPictureWrapper = styled__default["default"].figure `
1221
- max-width: var(--graphicSize);
1222
- min-width: var(--graphicSize);
1223
- `;
1224
- const StyledLocationPin = styled__default["default"].svg `
1225
- margin: 0 auto;
1226
- display: block;
1227
- `;
1228
- const StyledImageSkeletonWrapper = styled__default["default"].div `
1229
- display: grid;
1230
- place-items: center;
1231
- `;
1232
-
1233
- const defaultThumbnailByType = {
1234
- doctors: DefaultThumbnailDoctor,
1235
- services: DefaultThumbnailService,
1236
- };
1237
- const ResultSectionItem = ({ type, item, imageUrl, className, onClickItem, }) => {
1238
- const onKeyDown = (e) => {
1239
- if (e.key === 'Enter' || e.key === 'Space') {
1240
- if (onClickItem) {
1241
- onClickItem(item);
1242
- }
1243
- }
1244
- };
1245
- const defaultThumbnail = React.useMemo(() => {
1246
- const Cmp = defaultThumbnailByType[type] || DefaultThumbnailAny;
1247
- return React__default["default"].createElement(Cmp, { width: 32, height: type === 'services' ? 32 : 24 });
1248
- }, [type]);
1249
- return (React__default["default"].createElement(StyledResult, { onClick: () => onClickItem && onClickItem(item), onKeyDown: onKeyDown, tabIndex: 0, role: "button", className: className },
1250
- React__default["default"].createElement(StyledPictureWrapper, null, type === 'hospitals' ? (React__default["default"].createElement(StyledLocationPin, { width: "12", height: "16", viewBox: "0 0 12 16" },
1251
- React__default["default"].createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0.75 5.94873C0.75 3.04623 3.0975 0.69873 6 0.69873C8.9025 0.69873 11.25 3.04623 11.25 5.94873C11.25 9.07623 7.935 13.3887 6.5775 15.0312C6.2775 15.3912 5.73 15.3912 5.43 15.0312C4.065 13.3887 0.75 9.07623 0.75 5.94873ZM4.125 5.94873C4.125 6.98373 4.965 7.82373 6 7.82373C7.035 7.82373 7.875 6.98373 7.875 5.94873C7.875 4.91373 7.035 4.07373 6 4.07373C4.965 4.07373 4.125 4.91373 4.125 5.94873Z", fill: "#9AA2AC" }))) : (React__default["default"].createElement(StyledRoundedIconWrapper, { type: type }, imageUrl ? (React__default["default"].createElement("img", { src: imageUrl, width: 32, height: type === 'services' ? 32 : 24, loading: "lazy" })) : (defaultThumbnail)))),
1252
- React__default["default"].createElement(StyledText, { color: miscTheme.theme.colors.gray800, size: "p3" }, item.name)));
1253
- };
1254
-
1255
- const ResultSection = ({ type, data, state, dispatch, itemsToShow, itemsToShowDesktop, isMobile, isLoading, keyword, isNavResultItem, }) => {
1256
- const [seeMoreOpen, setSeeMoreOpen] = React.useState(false);
1257
- const { t, locale } = useTranslations.useTranslations();
1258
- const { selectedLocation, searchKeywords } = state;
1259
- const slugs = React.useMemo(() => constants.LOCALIZED_SLUGS[locale], [locale]);
1260
- const isMalay = locale === 'ms-MY';
1261
- const typeInformation = React.useMemo(() => {
1262
- return {
1263
- doctors: {
1264
- name: t('booking.searchPopup.doctors'),
1265
- icon: React__default["default"].createElement(DoctorIcon$1, null),
1266
- slug: slugs.DOCTOR,
1267
- },
1268
- services: {
1269
- name: t('booking.searchPopup.services'),
1270
- icon: React__default["default"].createElement(ServiceIcon$1, null),
1271
- slug: slugs.SERVICE,
1272
- },
1273
- hospitals: {
1274
- name: t('booking.searchPopup.hospitals'),
1275
- icon: React__default["default"].createElement(HospitalIcon$1, null),
1276
- slug: slugs.HOSPITAL,
1277
- },
1278
- specialties: {
1279
- name: t('booking.searchPopup.specialties'),
1280
- icon: React__default["default"].createElement(SpecialtyIcon$1, null),
1281
- slug: slugs.SPECIALTIES,
1282
- },
1283
- };
1284
- }, [type, slugs]);
1285
- const typeSlug = React.useMemo(() => typeInformation[type].slug, [typeInformation]);
1286
- const showItemCount = isMobile ? itemsToShow : itemsToShowDesktop;
1287
- function onClickItem(item) {
1288
- let url = '';
1289
- switch (type) {
1290
- case 'specialties':
1291
- url = `/${selectedLocation.slug}/${typeInformation.doctors.slug}/${item.slug}`;
1292
- break;
1293
- case 'services':
1294
- url = `/${selectedLocation.slug}/${typeSlug}/${item.slug}`;
1295
- break;
1296
- case 'doctors':
1297
- case 'hospitals':
1298
- url = `/${typeSlug}/${item.slug}-${item.id}`;
1299
- break;
1300
- }
1301
- if (url) {
1302
- dispatch({
1303
- type: ActionTypes$1.SelectSearchResult,
1304
- payload: { name: item.name, url },
1305
- });
1306
- }
1307
- }
1308
- function renderItem(item) {
1309
- return (React__default["default"].createElement(ResultSectionItem, { key: item.id, item: item, type: type, imageUrl: item.logo || item.avatar || item.thumbnail, className: !isNavResultItem ? 'not-nav' : '', onClickItem: isNavResultItem && onClickItem }));
1310
- }
1311
- function onSeeAllClick() {
1312
- let url = '';
1313
- switch (type) {
1314
- case 'specialties':
1315
- url = `/${typeSlug}`;
1316
- break;
1317
- case 'services':
1318
- case 'doctors':
1319
- case 'hospitals':
1320
- url = `/${selectedLocation.slug}/${typeSlug}`;
1321
- break;
1322
- }
1323
- if (url) {
1324
- dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
1325
- }
1326
- }
1327
- function onClickSearchByKeyword() {
1328
- const { slug: typeSlug } = typeInformation[type];
1329
- const url = `/${selectedLocation.slug}/${typeSlug}?q=${searchKeywords}`;
1330
- dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
1331
- }
1332
- return (React__default["default"].createElement("section", null,
1333
- React__default["default"].createElement(StyledTypeHeader, null,
1334
- React__default["default"].createElement(StyledInfoWrapper, null,
1335
- typeInformation[type].icon,
1336
- React__default["default"].createElement(StyledTypeName, null, typeInformation[type].name)),
1337
- (keyword.trim().length <= SEARCH_KEYWORD_MIN_LENGTH$1[locale] ||
1338
- isMalay) && (React__default["default"].createElement(StyledSeeMoreButton, { onClick: onSeeAllClick },
1339
- React__default["default"].createElement(index$2.Text, { size: "p3", color: miscTheme.theme.colors.primaryBase }, t('booking.searchPopup.seeAll'))))),
1340
- (isLoading || (data && data.length > 0)) && (React__default["default"].createElement(StyledResultsContainer, null,
1341
- React__default["default"].createElement(StyledItemsWrapper, null,
1342
- isLoading &&
1343
- Array(2)
1344
- .fill(undefined)
1345
- .map((_, i) => (React__default["default"].createElement(StyledResult, { key: type + 'loading' + i },
1346
- React__default["default"].createElement(StyledPictureWrapper, null,
1347
- React__default["default"].createElement(StyledImageSkeletonWrapper, null,
1348
- React__default["default"].createElement(Skeleton__default["default"], { height: 14, width: type === 'hospitals' ? 12 : 32, style: {
1349
- maxWidth: 'var(--graphicSize)',
1350
- minHeight: 'var(--graphicSize)',
1351
- } }))),
1352
- React__default["default"].createElement(Skeleton__default["default"], { width: 120, height: 24 })))),
1353
- !isLoading &&
1354
- data &&
1355
- data.length > 0 &&
1356
- data.slice(0, showItemCount).map(renderItem)),
1357
- React__default["default"].createElement(StyledItemsWrapper, { isShown: seeMoreOpen, isMore: true }, data.slice(showItemCount, -1).map(renderItem)),
1358
- type === 'specialties' &&
1359
- showItemCount < data.length &&
1360
- !isLoading && (React__default["default"].createElement("button", { onClick: () => setSeeMoreOpen(!seeMoreOpen) },
1361
- React__default["default"].createElement(StyledSeeMore, { size: "p3", color: miscTheme.theme.colors.primaryBase }, seeMoreOpen
1362
- ? t('booking.searchPopup.seeLessSpecialties')
1363
- : t('booking.searchPopup.seeMoreSpecialties')))),
1364
- type !== 'specialties' &&
1365
- (showItemCount < data.length || isMalay) &&
1366
- !isLoading &&
1367
- keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[locale] && (React__default["default"].createElement("button", { onClick: onClickSearchByKeyword },
1368
- React__default["default"].createElement(StyledSeeMore, { size: "p3", color: miscTheme.theme.colors.primaryBase }, t(`booking.searchPopup.searchIn.${type}`, {
1369
- name: keyword,
1370
- })))))),
1371
- !isLoading && (data === null || data === void 0 ? void 0 : data.length) === 0 && (React__default["default"].createElement(StyledResultsContainer, null,
1372
- React__default["default"].createElement(index$2.Text, { size: "sm", color: miscTheme.theme.colors.gray400 }, t('booking.searchBar.noResults'))))));
1373
- };
1374
-
1375
- const StyledSection = styled__default["default"].section `
1376
- background-color: white;
1377
- border-radius: 4px;
1378
- position: absolute;
1379
- width: 100%;
1380
- z-index: 30;
1381
-
1382
- ${utils.MediaQueries.tdUp} {
1383
- box-shadow: 0px 24px 32px rgba(0, 0, 0, 0.04),
1384
- 0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
1385
- 0px 0px 1px rgba(0, 0, 0, 0.04);
1386
- }
1387
- `;
1388
- const SearchResults = ({ data, state, dispatch, isMobile, isLoading, keyword, hideResults, isNavResultItem, }) => {
1389
- return (React__default["default"].createElement(StyledSection, null, data &&
1390
- data.map((data) => {
1391
- if (hideResults && hideResults.includes(data.type)) {
1392
- return React__default["default"].createElement(React__default["default"].Fragment, null);
1393
- }
1394
- return (React__default["default"].createElement(ResultSection, { type: data.type, state: state, dispatch: dispatch, itemsToShow: 2, itemsToShowDesktop: 4, key: data.type, data: data.results, isMobile: isMobile, isLoading: isLoading, keyword: keyword, isNavResultItem: isNavResultItem }));
1395
- })));
1396
- };
1397
-
1398
- const getApiPath = (path, params, locale) => {
1399
- return formatString__default["default"](path, Object.assign(Object.assign({}, params), { domain: constantsDomainLocales.domainLocales[locale || 'en-PH'] }));
1400
- };
1401
-
1402
- function useSearchBarApi$1({ dispatch, careApiDomain, locale = 'vi-VN', }) {
1403
- const fetchCitiesApi = React.useCallback(function fetchCitiesApi(path, params = {}) {
1404
- const url = `${careApiDomain}${path}`;
1405
- dispatch({ type: ActionTypes$1.FetchCitiesStart });
1406
- return fetch(getApiPath(url, params, locale), { method: 'GET' })
1407
- .then((res) => res.json())
1408
- .then((data) => {
1409
- if (data._status !== 1 || !data._data) {
1410
- console.log('error loading cities', data);
1411
- return Promise.reject(data);
1412
- }
1413
- return data === null || data === void 0 ? void 0 : data._data;
1414
- })
1415
- .finally(() => dispatch({ type: ActionTypes$1.FetchCitiesFinish }));
1416
- }, [locale]);
1417
- const fetchCitiesByLocation = React.useCallback(function fetchCitiesByLocation({ coordinates }) {
1418
- let params = {};
1419
- const moreParams = {};
1420
- if (coordinates) {
1421
- params = {
1422
- lat: coordinates.lat,
1423
- lng: coordinates.lng,
1424
- };
1425
- }
1426
- if (locale === 'ms-MY') {
1427
- moreParams.noPaging = 1;
1428
- }
1429
- const requests = [
1430
- fetchCitiesApi(paths.PATHS.GET_CITY_BY_IP, Object.assign(Object.assign({}, params), moreParams)),
1431
- ];
1432
- if (locale === 'zh-TW') {
1433
- requests.push(fetchCitiesApi(paths.PATHS.GET_CITIES_LIST, { noPaging: 1 }));
1434
- }
1435
- return Promise.all(requests)
1436
- .then(([data1, data2]) => {
1437
- const data = Object.assign({}, data1);
1438
- if (data2) {
1439
- const citiesIds = data.cities.map((c) => c.id);
1440
- data.cities = data.cities.concat(data2.cities.filter((c) => !citiesIds.includes(c.id)));
1441
- }
1442
- dispatch({
1443
- type: ActionTypes$1.FetchCitiesByGeoIpComplete,
1444
- payload: data,
1445
- });
1446
- })
1447
- .catch((err) => console.error('error loading cities by location', err));
1448
- }, [locale, careApiDomain, dispatch]);
1449
- const fetchCitiesByKeyword = React.useCallback(function fetchCitiesByKeyword(keyword) {
1450
- return fetchCitiesApi(paths.PATHS.GET_CITIES_LIST, { keyword })
1451
- .then((data) => {
1452
- dispatch({
1453
- type: ActionTypes$1.FetchCitiesByKeywordComplete,
1454
- payload: data.cities,
1455
- });
1456
- })
1457
- .catch((err) => console.error('error loading cities by keyword', err));
1458
- }, [locale, careApiDomain, dispatch]);
1459
- const fetchSearchResults = React.useCallback(function fetchSearchResults(searchKeywords, state) {
1460
- const url = `${careApiDomain}${paths.PATHS.GET_SEARCH_V2}`;
1461
- dispatch({ type: ActionTypes$1.FetchSearchResultsStart });
1462
- const { defaultCity, selectedLocation, geoLocationCoordinates } = state;
1463
- let cityId = '';
1464
- if (!selectedLocation || !defaultCity) {
1465
- dispatch({ type: ActionTypes$1.FetchSearchResultsFinish });
1466
- return;
1467
- }
1468
- const isCurrentLocationSelected = selectedLocation.id === constants.ID_OPTION_CURRENT_LOCATION;
1469
- if (isCurrentLocationSelected) {
1470
- if (!geoLocationCoordinates) {
1471
- cityId = defaultCity.id;
1472
- }
1473
- }
1474
- else if (selectedLocation.id === constants.ID_OPTION_ALL_LOCATION) {
1475
- cityId = '';
1476
- }
1477
- else {
1478
- cityId = selectedLocation.id;
1479
- }
1480
- const lat = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lat) || '';
1481
- const lng = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lng) || '';
1482
- return fetch(getApiPath(url, {
1483
- domain: careApiDomain,
1484
- searchType: 'global',
1485
- keyword: searchKeywords.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[locale]
1486
- ? searchKeywords.trim()
1487
- : '',
1488
- city: cityId === constants.ID_OPTION_CURRENT_LOCATION ? '' : cityId,
1489
- lat,
1490
- lng,
1491
- }, locale), {
1492
- method: 'GET',
1493
- headers: {
1494
- accept: 'version=2.0.0.0',
1495
- },
1496
- })
1497
- .then((res) => res.json())
1498
- .then((data) => {
1499
- if (data._status !== 1 || !data._data) {
1500
- return Promise.reject(data);
1501
- }
1502
- return data === null || data === void 0 ? void 0 : data._data;
1503
- })
1504
- .then((results) => dispatch({
1505
- type: ActionTypes$1.FetchSearchResultsComplete,
1506
- payload: results,
1507
- }))
1508
- .catch((error) => {
1509
- console.log('error loading search results', { url, error });
1510
- })
1511
- .finally(() => dispatch({ type: ActionTypes$1.FetchSearchResultsFinish }));
1512
- }, [locale, careApiDomain, dispatch]);
1513
- return {
1514
- fetchCitiesByLocation,
1515
- fetchCitiesByKeyword,
1516
- fetchSearchResults,
1517
- };
1518
- }
1519
-
1520
- const BookingSearchBar = ({ isMobile, careApiDomain, geoLocationPermission: geoLocationPermissionFromProps, geoLocationCoordinates: geoLocationCoordinatesFromProps, initialSelectedCity: initialSelectedCityFromProps, initialSearchValue = '', careFrontDomain = '/care', isDebug = false, askForGeolocationPermission = false, gaTrackingSearchBar, gaTrackingLocationSearch, autoCompleteDisabled = false, inputSearchPlaceholder = '', isOptionAllLocation = false, hideResults = [], isNavResultItem = true, routerPush, onGeoLocationPermissionChange, onSearch, onChangeLocation, }) => {
1521
- const { t, locale } = useTranslations.useTranslations();
1522
- const wrapperRef = React.useRef(null);
1523
- const hiddenInputRef = React.useRef(null);
1524
- const [viewportHeight, setViewportHeight] = React.useState(undefined);
1525
- const [isNavResultPage, setIsNavResultPage] = React.useState(false);
1526
- const { geoLocationPermission: geoLocationPermissionFromHook, geoLocationCoordinates: geoLocationCoordinatesFromHook, requestGeoLocation, } = useGeolocation();
1527
- const [state, dispatch] = React.useReducer(reducer$1, initialState$1, (s) => (Object.assign(Object.assign({}, s), { isDebug,
1528
- isMobile, geoLocationPermission: geoLocationPermissionFromProps ||
1529
- geoLocationPermissionFromHook ||
1530
- 'unset', geoLocationCoordinates: geoLocationCoordinatesFromProps ||
1531
- geoLocationCoordinatesFromHook ||
1532
- null, searchKeywords: initialSearchValue, initialSelectedCity: initialSelectedCityFromProps || null, selectedLocation: initialSelectedCityFromProps || s.selectedLocation || null, searchLocationKeywords: (initialSelectedCityFromProps === null || initialSelectedCityFromProps === void 0 ? void 0 : initialSelectedCityFromProps.name) || s.searchLocationKeywords, autoCompleteDisabled,
1533
- inputSearchPlaceholder,
1534
- locale })));
1535
- const { navigateTo, focused, isLoadingCities, cities, searchKeywords, geoLocationPermission, selectedLocation, initialSelectedCity, defaultCity, searchResults, isLoadingSearchResults, isMobileModalOpened, inputSearchPlaceholder: inputSearchPlaceholderState, } = state;
1536
- const { fetchCitiesByLocation, fetchCitiesByKeyword, fetchSearchResults } = useSearchBarApi$1({
1537
- dispatch,
1538
- locale,
1539
- careApiDomain,
1540
- });
1541
- const currentLocationCityItem = React.useMemo(() => {
1542
- var _a;
1543
- return ({
1544
- id: constants.ID_OPTION_CURRENT_LOCATION,
1545
- name: t('booking.searchBar.currentLocation'),
1546
- slug: (_a = constants.LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.CURRENT,
1547
- });
1548
- }, [t, locale]);
1549
- const debouncedFetchCitiesByKeyword = React.useMemo(() => debounce__default["default"](fetchCitiesByKeyword, 400), [fetchCitiesByKeyword]);
1550
- const debouncedFetchSearchResults = React.useMemo(() => debounce__default["default"](fetchSearchResults, 400), [fetchSearchResults]);
1551
- React.useEffect(() => {
1552
- if (initialSearchValue !== '' &&
1553
- initialSearchValue !== state.searchKeywords) {
1554
- dispatch({
1555
- type: ActionTypes$1.UpdateInitialSearchValue,
1556
- payload: initialSearchValue,
1557
- });
1558
- }
1559
- }, [initialSearchValue]);
1560
- React.useEffect(() => {
1561
- if (askForGeolocationPermission &&
1562
- (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === constants.ID_OPTION_CURRENT_LOCATION &&
1563
- geoLocationPermission === 'unset') {
1564
- requestGeoLocation();
1565
- }
1566
- }, [askForGeolocationPermission, selectedLocation, geoLocationPermission]);
1567
- React.useEffect(() => {
1568
- if (!geoLocationPermissionFromProps &&
1569
- geoLocationPermission !== geoLocationPermissionFromHook) {
1570
- if (geoLocationPermissionFromHook === 'granted' &&
1571
- geoLocationCoordinatesFromHook) {
1572
- dispatch({
1573
- type: ActionTypes$1.GrantGeoLocationPermission,
1574
- payload: geoLocationCoordinatesFromHook,
1575
- });
1576
- }
1577
- else if (geoLocationPermissionFromHook === 'denied') {
1578
- dispatch({ type: ActionTypes$1.DenyGeoLocationPermission });
1579
- }
1580
- }
1581
- }, [
1582
- geoLocationPermission,
1583
- geoLocationPermissionFromHook,
1584
- geoLocationCoordinatesFromHook,
1585
- geoLocationPermissionFromProps,
1586
- ]);
1587
- React.useEffect(() => {
1588
- if (navigateTo) {
1589
- if (routerPush) {
1590
- routerPush(navigateTo);
1591
- }
1592
- else {
1593
- window.location.href = `${careFrontDomain}${navigateTo}`;
1594
- }
1595
- }
1596
- }, [navigateTo]);
1597
- const selectCurrentLocation = React.useCallback(function selectCurrentLocation() {
1598
- dispatch({
1599
- type: ActionTypes$1.SelectCurrentLocation,
1600
- payload: currentLocationCityItem,
1601
- });
1602
- }, [t, dispatch]);
1603
- React.useEffect(() => {
1604
- var _a;
1605
- if (geoLocationPermission !== 'denied' && !initialSelectedCity) {
1606
- dispatch({
1607
- type: ActionTypes$1.SelectLocation,
1608
- payload: {
1609
- name: t('booking.searchBar.allLocations'),
1610
- id: constants.ID_OPTION_ALL_LOCATION,
1611
- slug: (_a = constants.LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
1612
- },
1613
- });
1614
- }
1615
- if (onGeoLocationPermissionChange) {
1616
- onGeoLocationPermissionChange(geoLocationPermission, state.geoLocationCoordinates);
1617
- }
1618
- if (isMobile && geoLocationPermission === 'granted' && selectedLocation) {
1619
- dispatch({ type: ActionTypes$1.FocusInputSearch });
1620
- }
1621
- fetchCitiesByLocation({ coordinates: state.geoLocationCoordinates });
1622
- }, [geoLocationPermission]);
1623
- React.useEffect(() => {
1624
- if (selectedLocation && defaultCity) {
1625
- fetchSearchResults(state.searchKeywords, state);
1626
- }
1627
- }, [selectedLocation, defaultCity]);
1628
- React.useEffect(() => {
1629
- if (inputSearchPlaceholder !== inputSearchPlaceholderState) {
1630
- dispatch({
1631
- type: ActionTypes$1.SetInputSearchPlaceholder,
1632
- payload: inputSearchPlaceholder,
1633
- });
1634
- }
1635
- }, [inputSearchPlaceholder, inputSearchPlaceholderState]);
1636
- React.useEffect(() => {
1637
- if (isMobileModalOpened) {
1638
- document.body.classList.add('care-popup-open');
1639
- }
1640
- else {
1641
- document.body.classList.remove('care-popup-open');
1642
- }
1643
- }, [isMobileModalOpened]);
1644
- const handleLocationClick = React.useCallback(function handleLocationClick(city) {
1645
- if (locale === 'ms-MY') {
1646
- setIsNavResultPage(true);
1647
- }
1648
- dispatch({ type: ActionTypes$1.SelectLocation, payload: city });
1649
- if (locale !== 'ms-MY') {
1650
- focusSearchInput();
1651
- }
1652
- if (onChangeLocation) {
1653
- onChangeLocation(city);
1654
- }
1655
- }, [t, dispatch]);
1656
- function handleCurrentLocationClick() {
1657
- if (locale === 'ms-MY') {
1658
- setIsNavResultPage(true);
1659
- }
1660
- if (isMobile && state.geoLocationPermission !== 'granted') {
1661
- requestGeoLocation();
1662
- }
1663
- else {
1664
- selectCurrentLocation();
1665
- if (locale !== 'ms-MY') {
1666
- focusSearchInput();
1667
- }
1668
- }
1669
- }
1670
- function handleMobileFakeInputClick() {
1671
- var _a;
1672
- return tslib_es6.__awaiter(this, void 0, void 0, function* () {
1673
- if (hiddenInputRef.current) {
1674
- hiddenInputRef.current.focus();
1675
- }
1676
- dispatch({ type: ActionTypes$1.OpenMobileModal });
1677
- yield Promise.resolve();
1678
- if (wrapperRef.current) {
1679
- (_a = wrapperRef.current
1680
- .querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
1681
- }
1682
- });
1683
- }
1684
- function focusLocationInput() {
1685
- var _a;
1686
- if (wrapperRef.current) {
1687
- (_a = wrapperRef.current
1688
- .querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
1689
- }
1690
- }
1691
- function focusSearchInput() {
1692
- var _a;
1693
- if (wrapperRef.current) {
1694
- (_a = wrapperRef.current
1695
- .querySelector('input[name="search-results"]')) === null || _a === void 0 ? void 0 : _a.focus();
1696
- }
1697
- }
1698
- function handleMobileTopBarClose() {
1699
- dispatch({ type: ActionTypes$1.CloseMobileModal });
1700
- }
1701
- function renderLocationResults() {
1702
- if (focused !== 'location') {
1703
- return null;
1704
- }
1705
- return (React__default["default"].createElement(LocationResults, { isLoading: isLoadingCities, cities: cities, onLocationClick: handleLocationClick, onCurrentLocationClick: handleCurrentLocationClick, isLocationLoading: isLoadingCities, geoLocationPermission: geoLocationPermission, selectedLocation: selectedLocation, isOptionAllLocation: isOptionAllLocation }));
1706
- }
1707
- function renderSearchResults() {
1708
- if (focused !== 'search') {
1709
- return null;
1710
- }
1711
- if (state.autoCompleteDisabled) {
1712
- if (!isMobile) {
1713
- return null;
1714
- }
1715
- return (React__default["default"].createElement(SearchButton, { onClick: () => {
1716
- onSearch({
1717
- cityId: state.selectedLocation.id,
1718
- keyword: searchKeywords,
1719
- });
1720
- handleMobileTopBarClose();
1721
- } }));
1722
- }
1723
- return (React__default["default"].createElement(SearchResults, { data: searchResults, state: state, dispatch: dispatch, isMobile: false, keyword: searchKeywords, isLoading: isLoadingSearchResults, hideResults: hideResults, isNavResultItem: isNavResultItem }));
1724
- }
1725
- function renderSearchInputs() {
1726
- return (React__default["default"].createElement(SearchInputs$1, { isMobile: isMobile, state: state, dispatch: dispatch, debouncedFetchCitiesByKeyword: debouncedFetchCitiesByKeyword, debouncedFetchSearchResults: debouncedFetchSearchResults, focusLocationInput: focusLocationInput, focusSearchInput: focusSearchInput, renderLocationResults: renderLocationResults, renderSearchResults: renderSearchResults, trackingAttributes: gaTrackingSearchBar, locationTrackingAttributes: gaTrackingLocationSearch, onSearch: onSearch, initalSearchValue: initialSearchValue }));
1727
- }
1728
- React.useEffect(() => {
1729
- if (window.visualViewport) {
1730
- const resizeHandler = (evt) => {
1731
- const viewport = evt.target;
1732
- setViewportHeight(viewport === null || viewport === void 0 ? void 0 : viewport.height);
1733
- };
1734
- window.visualViewport.addEventListener('resize', resizeHandler, {
1735
- passive: true,
1736
- });
1737
- return () => {
1738
- window.visualViewport.removeEventListener('resize', resizeHandler);
1739
- };
1740
- }
1741
- }, [setViewportHeight]);
1742
- React.useEffect(() => {
1743
- // Apply for ms-MY. Navigation to result page after selected location
1744
- if (selectedLocation && isNavResultPage && locale === 'ms-MY') {
1745
- const url = `/${selectedLocation.slug}/hospital`;
1746
- dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
1747
- setIsNavResultPage(false);
1748
- }
1749
- }, [isNavResultPage, locale, selectedLocation]);
1750
- if (isMobile) {
1751
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
1752
- React__default["default"].createElement(react.Global, { styles: react.css `
1753
- .care-popup-open {
1754
- overflow: hidden;
1755
- position: fixed;
1756
- &::before {
1757
- content: '';
1758
- inset: 0;
1759
- position: absolute;
1760
- background-color: white;
1761
- min-height: 100vh;
1762
- min-width: 100vw;
1763
- z-index: 2;
1764
- }
1765
- }
1766
- ` }),
1767
- React__default["default"].createElement(StyledHiddenInputMobile, { ref: hiddenInputRef }),
1768
- React__default["default"].createElement(StyledSearchBarMobileWrapper, { id: "booking-search-bar", ref: wrapperRef, "data-is-modal": isMobile && isMobileModalOpened, style: {
1769
- '--mobile-care-searchbar-height': isMobileModalOpened && viewportHeight
1770
- ? `${viewportHeight}px`
1771
- : '100%',
1772
- } }, !isMobileModalOpened ? (React__default["default"].createElement(MobileFakeInput, { onClick: handleMobileFakeInputClick, focused: focused, value: searchKeywords, trackingAttributes: gaTrackingSearchBar, inputSearchPlaceholder: inputSearchPlaceholder })) : (React__default["default"].createElement(React__default["default"].Fragment, null,
1773
- React__default["default"].createElement(StyledSearchBarMobileModalHeader, null,
1774
- React__default["default"].createElement(MobileTopBar, { headingText: t('booking.searchBar.searchButton'), onLeftClick: handleMobileTopBarClose }),
1775
- renderSearchInputs()),
1776
- renderLocationResults(),
1777
- renderSearchResults())))));
1778
- }
1779
- return (React__default["default"].createElement(StyledSearchBarWrapper$1, { id: "booking-search-bar", ref: wrapperRef }, renderSearchInputs()));
1780
- };
1781
-
1782
- const StyledSearchBarWrapper = styled__default["default"].div ``;
1783
- const StyleWrapperContainer = styled__default["default"].div `
1784
- background-color: ${miscTheme.theme.colors.neutral50};
1785
- padding-bottom: 1px;
1786
- ${utils.MediaQueries.mbDown} {
1787
- padding: 0 16px 10px;
1788
- }
1789
- `;
1790
- const StyleSearchInputContainer = styled__default["default"](index$3.Container) `
1791
- padding: 0 16px;
1792
-
1793
- ${utils.MediaQueries.mbDown} {
1794
- padding: 0;
1795
- }
1796
- `;
1797
- const StyleSearchContent = styled__default["default"].div `
1798
- padding: 24px 56px;
1799
- border-radius: 16px;
1800
- background-color: ${miscTheme.theme.colors.white};
1801
- box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.04),
1802
- 0px 0px 2px 0px rgba(0, 0, 0, 0.06), 0px 4px 8px 0px rgba(0, 0, 0, 0.04);
1803
-
1804
- ${utils.MediaQueries.mbDown} {
1805
- padding: 16px 16px;
1806
- border-radius: 0px 0px 12px 12px;
1807
- }
1808
-
1809
- .flex-search-input {
1810
- flex-direction: row;
1811
- ${utils.MediaQueries.mbDown} {
1812
- flex-direction: column;
1813
- }
1814
- }
1815
- `;
1816
-
1817
- const SEARCH_KEYWORD_MIN_LENGTH = {
1818
- 'en-PH': 3,
1819
- 'tl-PH': 2,
1820
- 'id-ID': 3,
1821
- 'vi-VN': 2,
1822
- 'zh-TW': 0,
1823
- 'ms-MY': 2,
1824
- };
1825
-
1826
- const initialState = {
1827
- isMobile: false,
1828
- isDebug: false,
1829
- navigateTo: null,
1830
- geoLocationPermission: 'unset',
1831
- geoLocationCoordinates: null,
1832
- focused: 'none',
1833
- focusedSpecialty: 'none',
1834
- searchLocationKeywords: '',
1835
- searchSpecialtyKeywords: '',
1836
- searchKeywords: '',
1837
- selectedLocation: null,
1838
- selectedSpecialty: null,
1839
- defaultCity: null,
1840
- initialCities: [],
1841
- cities: [],
1842
- searchResults: {},
1843
- initialSearchResults: {},
1844
- isLoadingCities: false,
1845
- isLoadingSearchResults: false,
1846
- isMobileModalOpened: false,
1847
- initialSelectedCity: null,
1848
- autoCompleteDisabled: false,
1849
- inputSearchPlaceholder: '',
1850
- locale: 'vi-VN',
1851
- allSpecialties: [],
1852
- popularKeys: [],
1853
- };
1854
- var ActionTypes;
1855
- (function (ActionTypes) {
1856
- ActionTypes["NavigateTo"] = "navigate to url";
1857
- ActionTypes["ClickOutsideInputLocation"] = "click outside input location";
1858
- ActionTypes["ClickOutsideInputSearch"] = "click outside input search";
1859
- ActionTypes["ClickOutsideInputSearchSpecialty"] = "click outside input search specialty";
1860
- ActionTypes["ClickOutsideInputSpecialty"] = "click outside input specialty";
1861
- ActionTypes["SelectCurrentLocation"] = "select current location";
1862
- ActionTypes["FocusInputLocation"] = "focus input location";
1863
- ActionTypes["FocusInputSearch"] = "focus input search";
1864
- ActionTypes["FocusInputSearchSpecialty"] = "focus input search specialty";
1865
- ActionTypes["ChangeInputLocation"] = "change input location";
1866
- ActionTypes["ChangeInputSearch"] = "change input search";
1867
- ActionTypes["ClearInputLocation"] = "clear input location";
1868
- ActionTypes["ClearInputSearch"] = "clear input search";
1869
- ActionTypes["SelectLocation"] = "select location";
1870
- ActionTypes["SelectSpecialty"] = "select specialty";
1871
- ActionTypes["FetchCitiesStart"] = "fetch cities start";
1872
- ActionTypes["FetchCitiesFinish"] = "fetch cities finish";
1873
- ActionTypes["FetchSearchResultsStart"] = "fetch search results start";
1874
- ActionTypes["FetchSearchResultsComplete"] = "fetch search results complete";
1875
- ActionTypes["FetchSearchResultsFinish"] = "fetch search results finish";
1876
- ActionTypes["FetchCitiesByGeoIpComplete"] = "fetch cities by geo IP finish";
1877
- ActionTypes["FetchCitiesByKeywordComplete"] = "fetch cities by keyword finish";
1878
- ActionTypes["DisplayInitialCities"] = "display initial cities";
1879
- ActionTypes["DisplayInitialSearchResults"] = "display initial search results";
1880
- ActionTypes["UpdateInitialSearchResults"] = "update initial search results";
1881
- ActionTypes["GrantGeoLocationPermission"] = "grant geolocation permission";
1882
- ActionTypes["DenyGeoLocationPermission"] = "deny geolocation permission";
1883
- ActionTypes["OpenMobileModal"] = "open mobile modal";
1884
- ActionTypes["CloseMobileModal"] = "close mobile modal";
1885
- ActionTypes["UpdateInitialSearchValue"] = "update initial search value";
1886
- ActionTypes["SelectSearchResult"] = "select search result";
1887
- ActionTypes["SetInputSearchPlaceholder"] = "set input search placeholder";
1888
- ActionTypes["FocusInputSpecialty"] = "focus input specialty";
1889
- ActionTypes["FetchAllSpecialties"] = "fetch all specialty";
1890
- ActionTypes["FetchPopularKeys"] = "fetch popular key by type";
1891
- })(ActionTypes || (ActionTypes = {}));
1892
- function resetSearchLocationKeywords(state) {
1893
- const { selectedLocation, searchLocationKeywords } = state;
1894
- if (selectedLocation && searchLocationKeywords !== selectedLocation.name) {
1895
- return Object.assign(Object.assign({}, state), { searchLocationKeywords: selectedLocation.name });
1896
- }
1897
- return state;
1898
- }
1899
- function reducer(state, action) {
1900
- var _a, _b;
1901
- if (state.isDebug) {
1902
- console.log('bookingSearchBar', { action, state });
1903
- }
1904
- switch (action.type) {
1905
- case ActionTypes.NavigateTo:
1906
- return Object.assign(Object.assign({}, state), { navigateTo: action.payload, focused: 'none', isMobileModalOpened: false });
1907
- case ActionTypes.ClickOutsideInputLocation: {
1908
- if (state.focused !== 'location') {
1909
- return state;
1910
- }
1911
- return resetSearchLocationKeywords(Object.assign(Object.assign({}, state), { focused: 'none' }));
1912
- }
1913
- case ActionTypes.ClickOutsideInputSpecialty: {
1914
- if (state.focused !== 'specialty') {
1915
- return state;
1916
- }
1917
- return resetSearchLocationKeywords(Object.assign(Object.assign({}, state), { focused: 'none' }));
1918
- }
1919
- case ActionTypes.ClickOutsideInputSearch: {
1920
- if (state.focused !== 'search') {
1921
- return state;
1922
- }
1923
- return Object.assign(Object.assign({}, state), { focused: 'none' });
1924
- }
1925
- case ActionTypes.ClickOutsideInputSearchSpecialty: {
1926
- if (state.focusedSpecialty !== 'search') {
1927
- return state;
1928
- }
1929
- return Object.assign(Object.assign({}, state), { focusedSpecialty: 'none' });
1930
- }
1931
- case ActionTypes.FocusInputLocation: {
1932
- const nextState = Object.assign(Object.assign({}, state), { focused: 'location' });
1933
- if (((_a = state.selectedLocation) === null || _a === void 0 ? void 0 : _a.id) === constants.ID_OPTION_CURRENT_LOCATION) {
1934
- nextState.searchLocationKeywords = '';
1935
- }
1936
- return nextState;
1937
- }
1938
- case ActionTypes.FocusInputSpecialty: {
1939
- const nextState = Object.assign(Object.assign({}, state), { focused: 'specialty' });
1940
- if (((_b = state.selectedLocation) === null || _b === void 0 ? void 0 : _b.id) === constants.ID_OPTION_CURRENT_LOCATION) {
1941
- nextState.searchLocationKeywords = '';
1942
- }
1943
- return nextState;
1944
- }
1945
- case ActionTypes.FocusInputSearch:
1946
- const nextState = Object.assign(Object.assign({}, state), { focused: 'search' });
1947
- if (state.isMobile) {
1948
- return resetSearchLocationKeywords(nextState);
1949
- }
1950
- return nextState;
1951
- case ActionTypes.FocusInputSearchSpecialty: {
1952
- const nextState = Object.assign(Object.assign({}, state), { focusedSpecialty: 'search' });
1953
- return nextState;
1954
- }
1955
- case ActionTypes.ChangeInputLocation:
1956
- return Object.assign(Object.assign({}, state), { searchLocationKeywords: action.payload });
1957
- case ActionTypes.ChangeInputSearch: {
1958
- const keyword = action.payload;
1959
- return Object.assign(Object.assign({}, state), { searchKeywords: keyword, isLoadingSearchResults: keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] });
1960
- }
1961
- case ActionTypes.SelectCurrentLocation:
1962
- return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
1963
- case ActionTypes.ClearInputLocation:
1964
- return Object.assign(Object.assign({}, state), { focused: 'location', cities: state.initialCities, searchLocationKeywords: '' });
1965
- case ActionTypes.ClearInputSearch:
1966
- return Object.assign(Object.assign({}, state), { focused: 'search', searchKeywords: '' });
1967
- case ActionTypes.SelectLocation:
1968
- return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
1969
- case ActionTypes.SelectSpecialty:
1970
- return Object.assign(Object.assign({}, state), { focused: 'none', selectedSpecialty: action.payload });
1971
- case ActionTypes.SelectSearchResult:
1972
- return Object.assign(Object.assign({}, state), { searchKeywords: action.payload.name, isMobileModalOpened: false, focused: 'none', navigateTo: action.payload.url });
1973
- case ActionTypes.FetchCitiesStart:
1974
- return Object.assign(Object.assign({}, state), { isLoadingCities: true });
1975
- case ActionTypes.FetchCitiesFinish:
1976
- return Object.assign(Object.assign({}, state), { isLoadingCities: false });
1977
- case ActionTypes.FetchSearchResultsStart:
1978
- return Object.assign(Object.assign({}, state), { isLoadingSearchResults: true });
1979
- case ActionTypes.FetchSearchResultsFinish:
1980
- return Object.assign(Object.assign({}, state), { isLoadingSearchResults: false });
1981
- case ActionTypes.FetchSearchResultsComplete: {
1982
- const nextState = Object.assign(Object.assign({}, state), { searchResults: Object.assign(Object.assign({}, state.searchResults), { [action.payload.key]: action.payload.searches }) });
1983
- return nextState;
1984
- }
1985
- case ActionTypes.FetchCitiesByGeoIpComplete: {
1986
- let { cities } = action.payload;
1987
- const { default: defaultCity } = action.payload;
1988
- cities = cities.filter((c) => c.id !== defaultCity.id);
1989
- if (defaultCity) {
1990
- cities.unshift(defaultCity);
1991
- }
1992
- if (state.initialSelectedCity &&
1993
- !cities.find((c) => c.id === state.initialSelectedCity.id)) {
1994
- cities.unshift(state.initialSelectedCity);
1995
- }
1996
- const nextState = Object.assign(Object.assign({}, state), { defaultCity, initialCities: cities, cities });
1997
- if (state.geoLocationPermission === 'denied' &&
1998
- !state.initialSelectedCity) {
1999
- nextState.selectedLocation = defaultCity;
2000
- nextState.searchLocationKeywords = defaultCity.name;
2001
- }
2002
- return nextState;
2003
- }
2004
- case ActionTypes.FetchCitiesByKeywordComplete:
2005
- return Object.assign(Object.assign({}, state), { cities: action.payload });
2006
- case ActionTypes.DisplayInitialCities:
2007
- return Object.assign(Object.assign({}, state), { cities: state.initialCities });
2008
- case ActionTypes.DisplayInitialSearchResults:
2009
- return Object.assign(Object.assign({}, state), { searchResults: state.initialSearchResults, isLoadingSearchResults: false });
2010
- case ActionTypes.UpdateInitialSearchResults:
2011
- return Object.assign(Object.assign({}, state), { initialSearchResults: Object.assign(Object.assign({}, state.initialSearchResults), { [action.payload.key]: action.payload.searches }) });
2012
- case ActionTypes.GrantGeoLocationPermission:
2013
- return Object.assign(Object.assign({}, state), { geoLocationPermission: 'granted', geoLocationCoordinates: action.payload });
2014
- case ActionTypes.DenyGeoLocationPermission:
2015
- return Object.assign(Object.assign({}, state), { geoLocationPermission: 'denied', geoLocationCoordinates: null });
2016
- case ActionTypes.OpenMobileModal:
2017
- return Object.assign(Object.assign({}, state), { isMobileModalOpened: true });
2018
- case ActionTypes.CloseMobileModal:
2019
- return Object.assign(Object.assign({}, state), { isMobileModalOpened: false });
2020
- case ActionTypes.UpdateInitialSearchValue:
2021
- return Object.assign(Object.assign({}, state), { searchKeywords: action.payload });
2022
- case ActionTypes.SetInputSearchPlaceholder:
2023
- return Object.assign(Object.assign({}, state), { inputSearchPlaceholder: action.payload });
2024
- case ActionTypes.FetchAllSpecialties:
2025
- return Object.assign(Object.assign({}, state), { allSpecialties: action.payload });
2026
- case ActionTypes.FetchPopularKeys:
2027
- return Object.assign(Object.assign({}, state), { popularKeys: action.payload });
2028
- default:
2029
- return state;
2030
- }
2031
- }
2032
-
2033
- const StyleSearchInputsWrapper = styled__default["default"].div `
2034
- flex: 1;
2035
- position: relative;
2036
-
2037
- ${utils.MediaQueries.mbDown} {
2038
- width: 100%;
2039
- display: flex;
2040
- flex-direction: column;
2041
- gap: 12px;
2042
- }
2043
- `;
2044
- const StyleResultWrapper$2 = styled__default["default"].div `
2045
- position: absolute;
2046
- top: calc(100% + 2px);
2047
- width: 100%;
2048
- border-radius: 4px;
2049
- background: ${miscTheme.theme.colors.white};
2050
- box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
2051
- z-index: 10;
2052
-
2053
- ${utils.MediaQueries.mbDown} {
2054
- width: calc(100% + 64px);
2055
- left: -32px;
2056
- }
2057
- `;
2058
-
2059
- const StyledSearchResultWrapper = styled__default["default"].div ``;
2060
- const StyleResultHeader = styled__default["default"].div `
2061
- display: flex;
2062
- justify-content: space-between;
2063
- align-item: center;
2064
- padding: 9px 14px 9px 22px;
2065
- background: #f7f9fc;
2066
-
2067
- .title {
2068
- color: ${miscTheme.theme.colors.gray800};
2069
- font-size: 14px;
2070
- font-weight: 600;
2071
- line-height: 22px;
2072
- }
2073
-
2074
- .btn-see-all {
2075
- color: ${miscTheme.theme.colors.blue600};
2076
- font-size: 14px;
2077
- line-height: 22px;
2078
- cursor: pointer;
2079
- }
2080
- `;
2081
- const StyleResultBody = styled__default["default"].div `
2082
- padding: 10px 16px;
2083
- max-height: 400px;
2084
- overflow: auto;
2085
- `;
2086
- const StyleResultItem = styled__default["default"].div `
2087
- display: flex;
2088
- gap: 12px;
2089
- align-items: center;
2090
- cursor: pointer;
2091
-
2092
- &:hover {
2093
- background-color: ${miscTheme.theme.colors.blue50};
2094
- }
2095
- .image-item {
2096
- flex: 0 0 48px;
2097
- width: 48px;
2098
- height: 48px;
2099
- border-radius: 50%;
2100
-
2101
- img {
2102
- object-fit: contain;
2103
- width: 100%;
2104
- height: 100%;
2105
- border-radius: 50%;
2106
- }
2107
- }
2108
- .infor {
2109
- overflow: hidden;
2110
- padding: 12px 0;
2111
- flex: 1;
2112
- border-bottom: 1px solid ${miscTheme.theme.colors.neutral100};
2113
- .title {
2114
- color: ${miscTheme.theme.colors.gray800};
2115
- font-size: 16px;
2116
- font-weight: 600;
2117
- line-height: 24px;
2118
- }
2119
- .description {
2120
- overflow: hidden;
2121
- color: ${miscTheme.theme.colors.gray600};
2122
- text-overflow: ellipsis;
2123
- white-space: nowrap;
2124
- font-size: 12px;
2125
- line-height: 18px;
2126
- display: flex;
2127
- gap: 8px;
2128
- align-items: center;
2129
- margin-top: 5px;
2130
-
2131
- svg {
2132
- flex: 0 0 16px;
2133
- }
2134
-
2135
- .sub-description {
2136
- overflow: hidden;
2137
- white-space: nowrap;
2138
- text-overflow: ellipsis;
2139
- flex: 1;
2140
- }
2141
- }
2142
- }
2143
-
2144
- &.last-item {
2145
- .infor {
2146
- border-bottom: none;
2147
- }
2148
- }
2149
- `;
2150
- styled__default["default"].div `
2151
- padding: 0 16px 16px;
2152
-
2153
- .search-detail-btn {
2154
- color: ${miscTheme.theme.colors.blue600};
2155
- font-size: 14px;
2156
- line-height: 22px;
2157
- cursor: pointer;
2158
- }
2159
- `;
2160
-
2161
- const SearchResult = ({ state, type, results, location, isLoading, typeInformation, clientSlug = '', dispatch, }) => {
2162
- const { locale, t } = useTranslations.useTranslations();
2163
- const { selectedLocation } = state;
2164
- const typeSlug = React.useMemo(() => typeInformation[type].slug, [typeInformation, type]);
2165
- const handleOnClick = (item) => {
2166
- let url = '';
2167
- switch (type) {
2168
- case 'service':
2169
- url = `/${selectedLocation.slug}/${typeSlug}/${item.slug}`;
2170
- break;
2171
- case 'doctor':
2172
- case 'hospital':
2173
- url = `/${typeSlug}/${item.slug}-${item.id}`;
2174
- break;
2175
- }
2176
- if (url) {
2177
- dispatch({
2178
- type: ActionTypes.NavigateTo,
2179
- payload: url,
2180
- });
2181
- }
2182
- };
2183
- const handleSeeAll = () => {
2184
- let url = `/${selectedLocation.slug}/${typeSlug}`;
2185
- const slugClientUrl = constants.MAPPING_CLIENT_WITH_SLUG[locale][clientSlug];
2186
- if (slugClientUrl) {
2187
- url += `/${slugClientUrl}`;
2188
- }
2189
- if ((type === 'doctor' || type === 'hospital') &&
2190
- state.selectedSpecialty.id > 0) {
2191
- url += `?specialtyId=${state.selectedSpecialty.id}`;
2192
- }
2193
- if (url) {
2194
- dispatch({ type: ActionTypes.NavigateTo, payload: url });
2195
- }
2196
- };
2197
- return (React__default["default"].createElement(StyledSearchResultWrapper, null,
2198
- React__default["default"].createElement(StyleResultHeader, null,
2199
- React__default["default"].createElement("div", { className: "title" }, t('booking.searchResult.description', {
2200
- search_type: typeInformation[type].name,
2201
- search_location: location,
2202
- })),
2203
- results.length > 0 && (React__default["default"].createElement("div", { className: "btn-see-all", onClick: handleSeeAll }, t('home.seeAll')))),
2204
- React__default["default"].createElement(StyleResultBody, null,
2205
- isLoading &&
2206
- Array(3)
2207
- .fill(undefined)
2208
- .map((_, i) => (React__default["default"].createElement(StyleResultItem, { key: type + 'loading' + i, className: i === 2 ? 'last-item' : '' },
2209
- React__default["default"].createElement("div", { className: "image-item" },
2210
- React__default["default"].createElement(core.Skeleton, { height: 48, circle: true, mb: "xl", animate: true })),
2211
- React__default["default"].createElement("div", { className: "infor" },
2212
- React__default["default"].createElement("div", { className: "title" },
2213
- React__default["default"].createElement(core.Skeleton, { height: 8, mt: 10, radius: "xl", animate: true })),
2214
- React__default["default"].createElement("div", { className: "description" },
2215
- React__default["default"].createElement("div", { className: "sub-description" },
2216
- React__default["default"].createElement(core.Skeleton, { height: 8, mt: 10, radius: "xl", width: "80%", animate: true }))))))),
2217
- !isLoading && results && results.length > 0 && (React__default["default"].createElement(React__default["default"].Fragment, null, results.map((item, index) => {
2218
- var _a, _b;
2219
- const isLastItem = (results.length > 4 && index === 3) ||
2220
- (results.length <= 4 && index === results.length - 1);
2221
- let subDescription = '';
2222
- if (type === 'hospital') {
2223
- subDescription = (item === null || item === void 0 ? void 0 : item.address) || '';
2224
- }
2225
- if (type === 'doctor') {
2226
- subDescription = ((_a = item === null || item === void 0 ? void 0 : item.specialties) === null || _a === void 0 ? void 0 : _a.join(', ')) || '';
2227
- }
2228
- if (type === 'service') {
2229
- subDescription = ((_b = item === null || item === void 0 ? void 0 : item.hospital_branch) === null || _b === void 0 ? void 0 : _b.name) || '';
2230
- }
2231
- if (index >= 4) {
2232
- return React__default["default"].createElement(React__default["default"].Fragment, null);
2233
- }
2234
- return (React__default["default"].createElement(StyleResultItem, { key: item.id, className: isLastItem ? 'last-item' : '', onClick: () => handleOnClick(item) },
2235
- React__default["default"].createElement("div", { className: "image-item" },
2236
- React__default["default"].createElement("img", { src: item.logo || item.avatar, alt: item.name })),
2237
- React__default["default"].createElement("div", { className: "infor" },
2238
- React__default["default"].createElement("div", { className: "title" }, item.name),
2239
- React__default["default"].createElement("div", { className: "description" },
2240
- typeInformation[type].icon,
2241
- React__default["default"].createElement("div", { className: "sub-description" }, subDescription)))));
2242
- }))),
2243
- !isLoading && (results === null || results === void 0 ? void 0 : results.length) === 0 && (React__default["default"].createElement(index$2.Text, { size: "sm", color: miscTheme.theme.colors.gray400 }, t('booking.searchBar.noResults'))))));
2244
- };
2245
-
2246
- const StyleSearchSpecialtyWrapper = styled__default["default"].div `
2247
- position: relative;
2248
-
2249
- ${utils.MediaQueries.mbDown} {
2250
- width: 100%;
2251
- display: flex;
2252
- flex-direction: column;
2253
- gap: 12px;
2254
- }
2255
- `;
2256
- const StyleResultWrapper$1 = styled__default["default"].div `
2257
- position: absolute;
2258
- top: calc(100% + 2px);
2259
- width: calc(100% + 100px);
2260
- border-radius: 4px;
2261
- background: ${miscTheme.theme.colors.white};
2262
- box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
2263
- z-index: 10;
2264
- max-height: 300px;
2265
- overflow: auto;
2266
-
2267
- ${utils.MediaQueries.mbDown} {
2268
- width: calc(100% + 64px);
2269
- left: -32px;
2270
- }
2271
- `;
2272
- const StyledSpecialtyItem = styled__default["default"].li `
2273
- position: relative;
2274
- cursor: pointer;
2275
- padding: 12px 18px;
2276
- display: flex;
2277
- align-items: center;
2278
- gap: 14px;
2279
- overflow: hidden;
2280
-
2281
- .image-item {
2282
- display: flex;
2283
- align-items: center;
2284
- width: 40px;
2285
- height: 40px;
2286
-
2287
- img {
2288
- width: 100%;
2289
- object-fit: cover;
2290
- }
2291
-
2292
- svg {
2293
- width: 40px;
2294
- }
2295
- }
2296
-
2297
- ${({ isSelected }) => isSelected &&
2298
- `
2299
- &::after {
2300
- content: ${checkMarkIconUrl};
2301
- top: 50%;
2302
- right: 18px;
2303
- position: absolute;
2304
- transform: translateY(-50%);
2305
- }
2306
- `}
2307
-
2308
- & + li::before {
2309
- content: '';
2310
- position: absolute;
2311
- left: 18px;
2312
- right: 18px;
2313
- top: 0;
2314
- height: 1px;
2315
- background-color: ${miscTheme.theme.colors.neutral100};
2316
- }
2317
-
2318
- &:not([data-is-denied='true']):hover {
2319
- background-color: ${miscTheme.theme.colors.neutral50};
2320
- }
2321
-
2322
- &:last-child:hover {
2323
- border-bottom-right-radius: 6px;
2324
- border-bottom-left-radius: 6px;
2325
- }
2326
-
2327
- &:first-child:hover {
2328
- border-top-right-radius: 6px;
2329
- border-top-left-radius: 6px;
2330
- }
2331
-
2332
- &[data-is-denied='true'] {
2333
- cursor: not-allowed;
2334
- }
2335
- `;
2336
-
2337
- const DoctorIcon = () => (React__default["default"].createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
2338
- React__default["default"].createElement("path", { d: "M8.983 14.333q-1.666 0-2.833-1.166Q4.983 12 4.983 10.333v-.366a3.48 3.48 0 0 1-2.258-1.2 3.57 3.57 0 0 1-.909-2.434V3.1a.58.58 0 0 1 .175-.425.58.58 0 0 1 .425-.175h1.4v-.167a.486.486 0 0 1 .5-.5q.217 0 .36.142a.5.5 0 0 1 .14.358v1.334a.485.485 0 0 1-.5.5.484.484 0 0 1-.5-.5V3.5h-1v2.833q0 1.1.784 1.884Q4.383 9 5.483 9t1.883-.783.784-1.884V3.5h-1v.167a.485.485 0 0 1-.5.5.484.484 0 0 1-.5-.5V2.333a.486.486 0 0 1 .5-.5q.217 0 .358.142a.5.5 0 0 1 .142.358V2.5h1.4a.58.58 0 0 1 .425.175.58.58 0 0 1 .175.425v3.233q0 1.4-.908 2.434a3.5 3.5 0 0 1-2.259 1.2v.366q0 1.25.875 2.126a2.9 2.9 0 0 0 2.125.874q1.25 0 2.125-.874a2.9 2.9 0 0 0 .875-2.126V9.25a1.74 1.74 0 0 1-.858-.609 1.6 1.6 0 0 1-.342-1.008q0-.716.5-1.216t1.2-.5q.716 0 1.217.5.5.5.5 1.216 0 .567-.342 1.008t-.875.609v1.083q0 1.667-1.167 2.834-1.166 1.166-2.833 1.166m3.5-6q.3 0 .509-.208a.67.67 0 0 0 .208-.492q0-.3-.208-.508a.7.7 0 0 0-.509-.208q-.3 0-.5.208a.7.7 0 0 0-.2.508q0 .284.2.492t.5.208", fill: "#595959" })));
2339
- const ServiceIcon = () => (React__default["default"].createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
2340
- React__default["default"].createElement("path", { d: "M6.868 9.265v.974q0 .405.284.69.284.283.69.283t.69-.284.284-.69v-.973h.973q.405 0 .69-.284a.94.94 0 0 0 .284-.689.94.94 0 0 0-.284-.69.94.94 0 0 0-.69-.284h-.973v-.974a.94.94 0 0 0-.284-.69.94.94 0 0 0-.69-.284.94.94 0 0 0-.689.284.94.94 0 0 0-.285.69v.974h-.973a.94.94 0 0 0-.69.283.94.94 0 0 0-.284.69q0 .405.284.69.285.284.69.284zm-3.46 4.868q-.581 0-.994-.413A1.36 1.36 0 0 1 2 12.725v-6.65a1.4 1.4 0 0 1 .563-1.127l4.434-3.333q.369-.282.844-.282.474 0 .846.282l4.434 3.333q.264.193.413.493.15.3.15.633v6.651q0 .58-.414.995a1.36 1.36 0 0 1-.994.413zm0-1.168h8.868q.105 0 .172-.068a.23.23 0 0 0 .068-.172v-6.65a.2.2 0 0 0-.027-.11.3.3 0 0 0-.07-.085L7.983 2.554a.2.2 0 0 0-.142-.052.2.2 0 0 0-.142.052L3.266 5.88a.3.3 0 0 0-.071.086.2.2 0 0 0-.027.108v6.651q0 .105.068.172a.23.23 0 0 0 .172.068", fill: "#595959" })));
2341
- const HospitalIcon = () => (React__default["default"].createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
2342
- React__default["default"].createElement("path", { d: "M8 8q.55 0 .941-.392.393-.391.392-.941 0-.55-.392-.942A1.28 1.28 0 0 0 8 5.333q-.55 0-.942.392a1.28 1.28 0 0 0-.391.942q0 .55.391.941Q7.45 8 8 8m0 4.9q2.032-1.866 3.017-3.392Q12 7.983 12 6.8q0-1.817-1.158-2.975Q9.682 2.667 8 2.667T5.158 3.825Q4 4.983 4 6.8q0 1.184.983 2.708Q5.966 11.034 8 12.9m0 1.517a.8.8 0 0 1-.5-.183q-2.433-2.151-3.633-3.992T2.667 6.8q0-2.5 1.608-3.983Q5.883 1.332 8 1.333q2.116 0 3.725 1.484T13.333 6.8q0 1.6-1.2 3.442-1.2 1.841-3.633 3.991a.8.8 0 0 1-.5.184", fill: "#8C8C8C" })));
2343
- const SpecialtyIcon = () => (React__default["default"].createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" },
2344
- React__default["default"].createElement("path", { d: "M3.833.5a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667M10.5.5c-.92 0-1.667.746-1.667 1.667V5.5c0 .92.746 1.667 1.667 1.667h3.333c.921 0 1.667-.746 1.667-1.667V2.167C15.5 1.246 14.754.5 13.833.5zM3.833 8.833a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667m8.334 0a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667", fill: "#9AA2AC" })));
2345
-
2346
- const SearchSpecialty = ({ state, isMobile, debouncedFetchSearchResults, selectedLocation, onSpecialtyClick, dispatch, }) => {
2347
- var _a;
2348
- const { t, locale } = useTranslations.useTranslations();
2349
- const inputSpecialtyWrapperRef = React.useRef(null);
2350
- const slugs = React.useMemo(() => constants.LOCALIZED_SLUGS[locale], [locale]);
2351
- const styleSpecialties = React.useMemo(() => {
2352
- return {
2353
- wrapper: {
2354
- '&:after': {
2355
- content: '""',
2356
- width: '1px',
2357
- height: '20px',
2358
- backgroundColor: '#E4E8EC',
2359
- position: 'absolute',
2360
- right: 0,
2361
- top: '13px',
2362
- },
2363
- },
2364
- input: {
2365
- border: isMobile ? 'border: 1px solid #d9d9d9' : 'none',
2366
- height: isMobile ? '40px' : '46px !important',
2367
- paddingRight: '30px',
2368
- '&:focus': {
2369
- boxShadow: isMobile ? 'box-shadow: 0px 0px 0px 2px #91caff' : 'none',
2370
- },
2371
- },
2372
- rightSection: {
2373
- width: '30px',
2374
- svg: {
2375
- fontSize: '20px',
2376
- },
2377
- },
2378
- };
2379
- }, [isMobile]);
2380
- const handleSearchSpecialtyInputChange = React.useCallback(function handleSearchSpecialtyInputChange(value) {
2381
- // dispatch({ type: ActionTypes.ChangeInputLocation, payload: value })
2382
- // if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale]) {
2383
- // debouncedFetchSearchResults(value.trim())
2384
- // } else {
2385
- // debouncedFetchSearchResults.cancel()
2386
- // dispatch({ type: ActionTypes.DisplayInitialCities })
2387
- // }
2388
- console.log(value);
2389
- }, [debouncedFetchSearchResults, dispatch]);
2390
- useOutsideClick.useOutsideClick(inputSpecialtyWrapperRef, () => {
2391
- dispatch({ type: ActionTypes.ClickOutsideInputSpecialty });
2392
- });
2393
- return (React__default["default"].createElement(StyleSearchSpecialtyWrapper, { ref: inputSpecialtyWrapperRef },
2394
- React__default["default"].createElement(core.Input.Wrapper, null,
2395
- React__default["default"].createElement(core.Input, { size: isMobile ? 'md' : 'lg', placeholder: t('booking.searchPopup.specialties'), value: ((_a = state === null || state === void 0 ? void 0 : state.selectedSpecialty) === null || _a === void 0 ? void 0 : _a.name) || '', rightSection: React__default["default"].createElement(ChevronDown.ChevronDown, null), styles: styleSpecialties, onFocus: () => dispatch({ type: ActionTypes.FocusInputSpecialty }), onChange: (event) => {
2396
- handleSearchSpecialtyInputChange(event.target.value);
2397
- } })),
2398
- state.focused === 'specialty' && (React__default["default"].createElement(StyleResultWrapper$1, null,
2399
- React__default["default"].createElement(StyledSpecialtyItem, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
2400
- if (onSpecialtyClick) {
2401
- onSpecialtyClick({
2402
- name: t('booking.searchBar.allSpecialties'),
2403
- id: -1,
2404
- thumbnail: '',
2405
- total_doctor: 0,
2406
- slug: slugs.SPECIALTIES,
2407
- });
2408
- }
2409
- } },
2410
- React__default["default"].createElement("div", { className: "image-item" },
2411
- React__default["default"].createElement(SpecialtyIcon, null)),
2412
- React__default["default"].createElement(index$2.Text, { size: "md" }, t('booking.searchBar.allSpecialties'))),
2413
- state.allSpecialties.map((specialty) => (React__default["default"].createElement(StyledSpecialtyItem, { key: specialty.id, onClick: (evt) => {
2414
- evt.nativeEvent.stopImmediatePropagation();
2415
- if (onSpecialtyClick) {
2416
- onSpecialtyClick(Object.assign(Object.assign({}, specialty), { total_doctor: 0 }));
2417
- }
2418
- }, role: "button", tabIndex: 0, "aria-label": `Select ${specialty.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === specialty.id },
2419
- React__default["default"].createElement("div", { className: "image-item" },
2420
- React__default["default"].createElement("img", { src: specialty.thumbnail, alt: specialty.name })),
2421
- React__default["default"].createElement(index$2.Text, { size: "md" }, specialty.name))))))));
2422
- };
2423
-
2424
- const SearchInputs = ({ state, type, isMobile, isLoading, initalSearchValue, typeInformation, debouncedFetchSearchResults, trackingAttributes, hideSpecialtySelection = false, clientSlug = '', focusSearchInput, onSearch, onEnterSearch, dispatch, }) => {
2425
- var _a;
2426
- const { t } = useTranslations.useTranslations();
2427
- const inputSearchWrapperRef = React.useRef(null);
2428
- const gaAttributes = React.useMemo(() => {
2429
- if (trackingAttributes) {
2430
- return {
2431
- 'data-event-category': trackingAttributes.dataEventCategory,
2432
- 'data-event-action': trackingAttributes.dataEventAction,
2433
- 'data-event-label': trackingAttributes.dataEventLabel,
2434
- };
2435
- }
2436
- else {
2437
- return {};
2438
- }
2439
- }, [trackingAttributes]);
2440
- const placeholderSearch = React.useMemo(() => {
2441
- if (type === 'doctor') {
2442
- return t('booking.searchBar.placeholder.doctor');
2443
- }
2444
- if (type === 'service') {
2445
- return t('booking.searchBar.placeholder.service');
2446
- }
2447
- if (type === 'hospital') {
2448
- return t('booking.searchBar.placeholder.hospital');
2449
- }
2450
- if (type === 'specialty') {
2451
- return t('booking.searchBar.placeholder.specialty');
2452
- }
2453
- return '';
2454
- }, [type]);
2455
- const styleInputWrapper = React.useMemo(() => {
2456
- return {
2457
- root: {
2458
- flex: 1,
2459
- '&.hide-specialty-selection': {
2460
- '.mantine-Input-rightSection': {
2461
- display: 'none',
2462
- },
2463
- input: {
2464
- paddingLeft: '48px',
2465
- },
2466
- '.mantine-Input-icon': {
2467
- left: '0',
2468
- },
2469
- },
2470
- },
2471
- };
2472
- }, []);
2473
- const styleInput = React.useMemo(() => {
2474
- return {
2475
- icon: {
2476
- left: '165px',
2477
- },
2478
- input: {
2479
- color: '#262626',
2480
- '&[data-with-icon="true"]': {
2481
- paddingLeft: '205px',
2482
- paddingRight: '16px',
2483
- },
2484
- },
2485
- rightSection: {
2486
- left: 0,
2487
- width: '165px',
2488
- padding: '1px',
2489
- },
2490
- };
2491
- }, []);
2492
- const styleInputSpecialties = React.useMemo(() => {
2493
- return {
2494
- input: {
2495
- color: '#262626',
2496
- },
2497
- };
2498
- }, []);
2499
- useOutsideClick.useOutsideClick(inputSearchWrapperRef, () => {
2500
- dispatch({ type: ActionTypes.ClickOutsideInputSearch });
2501
- });
2502
- const handleSearchInputChange = React.useCallback(function handleSearchInputChange(value) {
2503
- dispatch({ type: ActionTypes.ChangeInputSearch, payload: value });
2504
- if (typeof onSearch === 'function') {
2505
- return;
2506
- }
2507
- if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] ||
2508
- initalSearchValue ||
2509
- value.trim().length === 0) {
2510
- debouncedFetchSearchResults(value.trim(), state, type, clientSlug);
2511
- }
2512
- else {
2513
- debouncedFetchSearchResults.cancel();
2514
- dispatch({ type: ActionTypes.DisplayInitialSearchResults });
2515
- }
2516
- }, [dispatch, state, type]);
2517
- const handleSpecialtyClick = React.useCallback(function handleSpecialtyClick(specialty) {
2518
- dispatch({ type: ActionTypes.SelectSpecialty, payload: specialty });
2519
- focusSearchInput();
2520
- }, [dispatch]);
2521
- const inputOnKeyDown = React.useCallback((e) => {
2522
- if (e.keyCode === 13) {
2523
- e.stopPropagation();
2524
- e.preventDefault();
2525
- onEnterSearch && onEnterSearch();
2526
- }
2527
- }, [onEnterSearch]);
2528
- return (React__default["default"].createElement(StyleSearchInputsWrapper, { ref: inputSearchWrapperRef }, type === 'specialty' ? (React__default["default"].createElement(core.Input.Wrapper, { styles: styleInputWrapper },
2529
- React__default["default"].createElement(core.Input, { icon: React__default["default"].createElement(core$1.Search, null), size: isMobile ? 'md' : 'lg', placeholder: placeholderSearch, styles: styleInputSpecialties, value: state.searchKeywords, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearchSpecialty }), onChange: (event) => {
2530
- handleSearchInputChange(event.target.value);
2531
- }, onKeyDown: inputOnKeyDown }))) : (React__default["default"].createElement(React__default["default"].Fragment, null,
2532
- type === 'service' ? (React__default["default"].createElement(core.Input.Wrapper, { styles: styleInputWrapper },
2533
- React__default["default"].createElement(core.Input, { icon: React__default["default"].createElement(core$1.Search, null), size: isMobile ? 'md' : 'lg', name: "search-results", placeholder: placeholderSearch, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), value: state.searchKeywords, onChange: (event) => {
2534
- handleSearchInputChange(event.target.value);
2535
- }, onKeyDown: inputOnKeyDown }))) : (React__default["default"].createElement(React__default["default"].Fragment, null, isMobile && !hideSpecialtySelection ? (React__default["default"].createElement(React__default["default"].Fragment, null,
2536
- React__default["default"].createElement(SearchSpecialty, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchSearchResults: debouncedFetchSearchResults, onSpecialtyClick: handleSpecialtyClick }),
2537
- React__default["default"].createElement(core.Input.Wrapper, { styles: styleInputWrapper },
2538
- React__default["default"].createElement(core.Input, { icon: React__default["default"].createElement(core$1.Search, null), size: "md", placeholder: placeholderSearch, value: state.searchKeywords, name: "search-results", onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), onChange: (event) => {
2539
- handleSearchInputChange(event.target.value);
2540
- }, onKeyDown: inputOnKeyDown })))) : (React__default["default"].createElement(core.Input.Wrapper, { styles: styleInputWrapper, className: hideSpecialtySelection ? 'hide-specialty-selection' : '' },
2541
- React__default["default"].createElement(core.Input, Object.assign({ icon: React__default["default"].createElement(core$1.Search, null), size: "lg", placeholder: placeholderSearch, styles: styleInput, name: "search-results", autoComplete: "off", value: state.searchKeywords, onChange: (event) => {
2542
- handleSearchInputChange(event.target.value);
2543
- }, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), onKeyDown: inputOnKeyDown }, gaAttributes, { rightSection: hideSpecialtySelection ? (React__default["default"].createElement(React__default["default"].Fragment, null)) : (React__default["default"].createElement(SearchSpecialty, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchSearchResults: debouncedFetchSearchResults, onSpecialtyClick: handleSpecialtyClick })) })))))),
2544
- state.focused === 'search' && (React__default["default"].createElement(StyleResultWrapper$2, null,
2545
- React__default["default"].createElement(SearchResult, { type: type, state: state, results: ((_a = state.searchResults) === null || _a === void 0 ? void 0 : _a[type]) || [], location: state.selectedLocation.name, dispatch: dispatch, isLoading: isLoading, typeInformation: typeInformation, clientSlug: clientSlug })))))));
2546
- };
2547
-
2548
- const StyleSearchLocationWrapper = styled__default["default"].div `
2549
- position: relative;
2550
-
2551
- ${utils.MediaQueries.mbDown} {
2552
- width: 100%;
2553
- display: flex;
2554
- flex-direction: column;
2555
- gap: 12px;
2556
- }
2557
- `;
2558
- const StyleResultWrapper = styled__default["default"].div `
2559
- position: absolute;
2560
- top: calc(100% + 2px);
2561
- width: 100%;
2562
- border-radius: 4px;
2563
- background: ${miscTheme.theme.colors.white};
2564
- box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
2565
- z-index: 10;
2566
-
2567
- ${utils.MediaQueries.mbDown} {
2568
- width: calc(100% + 64px);
2569
- left: -32px;
2570
- }
2571
- `;
2572
- const StyledLocationItem = styled__default["default"].li `
2573
- position: relative;
2574
- cursor: pointer;
2575
- padding: 12px 18px;
2576
- display: flex;
2577
- align-items: center;
2578
- gap: 14px;
2579
- overflow: hidden;
2580
-
2581
- ${({ isSelected }) => isSelected &&
2582
- `
2583
- &::after {
2584
- content: ${checkMarkIconUrl};
2585
- top: 50%;
2586
- right: 18px;
2587
- position: absolute;
2588
- transform: translateY(-50%);
2589
- }
2590
- `}
2591
-
2592
- & + li::before {
2593
- content: '';
2594
- position: absolute;
2595
- left: 18px;
2596
- right: 18px;
2597
- top: 0;
2598
- height: 1px;
2599
- background-color: ${miscTheme.theme.colors.neutral100};
2600
- }
2601
-
2602
- &:not([data-is-denied='true']):hover {
2603
- background-color: ${miscTheme.theme.colors.neutral50};
2604
- }
2605
-
2606
- &:last-child:hover {
2607
- border-bottom-right-radius: 6px;
2608
- border-bottom-left-radius: 6px;
2609
- }
2610
-
2611
- &:first-child:hover {
2612
- border-top-right-radius: 6px;
2613
- border-top-left-radius: 6px;
2614
- }
2615
-
2616
- &[data-is-denied='true'] {
2617
- cursor: not-allowed;
2618
- }
2619
- `;
2620
- const StyledPinIcon = styled__default["default"](PinIcon) `
2621
- width: 12px;
2622
- height: 18px;
2623
- flex: 0 0 12px;
2624
- `;
2625
-
2626
- const SearchLocation = ({ state, isMobile, debouncedFetchCitiesByKeyword, selectedLocation, trackingAttributes, onLocationClick, dispatch, }) => {
2627
- const { t, locale } = useTranslations.useTranslations();
2628
- const inputLocationWrapperRef = React.useRef(null);
2629
- const gaAttributes = React.useMemo(() => {
2630
- if (trackingAttributes) {
2631
- return {
2632
- 'data-event-category': trackingAttributes.dataEventCategory,
2633
- 'data-event-action': trackingAttributes.dataEventAction,
2634
- 'data-event-label': trackingAttributes.dataEventLabel,
2635
- };
2636
- }
2637
- else {
2638
- return {};
2639
- }
2640
- }, [trackingAttributes]);
2641
- const handleSearchLocationInputChange = React.useCallback(function handleSearchLocationInputChange(value) {
2642
- dispatch({ type: ActionTypes.ChangeInputLocation, payload: value });
2643
- if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale]) {
2644
- debouncedFetchCitiesByKeyword(value.trim());
2645
- }
2646
- else {
2647
- debouncedFetchCitiesByKeyword.cancel();
2648
- dispatch({ type: ActionTypes.DisplayInitialCities });
2649
- }
2650
- }, [debouncedFetchCitiesByKeyword, dispatch]);
2651
- useOutsideClick.useOutsideClick(inputLocationWrapperRef, () => {
2652
- dispatch({ type: ActionTypes.ClickOutsideInputLocation });
2653
- });
2654
- return (React__default["default"].createElement(StyleSearchLocationWrapper, { ref: inputLocationWrapperRef },
2655
- React__default["default"].createElement(core.Input.Wrapper, null,
2656
- React__default["default"].createElement(core.Input, Object.assign({ size: isMobile ? 'md' : 'lg', placeholder: "Search location", value: state.searchLocationKeywords, onFocus: () => dispatch({ type: ActionTypes.FocusInputLocation }), onChange: (event) => {
2657
- handleSearchLocationInputChange(event.target.value);
2658
- } }, gaAttributes))),
2659
- state.focused === 'location' && (React__default["default"].createElement(StyleResultWrapper, null,
2660
- React__default["default"].createElement(StyledLocationItem, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
2661
- var _a;
2662
- if (onLocationClick) {
2663
- onLocationClick({
2664
- name: t('booking.searchBar.allLocations'),
2665
- id: constants.ID_OPTION_ALL_LOCATION,
2666
- slug: (_a = constants.LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
2667
- });
2668
- }
2669
- } },
2670
- React__default["default"].createElement(StyledPinIcon, { color: miscTheme.theme.colors.neutral400 }),
2671
- React__default["default"].createElement(index$2.Text, { size: "md" }, t('booking.searchBar.allLocations'))),
2672
- state.cities.map((city) => (React__default["default"].createElement(StyledLocationItem, { key: city.id, onClick: (evt) => {
2673
- evt.nativeEvent.stopImmediatePropagation();
2674
- if (onLocationClick) {
2675
- onLocationClick(city);
2676
- }
2677
- }, role: "button", tabIndex: 0, "aria-label": `Select ${city.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === city.id },
2678
- React__default["default"].createElement(StyledPinIcon, { color: miscTheme.theme.colors.neutral400 }),
2679
- React__default["default"].createElement(index$2.Text, { size: "md" }, city.name))))))));
2680
- };
2681
-
2682
- const StyleSpecialtiesWrapper = styled__default["default"].div `
2683
- display: flex;
2684
- flex-wrap: wrap;
2685
- row-gap: 8px;
2686
- column-gap: 20px;
2687
- ${utils.MediaQueries.mbDown} {
2688
- margin-top: 12px;
2689
- }
2690
- `;
2691
- const StyleSpecialtyItem = styled__default["default"].div `
2692
- display: flex;
2693
- align-items: center;
2694
- border-radius: 8px;
2695
- border: 1px solid ${miscTheme.theme.colors.neutral100};
2696
- background: ${miscTheme.theme.colors.white};
2697
- padding: 8px 12px 8px 8px;
2698
- flex: 0 0 calc(33.3% - 13px);
2699
- gap: 12px;
2700
- cursor: pointer;
2701
-
2702
- &:hover {
2703
- background: ${miscTheme.theme.colors.blue50};
2704
- }
2705
-
2706
- ${utils.MediaQueries.tdDown} {
2707
- flex: 0 0 calc(50% - 10px);
2708
- }
2709
-
2710
- ${utils.MediaQueries.mbDown} {
2711
- flex: 0 0 100%;
2712
- border: none;
2713
- }
2714
-
2715
- .image-item {
2716
- display: flex;
2717
- align-items: center;
2718
- width: 40px;
2719
- height: 40px;
2720
-
2721
- img {
2722
- width: 100%;
2723
- object-fit: cover;
2724
- }
2725
- }
2726
-
2727
- .infor {
2728
- flex: 1;
2729
- .title {
2730
- color: ${miscTheme.theme.colors.gray800};
2731
- font-size: 14px;
2732
- font-style: normal;
2733
- font-weight: 400;
2734
- line-height: 22px;
2735
- }
2736
-
2737
- .description {
2738
- color: ${miscTheme.theme.colors.gray600};
2739
- font-size: 12px;
2740
- font-weight: 400;
2741
- line-height: 18px;
2742
- }
2743
- }
2744
- `;
2745
- const StyleDivider = styled__default["default"](core.Divider) `
2746
- margin: 24px 0 !important;
2747
- `;
2748
- const StyleShowMore = styled__default["default"].div `
2749
- display: flex;
2750
- justify-content: center;
2751
- margin-top: 24px;
2752
- .show-more {
2753
- border-radius: 4px;
2754
- border: 1px solid ${miscTheme.theme.colors.neutral200};
2755
- padding: 12px 16px;
2756
- cursor: pointer;
2757
- display: inline-block;
2758
- color: ${miscTheme.theme.colors.gray800};
2759
- font-size: 16px;
2760
- font-weight: 600;
2761
- line-height: 24px;
2762
-
2763
- ${utils.MediaQueries.mbDown} {
2764
- width: 100%;
2765
- text-align: center;
2766
- }
2767
- }
2768
- `;
2769
-
2770
- const SearchResultSpecialties = ({ state, isMobile, specialties, isLoading, dispatch, }) => {
2771
- const { t, locale } = useTranslations.useTranslations();
2772
- const { selectedLocation } = state;
2773
- const slugs = React.useMemo(() => constants.LOCALIZED_SLUGS[locale], [locale]);
2774
- const handleOnClick = (specialtySlug) => {
2775
- let url = '';
2776
- if (specialtySlug === constants.SLUG_VACIN_ID) {
2777
- url = `/${selectedLocation.slug}/${slugs.HOSPITAL}/${constants.CLIENT_KEY.GSK}/`;
2778
- dispatch({ type: ActionTypes.ClickOutsideInputSearchSpecialty });
2779
- }
2780
- else {
2781
- url = `/${selectedLocation.slug}/${slugs.DOCTOR}/${specialtySlug}`;
2782
- }
2783
- dispatch({ type: ActionTypes.NavigateTo, payload: url });
2784
- };
2785
- const handleShowMore = () => {
2786
- const url = `/${slugs.SPECIALTIES}`;
2787
- dispatch({ type: ActionTypes.NavigateTo, payload: url });
2788
- };
2789
- const showSeeMore = React.useMemo(() => {
2790
- return (specialties.length >= 9 ||
2791
- state.searchKeywords.trim().length <=
2792
- SEARCH_KEYWORD_MIN_LENGTH[state.locale]);
2793
- }, [state.searchKeywords, specialties]);
2794
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
2795
- !isMobile && React__default["default"].createElement(StyleDivider, { color: "#E4E8EC" }),
2796
- React__default["default"].createElement(StyleSpecialtiesWrapper, null,
2797
- specialties.length > 0 && !isLoading && (React__default["default"].createElement(React__default["default"].Fragment, null, specialties.map((specialty, index) => {
2798
- if (index >= 9) {
2799
- return React__default["default"].createElement(React__default["default"].Fragment, null);
2800
- }
2801
- return (React__default["default"].createElement(StyleSpecialtyItem, { key: specialty.id, onClick: () => handleOnClick(specialty.slug) },
2802
- React__default["default"].createElement("div", { className: "image-item" },
2803
- React__default["default"].createElement("img", { src: specialty.thumbnail, alt: specialty.name })),
2804
- React__default["default"].createElement("div", { className: "infor" },
2805
- React__default["default"].createElement("div", { className: "title" }, specialty.name))));
2806
- }))),
2807
- specialties.length === 0 && !isLoading && (React__default["default"].createElement(index$2.Text, { size: "sm", color: miscTheme.theme.colors.gray400 }, t('booking.searchBar.noResults'))),
2808
- isLoading &&
2809
- Array(6)
2810
- .fill(undefined)
2811
- .map((_, i) => (React__default["default"].createElement(StyleSpecialtyItem, { key: 'loading' + i },
2812
- React__default["default"].createElement("div", { className: "image-item" },
2813
- React__default["default"].createElement(core.Skeleton, { height: 40, animate: true })),
2814
- React__default["default"].createElement("div", { className: "infor" },
2815
- React__default["default"].createElement("div", { className: "title" },
2816
- React__default["default"].createElement(core.Skeleton, { height: 20, radius: "sm", animate: true }))))))),
2817
- showSeeMore && (React__default["default"].createElement(StyleShowMore, null,
2818
- React__default["default"].createElement("div", { className: "show-more", onClick: handleShowMore }, t('home.seeAll'))))));
2819
- };
2820
-
2821
- const StyleSearchTagWrapper = styled__default["default"].div `
2822
- display: flex;
2823
- gap: 5px;
2824
- margin-top: 16px;
2825
- flex-wrap: wrap;
2826
- `;
2827
- const StyleTagItem = styled__default["default"].div `
2828
- color: ${miscTheme.theme.colors.gray600};
2829
- font-size: 14px;
2830
- font-weight: 600;
2831
- line-height: 22px;
2832
- padding: 4px 12px;
2833
- background: ${miscTheme.theme.colors.white};
2834
- border-radius: 32px;
2835
- cursor: pointer;
2836
- border: 1px solid ${miscTheme.theme.colors.white};
2837
- margin-bottom: 5px;
2838
- border-color: ${miscTheme.theme.colors.neutral100};
2839
- background: #f7f9fc;
2840
-
2841
- &.view-all {
2842
- border-radius: 32px;
2843
- border-color: ${miscTheme.theme.colors.blue50};
2844
- background: ${miscTheme.theme.colors.blue50};
2845
- color: ${miscTheme.theme.colors.blue600};
2846
-
2847
- &:hover {
2848
- border-color: ${miscTheme.theme.colors.blue50};
2849
- background: ${miscTheme.theme.colors.blue50};
2850
- color: ${miscTheme.theme.colors.blue600};
2851
- }
2852
- }
2853
-
2854
- &:hover {
2855
- border-color: ${miscTheme.theme.colors.neutral100};
2856
- background: #f7f9fc;
2857
- }
2858
- `;
2859
- const StyleTagLabel = styled__default["default"].div `
2860
- color: ${miscTheme.theme.colors.gray600};
2861
- font-size: 14px;
2862
- font-weight: 600;
2863
- line-height: 22px;
2864
- padding: 4px 0;
2865
- background: ${miscTheme.theme.colors.white};
2866
- border-radius: 32px;
2867
- border: 1px solid ${miscTheme.theme.colors.white};
2868
- margin-bottom: 5px;
2869
- margin-right: 7px;
2870
- `;
2871
-
2872
- const SearchTag = ({ state, type, typeInformation, dispatch }) => {
2873
- const { t } = useTranslations.useTranslations();
2874
- const { selectedLocation } = state;
2875
- const typeSlug = React.useMemo(() => typeInformation[type].slug, [typeInformation, type]);
2876
- const handleViewAll = () => {
2877
- const url = `/${selectedLocation.slug}/${typeSlug}`;
2878
- if (url) {
2879
- dispatch({ type: ActionTypes.NavigateTo, payload: url });
2880
- }
2881
- };
2882
- const handleClickKeyword = (keyword) => {
2883
- if (keyword.url) {
2884
- window.location.href = keyword.url;
2885
- }
2886
- };
2887
- return (React__default["default"].createElement(StyleSearchTagWrapper, null,
2888
- React__default["default"].createElement(StyleTagLabel, null, t('booking.searchBar.popularKey')),
2889
- state.popularKeys.map((item) => {
2890
- return (React__default["default"].createElement(StyleTagItem, { key: item.id, onClick: () => handleClickKeyword(item) }, item.keyword));
2891
- }),
2892
- React__default["default"].createElement(StyleTagItem, { className: "view-all", onClick: handleViewAll }, t('booking.searchBar.viewAll'))));
2893
- };
2894
-
2895
- const StyledTabWrapper = styled__default["default"].div `
2896
- background: rgba(255, 255, 255, 0.64);
2897
- backdrop-filter: blur(12px);
2898
- border-bottom: 1px solid ${miscTheme.theme.colors.neutral100};
2899
- `;
2900
- const StyleTabContainer = styled__default["default"](index$3.Container) `
2901
- padding: 0 16px;
2902
- `;
2903
-
2904
- const itemTabs = () => {
2905
- const { t } = useTranslations.useTranslations();
2906
- return [
2907
- {
2908
- value: 'hospital',
2909
- label: t('booking.searchPopup.hospitals'),
2910
- },
2911
- {
2912
- value: 'doctor',
2913
- label: t('booking.searchPopup.doctors'),
2914
- },
2915
- {
2916
- value: 'service',
2917
- label: t('booking.searchPopup.services'),
2918
- },
2919
- {
2920
- value: 'specialty',
2921
- label: t('booking.searchPopup.specialties'),
2922
- },
2923
- ];
2924
- };
2925
- const TabSearch = ({ currentTab, hideTabBookingSearch = [], isMobile, setCurrentTab, }) => {
2926
- const stylesTabs = React.useMemo(() => {
2927
- return {
2928
- root: {
2929
- overflowY: isMobile ? 'hidden' : 'initial',
2930
- overflowX: isMobile ? 'auto' : 'initial',
2931
- },
2932
- tabsList: {
2933
- background: 'rgba(255, 255, 255, 0)',
2934
- borderBottom: 'none',
2935
- flexWrap: 'nowrap',
2936
- '.mantine-Tabs-tab': {
2937
- '&:last-child': {
2938
- '&:after': {
2939
- display: 'none',
2940
- },
2941
- },
2942
- },
2943
- },
2944
- tab: {
2945
- padding: isMobile ? '12px 16px 12px 16px' : '15px 40px 15px 40px',
2946
- borderTop: '2px solid transparent',
2947
- borderBottom: 'none',
2948
- margin: 0,
2949
- borderRadius: 0,
2950
- position: 'relative',
2951
- width: 'auto',
2952
- '&[data-active="true"]': {
2953
- borderColor: '#2d87f3',
2954
- backgroundColor: '#ffffff',
2955
- '&:after': {
2956
- display: 'none',
2957
- },
2958
- '&:before': {
2959
- content: '""',
2960
- width: '100%',
2961
- height: '1px',
2962
- position: 'absolute',
2963
- backgroundColor: '#ffffff',
2964
- bottom: '-1px',
2965
- },
2966
- },
2967
- '&:hover': {
2968
- borderColor: '#2d87f3',
2969
- backgroundColor: '#ffffff',
2970
- '&:before': {
2971
- content: '""',
2972
- width: '100%',
2973
- height: '1px',
2974
- position: 'absolute',
2975
- backgroundColor: '#ffffff',
2976
- bottom: '-1px',
2977
- },
2978
- },
2979
- '&:after': {
2980
- content: '""',
2981
- width: '1px',
2982
- height: '24px',
2983
- backgroundColor: '#E4E8EC',
2984
- position: 'absolute',
2985
- right: '-1px',
2986
- },
2987
- },
2988
- tabLabel: {
2989
- color: '#595959',
2990
- fontSize: isMobile ? '14px' : '16px',
2991
- fontWeight: 600,
2992
- lineHeight: isMobile ? '22px' : '24px',
2993
- },
2994
- };
2995
- }, [isMobile]);
2996
- const tabConfig = itemTabs();
2997
- const activeTabs = React.useMemo(() => {
2998
- return (tabConfig.filter((item) => !hideTabBookingSearch.includes(item.value)) ||
2999
- []);
3000
- }, [hideTabBookingSearch, tabConfig]);
3001
- return (React__default["default"].createElement(StyledTabWrapper, { className: "booking-search-tab" },
3002
- React__default["default"].createElement(StyleTabContainer, null,
3003
- React__default["default"].createElement(core.Tabs, { value: currentTab, onTabChange: (tab) => {
3004
- setCurrentTab(tab);
3005
- }, styles: stylesTabs },
3006
- React__default["default"].createElement(core.Tabs.List, null, activeTabs.map((tab) => {
3007
- return (React__default["default"].createElement(core.Tabs.Tab, { value: tab.value, key: tab.value }, tab.label));
3008
- }))))));
3009
- };
3010
-
3011
- var TypePopularKeySearch;
3012
- (function (TypePopularKeySearch) {
3013
- TypePopularKeySearch["doctor"] = "doctor";
3014
- TypePopularKeySearch["service"] = "hospital_service";
3015
- TypePopularKeySearch["hospital"] = "hospital_branch";
3016
- })(TypePopularKeySearch || (TypePopularKeySearch = {}));
3017
-
3018
- function useSearchBarApi({ dispatch, careApiDomain, locale = 'vi-VN', client = '', }) {
3019
- const fetchCitiesApi = React.useCallback(function fetchCitiesApi(path, params = {}) {
3020
- const url = `${careApiDomain}${path}`;
3021
- dispatch({ type: ActionTypes.FetchCitiesStart });
3022
- return fetch(getApiPath(url, params, locale), { method: 'GET' })
3023
- .then((res) => res.json())
3024
- .then((data) => {
3025
- if (data._status !== 1 || !data._data) {
3026
- console.log('error loading cities', data);
3027
- return Promise.reject(data);
3028
- }
3029
- return data === null || data === void 0 ? void 0 : data._data;
3030
- })
3031
- .finally(() => dispatch({ type: ActionTypes.FetchCitiesFinish }));
3032
- }, [locale]);
3033
- const fetchCitiesByLocation = React.useCallback(function fetchCitiesByLocation({ coordinates }) {
3034
- let params = {};
3035
- const moreParams = {};
3036
- if (coordinates) {
3037
- params = {
3038
- lat: coordinates.lat,
3039
- lng: coordinates.lng,
3040
- };
3041
- }
3042
- if (locale === 'ms-MY') {
3043
- moreParams.noPaging = 1;
3044
- }
3045
- const requests = [
3046
- fetchCitiesApi(paths.PATHS.GET_CITY_BY_IP, Object.assign(Object.assign(Object.assign({}, params), moreParams), { client: constants.CLIENT_KEY.MSD === client ? '' : client })),
3047
- ];
3048
- if (locale === 'zh-TW') {
3049
- requests.push(fetchCitiesApi(paths.PATHS.GET_CITIES_LIST, {
3050
- noPaging: 1,
3051
- client: constants.CLIENT_KEY.MSD === client ? '' : client,
3052
- }));
3053
- }
3054
- return Promise.all(requests)
3055
- .then(([data1, data2]) => {
3056
- const data = Object.assign({}, data1);
3057
- if (data2) {
3058
- const citiesIds = data.cities.map((c) => c.id);
3059
- data.cities = data.cities.concat(data2.cities.filter((c) => !citiesIds.includes(c.id)));
3060
- }
3061
- dispatch({
3062
- type: ActionTypes.FetchCitiesByGeoIpComplete,
3063
- payload: data,
3064
- });
3065
- })
3066
- .catch((err) => console.error('error loading cities by location', err));
3067
- }, [locale, careApiDomain, dispatch]);
3068
- const fetchCitiesByKeyword = React.useCallback(function fetchCitiesByKeyword(keyword) {
3069
- return fetchCitiesApi(paths.PATHS.GET_CITIES_LIST, {
3070
- keyword,
3071
- client,
3072
- })
3073
- .then((data) => {
3074
- dispatch({
3075
- type: ActionTypes.FetchCitiesByKeywordComplete,
3076
- payload: data.cities,
3077
- });
3078
- })
3079
- .catch((err) => console.error('error loading cities by keyword', err));
3080
- }, [locale, careApiDomain, dispatch]);
3081
- const fetchSearchResults = React.useCallback(function fetchSearchResults(searchKeywords, state, searchType, clientSlug, cacheResult) {
3082
- const url = searchType === 'specialty'
3083
- ? `${careApiDomain}${paths.PATHS.GET_SEARCH_SPECIALTY}`
3084
- : `${careApiDomain}${paths.PATHS.GET_SEARCH_V2}`;
3085
- dispatch({ type: ActionTypes.FetchSearchResultsStart });
3086
- const { selectedLocation, geoLocationCoordinates, selectedSpecialty } = state;
3087
- let cityId = '';
3088
- if (!selectedLocation) {
3089
- dispatch({ type: ActionTypes.FetchSearchResultsFinish });
3090
- return;
3091
- }
3092
- if (selectedLocation.id === constants.ID_OPTION_ALL_LOCATION) {
3093
- cityId = '';
3094
- }
3095
- else {
3096
- cityId = selectedLocation.id;
3097
- }
3098
- const lat = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lat) || '';
3099
- const lng = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lng) || '';
3100
- const specialty_id = (selectedSpecialty === null || selectedSpecialty === void 0 ? void 0 : selectedSpecialty.id) > 0 ? selectedSpecialty === null || selectedSpecialty === void 0 ? void 0 : selectedSpecialty.id : '';
3101
- const keyword = searchKeywords.trim().length > SEARCH_KEYWORD_MIN_LENGTH[locale]
3102
- ? searchKeywords.trim()
3103
- : '';
3104
- return fetch(getApiPath(url, {
3105
- domain: careApiDomain,
3106
- searchType: searchType || 'global',
3107
- keyword: keyword,
3108
- city: cityId === constants.ID_OPTION_CURRENT_LOCATION ? '' : cityId,
3109
- lat,
3110
- lng,
3111
- specialty_id,
3112
- client_slug: constants.CLIENT_KEY.MSD === clientSlug ? '' : clientSlug,
3113
- msd: constants.CLIENT_KEY.MSD === client ? 1 : '',
3114
- }, locale), {
3115
- method: 'GET',
3116
- headers: {
3117
- accept: 'version=2.0.0.0',
3118
- },
3119
- })
3120
- .then((res) => res.json())
3121
- .then((data) => {
3122
- if (data._status !== 1 || !data._data) {
3123
- return Promise.reject(data);
3124
- }
3125
- return data === null || data === void 0 ? void 0 : data._data;
3126
- })
3127
- .then((results) => {
3128
- let searchesResult = [];
3129
- if (searchType !== 'specialty') {
3130
- searchesResult = results.searches;
3131
- }
3132
- if (searchType === 'specialty') {
3133
- if (keyword) {
3134
- searchesResult = results.specialties;
3135
- }
3136
- else {
3137
- searchesResult = results.default;
3138
- }
3139
- }
3140
- dispatch({
3141
- type: ActionTypes.FetchSearchResultsComplete,
3142
- payload: {
3143
- key: searchType,
3144
- searches: searchesResult || [],
3145
- },
3146
- });
3147
- if (cacheResult) {
3148
- dispatch({
3149
- type: ActionTypes.UpdateInitialSearchResults,
3150
- payload: {
3151
- key: searchType,
3152
- searches: searchesResult || [],
3153
- },
3154
- });
3155
- }
3156
- })
3157
- .catch((error) => {
3158
- console.log('error loading search results', { url, error });
3159
- })
3160
- .finally(() => dispatch({ type: ActionTypes.FetchSearchResultsFinish }));
3161
- }, [locale, careApiDomain, dispatch]);
3162
- const fetchAllSpecialties = React.useCallback(function fetchSearchSpecialties() {
3163
- const url = `${careApiDomain}${paths.PATHS.GET_SEARCH_SPECIALTY}`;
3164
- return fetch(getApiPath(url, {
3165
- domain: careApiDomain,
3166
- searchType: '',
3167
- msd: constants.CLIENT_KEY.MSD === client ? 1 : '',
3168
- }, locale), {
3169
- method: 'GET',
3170
- headers: {
3171
- accept: 'version=2.0.0.0',
3172
- },
3173
- })
3174
- .then((res) => res.json())
3175
- .then((data) => {
3176
- if (data._status !== 1 || !data._data) {
3177
- return Promise.reject(data);
3178
- }
3179
- return data === null || data === void 0 ? void 0 : data._data;
3180
- })
3181
- .then((results) => {
3182
- dispatch({
3183
- type: ActionTypes.FetchAllSpecialties,
3184
- payload: results.specialties || [],
3185
- });
3186
- })
3187
- .catch((error) => {
3188
- console.log('error loading search results', { url, error });
3189
- });
3190
- }, [locale, careApiDomain, dispatch]);
3191
- const fetchPopularKeys = React.useCallback(function fetchPopularKeys(searchType) {
3192
- const url = `${careApiDomain}${paths.PATHS.GET_SEARCH_POPULAR_KEY}`;
3193
- return fetch(getApiPath(url, {
3194
- domain: careApiDomain,
3195
- searchType: TypePopularKeySearch[searchType],
3196
- sort_by: 'display_order',
3197
- sort_order: 'asc',
3198
- }, locale))
3199
- .then((res) => res.json())
3200
- .then((data) => {
3201
- if (data._status !== 1 || !data._data) {
3202
- return Promise.reject(data);
3203
- }
3204
- return data === null || data === void 0 ? void 0 : data._data;
3205
- })
3206
- .then((results) => {
3207
- dispatch({
3208
- type: ActionTypes.FetchPopularKeys,
3209
- payload: results.popular_searches || [],
3210
- });
3211
- })
3212
- .catch((error) => {
3213
- console.log('error loading search results', { url, error });
3214
- });
3215
- }, [locale, careApiDomain, dispatch]);
3216
- return {
3217
- fetchCitiesByLocation,
3218
- fetchCitiesByKeyword,
3219
- fetchSearchResults,
3220
- fetchAllSpecialties,
3221
- fetchPopularKeys,
3222
- };
3223
- }
3224
-
3225
- const BookingSearchBarV2 = ({ isMobile, careApiDomain, geoLocationPermission: geoLocationPermissionFromProps, geoLocationCoordinates: geoLocationCoordinatesFromProps, initialSelectedCity: initialSelectedCityFromProps, initialSearchValue = '', initTypeSearch = 'hospital', initSpecialty, careFrontDomain = '/care', isDebug = false,
3226
- // askForGeolocationPermission = false,
3227
- gaTrackingSearchBar, gaTrackingLocationSearch, autoCompleteDisabled = false, inputSearchPlaceholder = '', hideTabBookingSearch = [], hideSpecialtySelection = false, hidePopularSearchKeys = false, clientSlug = '',
3228
- // isOptionAllLocation = false,
3229
- // hideResults = [],
3230
- // isNavResultItem = true,
3231
- routerPush, onGeoLocationPermissionChange,
3232
- // onSearch,
3233
- onChangeLocation, }) => {
3234
- const { locale, t } = useTranslations.useTranslations();
3235
- const wrapperRef = React.useRef(null);
3236
- const inputSearchSpecialtyWrapperRef = React.useRef(null);
3237
- const [currentTab, setCurrentTab] = React.useState(initTypeSearch);
3238
- const { geoLocationPermission: geoLocationPermissionFromHook, geoLocationCoordinates: geoLocationCoordinatesFromHook, } = useGeolocation();
3239
- const [state, dispatch] = React.useReducer(reducer, initialState, (s) => (Object.assign(Object.assign({}, s), { isDebug,
3240
- isMobile, geoLocationPermission: geoLocationPermissionFromProps ||
3241
- geoLocationPermissionFromHook ||
3242
- 'unset', geoLocationCoordinates: geoLocationCoordinatesFromProps ||
3243
- geoLocationCoordinatesFromHook ||
3244
- null, searchKeywords: initialSearchValue, initialSelectedCity: initialSelectedCityFromProps || null, selectedLocation: initialSelectedCityFromProps || s.selectedLocation || null, searchLocationKeywords: (initialSelectedCityFromProps === null || initialSelectedCityFromProps === void 0 ? void 0 : initialSelectedCityFromProps.name) || s.searchLocationKeywords, autoCompleteDisabled,
3245
- inputSearchPlaceholder,
3246
- locale })));
3247
- const { navigateTo, focusedSpecialty,
3248
- // isLoadingCities,
3249
- // cities,
3250
- searchKeywords, geoLocationPermission, selectedLocation, selectedSpecialty, initialSelectedCity,
3251
- // defaultCity,
3252
- searchResults, isLoadingSearchResults,
3253
- // isMobileModalOpened,
3254
- // inputSearchPlaceholder,
3255
- // allSpecialties,
3256
- } = state;
3257
- const { fetchCitiesByLocation, fetchCitiesByKeyword, fetchSearchResults, fetchAllSpecialties, fetchPopularKeys, } = useSearchBarApi({
3258
- dispatch,
3259
- locale,
3260
- careApiDomain,
3261
- client: clientSlug,
3262
- });
3263
- const slugs = React.useMemo(() => constants.LOCALIZED_SLUGS[locale], [locale]);
3264
- const typeInformation = React.useMemo(() => {
3265
- return {
3266
- doctor: {
3267
- name: t('booking.searchPopup.doctors'),
3268
- icon: React__default["default"].createElement(DoctorIcon, null),
3269
- slug: slugs.DOCTOR,
3270
- },
3271
- service: {
3272
- name: t('booking.searchPopup.services'),
3273
- icon: React__default["default"].createElement(ServiceIcon, null),
3274
- slug: slugs.SERVICE,
3275
- },
3276
- hospital: {
3277
- name: t('booking.searchPopup.hospitals'),
3278
- icon: React__default["default"].createElement(HospitalIcon, null),
3279
- slug: slugs.HOSPITAL,
3280
- },
3281
- specialty: {
3282
- name: t('booking.searchPopup.specialties'),
3283
- icon: React__default["default"].createElement(SpecialtyIcon, null),
3284
- slug: slugs.SPECIALTIES,
3285
- },
3286
- };
3287
- }, [currentTab]);
3288
- const debouncedFetchCitiesByKeyword = React.useMemo(() => debounce__default["default"](fetchCitiesByKeyword, 400), [fetchCitiesByKeyword]);
3289
- const debouncedFetchSearchResults = React.useMemo(() => debounce__default["default"](fetchSearchResults, 400), [fetchSearchResults]);
3290
- const handleLocationClick = React.useCallback(function handleLocationClick(city) {
3291
- dispatch({ type: ActionTypes.SelectLocation, payload: city });
3292
- focusSearchInput();
3293
- if (onChangeLocation) {
3294
- onChangeLocation(city);
3295
- }
3296
- }, [t, dispatch]);
3297
- function focusSearchInput() {
3298
- var _a;
3299
- if (wrapperRef.current) {
3300
- (_a = wrapperRef.current
3301
- .querySelector('input[name="search-results"]')) === null || _a === void 0 ? void 0 : _a.focus();
3302
- }
3303
- }
3304
- function onClickSearchByKeyword() {
3305
- let url = '';
3306
- const { slug: typeSlug } = typeInformation[currentTab];
3307
- let moreParams = '';
3308
- const slugClientUrl = constants.MAPPING_CLIENT_WITH_SLUG[locale][clientSlug];
3309
- if ((currentTab === 'doctor' || currentTab === 'hospital') &&
3310
- state.selectedSpecialty.id > 0) {
3311
- moreParams = `&specialtyId=${state.selectedSpecialty.id}`;
3312
- }
3313
- if (currentTab === 'specialty') {
3314
- url = `/${typeSlug}`;
3315
- }
3316
- else {
3317
- url = `/${selectedLocation.slug}/${typeSlug}`;
3318
- }
3319
- if (slugClientUrl) {
3320
- url += `/${slugClientUrl}`;
3321
- }
3322
- url += `?q=${searchKeywords}${moreParams}`;
3323
- if (url) {
3324
- dispatch({ type: ActionTypes.NavigateTo, payload: url });
3325
- }
3326
- }
3327
- useOutsideClick.useOutsideClick(inputSearchSpecialtyWrapperRef, () => {
3328
- dispatch({ type: ActionTypes.ClickOutsideInputSearchSpecialty });
3329
- });
3330
- React.useEffect(() => {
3331
- var _a;
3332
- if (geoLocationPermission !== 'denied' && !initialSelectedCity) {
3333
- dispatch({
3334
- type: ActionTypes.SelectLocation,
3335
- payload: {
3336
- name: t('booking.searchBar.allLocations'),
3337
- id: constants.ID_OPTION_ALL_LOCATION,
3338
- slug: (_a = constants.LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
3339
- },
3340
- });
3341
- }
3342
- if (onGeoLocationPermissionChange) {
3343
- onGeoLocationPermissionChange(geoLocationPermission, state.geoLocationCoordinates);
3344
- }
3345
- if (isMobile && geoLocationPermission === 'granted' && selectedLocation) {
3346
- dispatch({ type: ActionTypes.FocusInputSearch });
3347
- }
3348
- fetchCitiesByLocation({ coordinates: state.geoLocationCoordinates });
3349
- }, [geoLocationPermission]);
3350
- React.useEffect(() => {
3351
- const defaultSpecialty = initSpecialty
3352
- ? initSpecialty
3353
- : {
3354
- name: t('booking.searchBar.allSpecialties'),
3355
- id: -1,
3356
- thumbnail: '',
3357
- total_doctor: 0,
3358
- slug: slugs.SPECIALTIES,
3359
- };
3360
- if (!state.selectedSpecialty) {
3361
- dispatch({
3362
- type: ActionTypes.SelectSpecialty,
3363
- payload: defaultSpecialty,
3364
- });
3365
- }
3366
- }, [initSpecialty, state.selectedSpecialty]);
3367
- React.useEffect(() => {
3368
- fetchAllSpecialties();
3369
- }, []);
3370
- React.useEffect(() => {
3371
- fetchPopularKeys(currentTab);
3372
- }, [currentTab]);
3373
- React.useEffect(() => {
3374
- if (navigateTo) {
3375
- if (routerPush) {
3376
- routerPush(navigateTo);
3377
- }
3378
- else {
3379
- window.location.href = `${careFrontDomain}${navigateTo}`;
3380
- }
3381
- }
3382
- }, [navigateTo]);
3383
- React.useEffect(() => {
3384
- fetchSearchResults(state.searchKeywords, state, currentTab, clientSlug, true);
3385
- }, [selectedLocation, selectedSpecialty, currentTab]);
3386
- return (React__default["default"].createElement(StyledSearchBarWrapper, { ref: wrapperRef },
3387
- React__default["default"].createElement(TabSearch, { currentTab: currentTab, setCurrentTab: setCurrentTab, isMobile: isMobile, hideTabBookingSearch: hideTabBookingSearch }),
3388
- React__default["default"].createElement(StyleWrapperContainer, { className: "booking-search-container" },
3389
- React__default["default"].createElement(StyleSearchInputContainer, null,
3390
- React__default["default"].createElement(StyleSearchContent, { className: "booking-search-content" },
3391
- React__default["default"].createElement("div", { ref: inputSearchSpecialtyWrapperRef },
3392
- React__default["default"].createElement(core.Flex, { gap: "12px", justify: "space-between", align: "center", direction: isMobile ? 'column' : 'row', className: "flex-search-input" },
3393
- currentTab !== 'specialty' && (React__default["default"].createElement(SearchLocation, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchCitiesByKeyword: debouncedFetchCitiesByKeyword, selectedLocation: selectedLocation, onLocationClick: handleLocationClick, trackingAttributes: gaTrackingLocationSearch })),
3394
- React__default["default"].createElement(SearchInputs, { type: currentTab, isMobile: isMobile, state: state, dispatch: dispatch, debouncedFetchSearchResults: debouncedFetchSearchResults, initalSearchValue: initialSearchValue, focusSearchInput: focusSearchInput, onEnterSearch: onClickSearchByKeyword, typeInformation: typeInformation, trackingAttributes: gaTrackingSearchBar, isLoading: isLoadingSearchResults, hideSpecialtySelection: hideSpecialtySelection, clientSlug: clientSlug }),
3395
- React__default["default"].createElement(core.Button, { size: isMobile ? 'md' : 'lg', color: "#2D87F3", fullWidth: isMobile, variant: "filled", onClick: onClickSearchByKeyword, styles: {
3396
- root: {
3397
- height: isMobile ? '40px' : '48px',
3398
- },
3399
- } }, t('booking.searchBar.searchButton'))),
3400
- !hidePopularSearchKeys &&
3401
- currentTab !== 'specialty' &&
3402
- state.popularKeys.length > 0 && (React__default["default"].createElement(SearchTag, { type: currentTab, state: state, typeInformation: typeInformation, dispatch: dispatch })),
3403
- currentTab === 'specialty' && focusedSpecialty === 'search' && (React__default["default"].createElement(SearchResultSpecialties, { state: state, isMobile: isMobile, dispatch: dispatch, specialties: (searchResults === null || searchResults === void 0 ? void 0 : searchResults.specialty) || [], isLoading: isLoadingSearchResults }))))))));
3404
- };
3405
-
3406
- const StyledTextDivider = styled__default["default"].div `
3407
- background-color: var(--neutral50);
3408
- padding: 12px 0;
3409
- box-shadow: inset 0px 1px 0px #e4e8ec;
3410
-
3411
- > * {
3412
- display: grid;
3413
- grid-template-columns: 32px 1fr;
3414
- align-content: center;
3415
-
3416
- p {
3417
- font-weight: 600;
3418
- }
3419
- }
3420
-
3421
- .icon-wrapper {
3422
- display: flex;
3423
- align-items: center;
3424
- }
3425
- `;
3426
- const TextDivider = ({ children, icon, className, style }) => (React__default["default"].createElement(StyledTextDivider, { style: style, className: className },
3427
- React__default["default"].createElement(index$3.Container, null,
3428
- React__default["default"].createElement("div", { className: "icon-wrapper" }, icon),
3429
- React__default["default"].createElement(index$2.Text, { size: "c1", color: "var(--neutral800)" }, children))));
3430
-
3431
- var RedirectType;
3432
- (function (RedirectType) {
3433
- RedirectType[RedirectType["SPECIALTY"] = 1] = "SPECIALTY";
3434
- RedirectType[RedirectType["DOCTOR"] = 2] = "DOCTOR";
3435
- RedirectType[RedirectType["CLINIC"] = 3] = "CLINIC";
3436
- RedirectType[RedirectType["SERVICE"] = 4] = "SERVICE";
3437
- })(RedirectType || (RedirectType = {}));
3438
-
3439
- var types = /*#__PURE__*/Object.freeze({
3440
- __proto__: null,
3441
- get RedirectType () { return RedirectType; }
3442
- });
3443
-
3444
- exports.BookingSearchBar = BookingSearchBar;
3445
- exports.BookingSearchBarV2 = BookingSearchBarV2;
3446
- exports.TextDivider = TextDivider;
3447
- exports.types = types;