@hhgtech/hhg-components 1.28.67 → 1.28.69
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.
- package/build/BMI_BOYS.percentile.monthly-48c9471d.js +688 -0
- package/build/BMI_BOYS.percentile.weekly-4965852e.js +182 -0
- package/build/BMI_BOYS.percentile.yearly-0f7cc8f4.js +83 -0
- package/build/BMI_BOYS.zscore.monthly-5bb8a433.js +440 -0
- package/build/BMI_BOYS.zscore.weekly-3d56f80f.js +118 -0
- package/build/BMI_BOYS.zscore.yearly-57081f24.js +55 -0
- package/build/BMI_GIRLS.percentile.monthly-95859cd9.js +688 -0
- package/build/BMI_GIRLS.percentile.weekly-009cf4df.js +182 -0
- package/build/BMI_GIRLS.percentile.yearly-4436947b.js +83 -0
- package/build/BMI_GIRLS.zscore.monthly-689b4eee.js +440 -0
- package/build/BMI_GIRLS.zscore.weekly-dff693df.js +118 -0
- package/build/BMI_GIRLS.zscore.yearly-05ef5f4f.js +55 -0
- package/build/ChevronDown-275f1ab5.js +29 -0
- package/build/HEAD CIRCUM_BOYS.percentile.monthly-55c580a7.js +688 -0
- package/build/HEAD CIRCUM_BOYS.percentile.weekly-e30f4a42.js +182 -0
- package/build/HEAD CIRCUM_BOYS.percentile.yearly-2378a5f0.js +83 -0
- package/build/HEAD CIRCUM_BOYS.zscore.monthly-102d5559.js +440 -0
- package/build/HEAD CIRCUM_BOYS.zscore.weekly-7b0f1ba8.js +118 -0
- package/build/HEAD CIRCUM_BOYS.zscore.yearly-e9237d31.js +55 -0
- package/build/HEAD CIRCUM_GIRLS.percentile.monthly-1ddda8b3.js +688 -0
- package/build/HEAD CIRCUM_GIRLS.percentile.weekly-843147ea.js +182 -0
- package/build/HEAD CIRCUM_GIRLS.percentile.yearly-9b51c237.js +83 -0
- package/build/HEAD CIRCUM_GIRLS.zscore.monthly-3f1b233c.js +440 -0
- package/build/HEAD CIRCUM_GIRLS.zscore.weekly-9e14d3fe.js +118 -0
- package/build/HEAD CIRCUM_GIRLS.zscore.yearly-d924f5ae.js +55 -0
- package/build/HEIGHT_BOYS.percentile.monthly-15538920.js +688 -0
- package/build/HEIGHT_BOYS.percentile.weekly-10bd0277.js +182 -0
- package/build/HEIGHT_BOYS.percentile.yearly-8e678d38.js +237 -0
- package/build/HEIGHT_BOYS.zscore.monthly-2c110da9.js +440 -0
- package/build/HEIGHT_BOYS.zscore.weekly-288b7733.js +118 -0
- package/build/HEIGHT_BOYS.zscore.yearly-42f6f9f7.js +153 -0
- package/build/HEIGHT_GIRLS.percentile.monthly-04abe7d2.js +688 -0
- package/build/HEIGHT_GIRLS.percentile.weekly-9653b16c.js +182 -0
- package/build/HEIGHT_GIRLS.percentile.yearly-9efacd67.js +237 -0
- package/build/HEIGHT_GIRLS.zscore.monthly-c64a97b2.js +440 -0
- package/build/HEIGHT_GIRLS.zscore.weekly-3302dd83.js +118 -0
- package/build/HEIGHT_GIRLS.zscore.yearly-ebe5114f.js +153 -0
- package/build/Subot-5fc40fb5.js +217 -0
- package/build/Visible-5c5d57cf.js +29 -0
- package/build/WEIGHT_BOYS.percentile.monthly-5e11e7a0.js +688 -0
- package/build/WEIGHT_BOYS.percentile.weekly-68ae2578.js +182 -0
- package/build/WEIGHT_BOYS.percentile.yearly-030c06a4.js +138 -0
- package/build/WEIGHT_BOYS.zscore.monthly-d22c7b57.js +440 -0
- package/build/WEIGHT_BOYS.zscore.weekly-d8d901e6.js +118 -0
- package/build/WEIGHT_BOYS.zscore.yearly-c311a084.js +90 -0
- package/build/WEIGHT_GIRLS.percentile.monthly-5c44f8eb.js +688 -0
- package/build/WEIGHT_GIRLS.percentile.weekly-faa98671.js +182 -0
- package/build/WEIGHT_GIRLS.percentile.yearly-560b862e.js +138 -0
- package/build/WEIGHT_GIRLS.zscore.monthly-5365ba1a.js +440 -0
- package/build/WEIGHT_GIRLS.zscore.weekly-0d9dc521.js +118 -0
- package/build/WEIGHT_GIRLS.zscore.yearly-5a3c4e43.js +90 -0
- package/build/adapters.js +36 -1
- package/build/{esm/animation-0340efb3.js → animation-eb4e500b.js} +32 -10
- package/build/babyGrowth.js +913 -47
- package/build/cache.js +13 -1
- package/build/care.js +38 -1
- package/build/components/navigationV2/hooks/useNavConfig.d.ts +1 -3
- package/build/components.js +186 -1
- package/build/constants-8b8bc19f.js +255 -0
- package/build/constants-ae18ce18.js +935 -0
- package/build/constants.js +43 -1
- package/build/cookieHelper-5c9f4bb8.js +43 -0
- package/build/core-2aa8d86c.js +51 -0
- package/build/dataTransform-089f414c.js +66 -0
- package/build/ecom.js +745 -1
- package/build/esm/BMI_BOYS.percentile.monthly-de5dce68.js +686 -0
- package/build/esm/BMI_BOYS.percentile.weekly-9d3990b6.js +180 -0
- package/build/esm/BMI_BOYS.percentile.yearly-98b9114a.js +81 -0
- package/build/esm/BMI_BOYS.zscore.monthly-394646f0.js +438 -0
- package/build/esm/BMI_BOYS.zscore.weekly-c669ea51.js +116 -0
- package/build/esm/BMI_BOYS.zscore.yearly-771ef6b6.js +53 -0
- package/build/esm/BMI_GIRLS.percentile.monthly-1ff3d499.js +686 -0
- package/build/esm/BMI_GIRLS.percentile.weekly-211d2f27.js +180 -0
- package/build/esm/BMI_GIRLS.percentile.yearly-206fdcff.js +81 -0
- package/build/esm/BMI_GIRLS.zscore.monthly-b1137e36.js +438 -0
- package/build/esm/BMI_GIRLS.zscore.weekly-63ed3cd6.js +116 -0
- package/build/esm/BMI_GIRLS.zscore.yearly-221d187c.js +53 -0
- package/build/esm/ChevronDown-9a8ece61.js +7 -0
- package/build/esm/HEAD CIRCUM_BOYS.percentile.monthly-4c37847c.js +686 -0
- package/build/esm/HEAD CIRCUM_BOYS.percentile.weekly-8f6ea38a.js +180 -0
- package/build/esm/HEAD CIRCUM_BOYS.percentile.yearly-6c12a99a.js +81 -0
- package/build/esm/HEAD CIRCUM_BOYS.zscore.monthly-c531b497.js +438 -0
- package/build/esm/HEAD CIRCUM_BOYS.zscore.weekly-6cafba00.js +116 -0
- package/build/esm/HEAD CIRCUM_BOYS.zscore.yearly-fe8114a0.js +53 -0
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.monthly-25ce0d36.js +686 -0
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.weekly-5d3f2862.js +180 -0
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.yearly-2b709ca5.js +81 -0
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.monthly-e8617bae.js +438 -0
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.weekly-f3252d67.js +116 -0
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.yearly-5b62d41f.js +53 -0
- package/build/esm/HEIGHT_BOYS.percentile.monthly-63d2cf96.js +686 -0
- package/build/esm/HEIGHT_BOYS.percentile.weekly-8ea5102d.js +180 -0
- package/build/esm/HEIGHT_BOYS.percentile.yearly-8107b77b.js +235 -0
- package/build/esm/HEIGHT_BOYS.zscore.monthly-641cdfa3.js +438 -0
- package/build/esm/HEIGHT_BOYS.zscore.weekly-86da0362.js +116 -0
- package/build/esm/HEIGHT_BOYS.zscore.yearly-060f6e79.js +151 -0
- package/build/esm/HEIGHT_GIRLS.percentile.monthly-fb987d37.js +686 -0
- package/build/esm/HEIGHT_GIRLS.percentile.weekly-82655dc0.js +180 -0
- package/build/esm/HEIGHT_GIRLS.percentile.yearly-a63b8456.js +235 -0
- package/build/esm/HEIGHT_GIRLS.zscore.monthly-77d676a3.js +438 -0
- package/build/esm/HEIGHT_GIRLS.zscore.weekly-c0387a4e.js +116 -0
- package/build/esm/HEIGHT_GIRLS.zscore.yearly-41203c20.js +151 -0
- package/build/esm/Subot-3289bd8e.js +212 -0
- package/build/esm/Visible-a3d436dd.js +7 -0
- package/build/esm/WEIGHT_BOYS.percentile.monthly-50802d8b.js +686 -0
- package/build/esm/WEIGHT_BOYS.percentile.weekly-4d72ddd6.js +180 -0
- package/build/esm/WEIGHT_BOYS.percentile.yearly-20a29844.js +136 -0
- package/build/esm/WEIGHT_BOYS.zscore.monthly-729e6614.js +438 -0
- package/build/esm/WEIGHT_BOYS.zscore.weekly-90352f48.js +116 -0
- package/build/esm/WEIGHT_BOYS.zscore.yearly-fe1871cc.js +88 -0
- package/build/esm/WEIGHT_GIRLS.percentile.monthly-e6afb2e0.js +686 -0
- package/build/esm/WEIGHT_GIRLS.percentile.weekly-b66d3016.js +180 -0
- package/build/esm/WEIGHT_GIRLS.percentile.yearly-a55622c5.js +136 -0
- package/build/esm/WEIGHT_GIRLS.zscore.monthly-2cdcbe75.js +438 -0
- package/build/esm/WEIGHT_GIRLS.zscore.weekly-d5be31d5.js +116 -0
- package/build/esm/WEIGHT_GIRLS.zscore.yearly-99e8d3a7.js +88 -0
- package/build/esm/adapters.js +26 -1
- package/build/{animation-d5d9ef32.js → esm/animation-3d5edc39.js} +22 -10
- package/build/esm/babyGrowth.js +883 -47
- package/build/esm/cache.js +3 -1
- package/build/esm/care.js +26 -1
- package/build/esm/components/navigationV2/hooks/useNavConfig.d.ts +1 -3
- package/build/esm/components.js +88 -1
- package/build/esm/constants-2a6d2434.js +932 -0
- package/build/esm/constants-b77ffe3d.js +238 -0
- package/build/esm/constants.js +4 -1
- package/build/esm/cookieHelper-d314282c.js +39 -0
- package/build/esm/core-8c73d133.js +47 -0
- package/build/esm/dataTransform-8ecfc046.js +56 -0
- package/build/esm/ecom.js +737 -1
- package/build/esm/footer.js +31 -1
- package/build/esm/gAssets.js +5 -1
- package/build/esm/getDynamicHealthTool-f4497aa5.js +44 -0
- package/build/esm/getSocialList-a5b8462e.js +66 -0
- package/build/esm/hooks.js +21 -1
- package/build/esm/i18n-values/en-PH.js +600 -1
- package/build/esm/i18n-values/hi-IN.js +600 -1
- package/build/esm/i18n-values/id-ID.js +600 -1
- package/build/esm/i18n-values/km-KH.js +600 -1
- package/build/esm/i18n-values/ms-MY.js +602 -1
- package/build/esm/i18n-values/my-MM.js +600 -1
- package/build/esm/i18n-values/th-TH.js +600 -1
- package/build/esm/i18n-values/tl-PH.js +600 -1
- package/build/esm/i18n-values/vi-VN.js +607 -1
- package/build/esm/i18n-values/vi-VN_MB.js +607 -1
- package/build/esm/i18n-values/zh-TW.js +600 -1
- package/build/esm/i18n.js +55 -1
- package/build/esm/i18nV2.js +18 -1
- package/build/esm/index-12fa4985.js +8 -0
- package/build/esm/index-1e59f99a.js +152 -0
- package/build/esm/index-32e53dac.js +1936 -0
- package/build/esm/index-3474401a.js +149 -0
- package/build/esm/index-34899aa3.js +17 -0
- package/build/esm/index-350e8f5b.js +124 -0
- package/build/esm/index-41bf860a.js +151 -0
- package/build/esm/index-4aa8e518.js +116 -0
- package/build/esm/index-4fe2b03f.js +32 -0
- package/build/esm/index-6ea6484e.js +29 -0
- package/build/esm/index-717401ee.js +184 -0
- package/build/esm/index-7af5242a.js +24 -0
- package/build/esm/index-7b8c85cd.js +8302 -0
- package/build/esm/index-81f295b7.js +23 -0
- package/build/esm/index-8858383e.js +52 -0
- package/build/esm/index-8f52dcf3.js +33 -0
- package/build/esm/index-9ea7e838.js +33 -0
- package/build/esm/index-aabac2aa.js +3241 -0
- package/build/esm/index-b9b2c417.js +837 -0
- package/build/esm/index-c2da5293.js +12 -0
- package/build/esm/index-c56d60db.js +370 -0
- package/build/esm/index-c5d7f692.js +24 -0
- package/build/esm/index-cc93e010.js +53 -0
- package/build/esm/index-d7f046db.js +5 -0
- package/build/esm/index-d8177667.js +14 -0
- package/build/esm/index-da139dda.js +615 -0
- package/build/esm/index-e612be9c.js +905 -0
- package/build/esm/index-f3d0592b.js +71 -0
- package/build/esm/index.js +190 -1
- package/build/{index.styled-0a1fb891.js → esm/index.styled-9c9db9cc.js} +17 -5
- package/build/esm/index.styles-5add27c5.js +1303 -0
- package/build/esm/isProduction-0ea904dd.js +27 -0
- package/build/esm/lead.js +2140 -1
- package/build/esm/localizeNumberFormat-2ac3773e.js +23 -0
- package/build/esm/mantine.js +113 -1
- package/build/esm/misc.js +22 -1
- package/build/esm/navigation.js +51 -1
- package/build/esm/normalizeLink-d1c9617e.js +12 -0
- package/build/esm/number-0c126a39.js +38 -0
- package/build/esm/onboardingV2.js +860 -34
- package/build/esm/paths-a8204db4.js +14 -0
- package/build/esm/pwg.js +208 -7
- package/build/esm/routing-2474f896.js +40 -0
- package/build/esm/subot.js +4553 -134
- package/build/esm/theme-e74db08c.js +186 -0
- package/build/esm/together.js +52 -1
- package/build/esm/translationsContext-ad3e25de.js +5 -0
- package/build/esm/tslib.es6-1b1533a9.js +38 -0
- package/build/esm/types-06f00b3d.js +8015 -0
- package/build/esm/types-15e34418.js +3432 -0
- package/build/esm/types-ba190c26.js +21 -0
- package/build/esm/types.js +1 -1
- package/build/esm/unifyEnv.js +42 -1
- package/build/esm/useCategory-2c87152d.js +292 -0
- package/build/esm/useHealthToolCache-29d22ddb.js +17 -0
- package/build/esm/useIsInit-8a2fc8e5.js +11 -0
- package/build/esm/useOutsideClick-c8a7ff20.js +45 -0
- package/build/esm/usePlacesAutocomplete-63e04e8e.js +80 -0
- package/build/esm/useScrollbarSize-51ce1374.js +57 -0
- package/build/esm/useTranslations-4f1db486.js +26 -0
- package/build/esm/useUniqueId-3638402f.js +41 -0
- package/build/esm/utils-2c484c05.js +132 -0
- package/build/esm/utils-3a2a47d9.js +22 -0
- package/build/esm/utils-6d7b88da.js +367 -0
- package/build/esm/utils-70718e9c.js +1124 -0
- package/build/esm/vaccination.js +868 -40
- package/build/footer.js +39 -1
- package/build/gAssets.js +14 -1
- package/build/getDynamicHealthTool-114a1e27.js +48 -0
- package/build/getSocialList-4713441d.js +72 -0
- package/build/hooks.js +44 -1
- package/build/i18n-values/en-PH.js +611 -1
- package/build/i18n-values/hi-IN.js +611 -1
- package/build/i18n-values/id-ID.js +611 -1
- package/build/i18n-values/km-KH.js +611 -1
- package/build/i18n-values/ms-MY.js +613 -1
- package/build/i18n-values/my-MM.js +611 -1
- package/build/i18n-values/th-TH.js +611 -1
- package/build/i18n-values/tl-PH.js +611 -1
- package/build/i18n-values/vi-VN.js +618 -1
- package/build/i18n-values/vi-VN_MB.js +618 -1
- package/build/i18n-values/zh-TW.js +611 -1
- package/build/i18n.js +64 -1
- package/build/i18nV2.js +26 -1
- package/build/index-020e6908.js +39 -0
- package/build/index-0da9b2e8.js +59 -0
- package/build/index-11468c00.js +157 -0
- package/build/index-117448a5.js +133 -0
- package/build/index-12c07f71.js +18 -0
- package/build/index-1a105e87.js +123 -0
- package/build/index-1baaedb0.js +55 -0
- package/build/index-32d38318.js +7 -0
- package/build/index-38582ee0.js +8373 -0
- package/build/index-3e5fc2d6.js +1994 -0
- package/build/index-3eef6bed.js +853 -0
- package/build/index-4035e658.js +159 -0
- package/build/index-488d71ae.js +30 -0
- package/build/index-5553f9e1.js +930 -0
- package/build/index-5fa68e45.js +380 -0
- package/build/index-7b467209.js +39 -0
- package/build/index-81cb1142.js +77 -0
- package/build/index-84ab5b89.js +38 -0
- package/build/index-8a95d709.js +30 -0
- package/build/index-9da9f0c3.js +35 -0
- package/build/index-af91c83e.js +20 -0
- package/build/index-b6aea85e.js +191 -0
- package/build/index-bc4f4c33.js +156 -0
- package/build/index-c604d6bb.js +624 -0
- package/build/index-d330735e.js +30 -0
- package/build/index-d8a7efaf.js +14 -0
- package/build/index-e2e81fa2.js +23 -0
- package/build/index-e3d896b3.js +3261 -0
- package/build/index.js +436 -1
- package/build/{esm/index.styled-14b65c9e.js → index.styled-5628b3e7.js} +25 -5
- package/build/index.styles-b822bf42.js +1342 -0
- package/build/isProduction-5ce3a388.js +29 -0
- package/build/lead.js +2168 -1
- package/build/localizeNumberFormat-f5f50987.js +31 -0
- package/build/mantine.js +154 -1
- package/build/misc.js +70 -1
- package/build/navigation.js +61 -1
- package/build/normalizeLink-6f7b85d8.js +15 -0
- package/build/number-79fe92e1.js +40 -0
- package/build/onboardingV2.js +892 -34
- package/build/paths-a5643d9e.js +16 -0
- package/build/pwg.js +217 -7
- package/build/routing-191a9a00.js +46 -0
- package/build/subot.js +4592 -134
- package/build/theme-fa910869.js +189 -0
- package/build/together.js +112 -1
- package/build/translationsContext-950334bf.js +7 -0
- package/build/tslib.es6-65e312a5.js +41 -0
- package/build/types-0f117a9f.js +8084 -0
- package/build/types-1fedb3d1.js +3446 -0
- package/build/types-52a4e888.js +24 -0
- package/build/types.js +56 -1
- package/build/unifyEnv.js +46 -1
- package/build/useCategory-cfc702f5.js +299 -0
- package/build/useHealthToolCache-43a7014d.js +19 -0
- package/build/useIsInit-89535012.js +13 -0
- package/build/useOutsideClick-c6813964.js +49 -0
- package/build/usePlacesAutocomplete-297de092.js +84 -0
- package/build/useScrollbarSize-0fa31aa7.js +64 -0
- package/build/useTranslations-e1853417.js +32 -0
- package/build/useUniqueId-11369116.js +44 -0
- package/build/utils-52113753.js +384 -0
- package/build/utils-64bd0c42.js +143 -0
- package/build/utils-661411f6.js +1171 -0
- package/build/utils-e1513cbc.js +25 -0
- package/build/vaccination.js +891 -40
- package/package.json +4 -5
- package/build/BMI_BOYS.percentile.monthly-c56b0165.js +0 -1
- package/build/BMI_BOYS.percentile.weekly-64287e04.js +0 -1
- package/build/BMI_BOYS.percentile.yearly-8db65d54.js +0 -1
- package/build/BMI_BOYS.zscore.monthly-f12389cd.js +0 -1
- package/build/BMI_BOYS.zscore.weekly-fff37a57.js +0 -1
- package/build/BMI_BOYS.zscore.yearly-a19b57eb.js +0 -1
- package/build/BMI_GIRLS.percentile.monthly-a4b36d7d.js +0 -1
- package/build/BMI_GIRLS.percentile.weekly-b6089202.js +0 -1
- package/build/BMI_GIRLS.percentile.yearly-0d340818.js +0 -1
- package/build/BMI_GIRLS.zscore.monthly-fd5b57c0.js +0 -1
- package/build/BMI_GIRLS.zscore.weekly-d4577f50.js +0 -1
- package/build/BMI_GIRLS.zscore.yearly-e40b8a7d.js +0 -1
- package/build/ChevronDown-602ce39e.js +0 -1
- package/build/HEAD CIRCUM_BOYS.percentile.monthly-2e4c5776.js +0 -1
- package/build/HEAD CIRCUM_BOYS.percentile.weekly-fc5728a5.js +0 -1
- package/build/HEAD CIRCUM_BOYS.percentile.yearly-6bfab277.js +0 -1
- package/build/HEAD CIRCUM_BOYS.zscore.monthly-6af7ce44.js +0 -1
- package/build/HEAD CIRCUM_BOYS.zscore.weekly-9adb819b.js +0 -1
- package/build/HEAD CIRCUM_BOYS.zscore.yearly-9a6cdbcf.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.percentile.monthly-e7bfe9c6.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.percentile.weekly-9f17e019.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.percentile.yearly-8a59f541.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.zscore.monthly-b7ddb16c.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.zscore.weekly-72701c55.js +0 -1
- package/build/HEAD CIRCUM_GIRLS.zscore.yearly-dd94bded.js +0 -1
- package/build/HEIGHT_BOYS.percentile.monthly-b890068c.js +0 -1
- package/build/HEIGHT_BOYS.percentile.weekly-a1aa5130.js +0 -1
- package/build/HEIGHT_BOYS.percentile.yearly-5727d920.js +0 -1
- package/build/HEIGHT_BOYS.zscore.monthly-13b70aa6.js +0 -1
- package/build/HEIGHT_BOYS.zscore.weekly-3e1d7f23.js +0 -1
- package/build/HEIGHT_BOYS.zscore.yearly-a956102d.js +0 -1
- package/build/HEIGHT_GIRLS.percentile.monthly-da5ec01b.js +0 -1
- package/build/HEIGHT_GIRLS.percentile.weekly-e6205d32.js +0 -1
- package/build/HEIGHT_GIRLS.percentile.yearly-caefa502.js +0 -1
- package/build/HEIGHT_GIRLS.zscore.monthly-102ba473.js +0 -1
- package/build/HEIGHT_GIRLS.zscore.weekly-db4f710b.js +0 -1
- package/build/HEIGHT_GIRLS.zscore.yearly-36465920.js +0 -1
- package/build/Subot-4751194d.js +0 -1
- package/build/Visible-9497c463.js +0 -1
- package/build/WEIGHT_BOYS.percentile.monthly-554d0361.js +0 -1
- package/build/WEIGHT_BOYS.percentile.weekly-8e5334b8.js +0 -1
- package/build/WEIGHT_BOYS.percentile.yearly-536e1ccb.js +0 -1
- package/build/WEIGHT_BOYS.zscore.monthly-01eccee1.js +0 -1
- package/build/WEIGHT_BOYS.zscore.weekly-ee8f2c6b.js +0 -1
- package/build/WEIGHT_BOYS.zscore.yearly-0aea2749.js +0 -1
- package/build/WEIGHT_GIRLS.percentile.monthly-7abf9d06.js +0 -1
- package/build/WEIGHT_GIRLS.percentile.weekly-f9b6e963.js +0 -1
- package/build/WEIGHT_GIRLS.percentile.yearly-254865a5.js +0 -1
- package/build/WEIGHT_GIRLS.zscore.monthly-909f7417.js +0 -1
- package/build/WEIGHT_GIRLS.zscore.weekly-e62cd084.js +0 -1
- package/build/WEIGHT_GIRLS.zscore.yearly-8d6e5405.js +0 -1
- package/build/constants-00e06f68.js +0 -108
- package/build/constants-51251306.js +0 -1
- package/build/cookieHelper-7d519a72.js +0 -1
- package/build/core-ba3af3e2.js +0 -1
- package/build/dataTransform-1805eae3.js +0 -1
- package/build/esm/BMI_BOYS.percentile.monthly-6272f835.js +0 -1
- package/build/esm/BMI_BOYS.percentile.weekly-80d18f47.js +0 -1
- package/build/esm/BMI_BOYS.percentile.yearly-a7e5b5f6.js +0 -1
- package/build/esm/BMI_BOYS.zscore.monthly-d3658f97.js +0 -1
- package/build/esm/BMI_BOYS.zscore.weekly-6e6708dc.js +0 -1
- package/build/esm/BMI_BOYS.zscore.yearly-b8400c9d.js +0 -1
- package/build/esm/BMI_GIRLS.percentile.monthly-98586b46.js +0 -1
- package/build/esm/BMI_GIRLS.percentile.weekly-7c1511b0.js +0 -1
- package/build/esm/BMI_GIRLS.percentile.yearly-ea667f90.js +0 -1
- package/build/esm/BMI_GIRLS.zscore.monthly-3a4fd1a6.js +0 -1
- package/build/esm/BMI_GIRLS.zscore.weekly-cc1de097.js +0 -1
- package/build/esm/BMI_GIRLS.zscore.yearly-6dd1a364.js +0 -1
- package/build/esm/ChevronDown-4e59cac6.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.percentile.monthly-bd0965ae.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.percentile.weekly-db1053f7.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.percentile.yearly-cd38b622.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.zscore.monthly-d7f88a95.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.zscore.weekly-76f7db79.js +0 -1
- package/build/esm/HEAD CIRCUM_BOYS.zscore.yearly-3ce70f8e.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.monthly-b2e678ae.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.weekly-8e2664bb.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.percentile.yearly-f5c075a9.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.monthly-6f87849e.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.weekly-48da0aaa.js +0 -1
- package/build/esm/HEAD CIRCUM_GIRLS.zscore.yearly-4eea437b.js +0 -1
- package/build/esm/HEIGHT_BOYS.percentile.monthly-d1a8cc8e.js +0 -1
- package/build/esm/HEIGHT_BOYS.percentile.weekly-2b6cfe6c.js +0 -1
- package/build/esm/HEIGHT_BOYS.percentile.yearly-9e78afc3.js +0 -1
- package/build/esm/HEIGHT_BOYS.zscore.monthly-5292d78a.js +0 -1
- package/build/esm/HEIGHT_BOYS.zscore.weekly-fbdee645.js +0 -1
- package/build/esm/HEIGHT_BOYS.zscore.yearly-c11a8f1b.js +0 -1
- package/build/esm/HEIGHT_GIRLS.percentile.monthly-8e11e2dc.js +0 -1
- package/build/esm/HEIGHT_GIRLS.percentile.weekly-dc3965cb.js +0 -1
- package/build/esm/HEIGHT_GIRLS.percentile.yearly-490f7b4e.js +0 -1
- package/build/esm/HEIGHT_GIRLS.zscore.monthly-e3531c32.js +0 -1
- package/build/esm/HEIGHT_GIRLS.zscore.weekly-36a16a66.js +0 -1
- package/build/esm/HEIGHT_GIRLS.zscore.yearly-61736bba.js +0 -1
- package/build/esm/Subot-4642c5bf.js +0 -1
- package/build/esm/Visible-ff7d225c.js +0 -1
- package/build/esm/WEIGHT_BOYS.percentile.monthly-0cfe7ecd.js +0 -1
- package/build/esm/WEIGHT_BOYS.percentile.weekly-89802113.js +0 -1
- package/build/esm/WEIGHT_BOYS.percentile.yearly-0eb40972.js +0 -1
- package/build/esm/WEIGHT_BOYS.zscore.monthly-7f8c5a15.js +0 -1
- package/build/esm/WEIGHT_BOYS.zscore.weekly-3dcfa8ce.js +0 -1
- package/build/esm/WEIGHT_BOYS.zscore.yearly-98ce1ea0.js +0 -1
- package/build/esm/WEIGHT_GIRLS.percentile.monthly-df98e335.js +0 -1
- package/build/esm/WEIGHT_GIRLS.percentile.weekly-63fff42a.js +0 -1
- package/build/esm/WEIGHT_GIRLS.percentile.yearly-8db8cdd0.js +0 -1
- package/build/esm/WEIGHT_GIRLS.zscore.monthly-15c83c6d.js +0 -1
- package/build/esm/WEIGHT_GIRLS.zscore.weekly-747a55ec.js +0 -1
- package/build/esm/WEIGHT_GIRLS.zscore.yearly-197dc52d.js +0 -1
- package/build/esm/constants-6ecfa77c.js +0 -1
- package/build/esm/constants-f7c80032.js +0 -108
- package/build/esm/cookieHelper-4f089e3c.js +0 -1
- package/build/esm/core-80112758.js +0 -1
- package/build/esm/dataTransform-0fa341bb.js +0 -1
- package/build/esm/getDynamicHealthTool-a4c9d6dd.js +0 -1
- package/build/esm/getSocialList-4e48deba.js +0 -1
- package/build/esm/index-13dc1f44.js +0 -1
- package/build/esm/index-13e62563.js +0 -137
- package/build/esm/index-1e7ad007.js +0 -1
- package/build/esm/index-24557f2b.js +0 -1
- package/build/esm/index-252cb964.js +0 -1
- package/build/esm/index-2e99f941.js +0 -1
- package/build/esm/index-3452fed2.js +0 -1
- package/build/esm/index-3aff939b.js +0 -1
- package/build/esm/index-459e0362.js +0 -1
- package/build/esm/index-45dcd965.js +0 -1
- package/build/esm/index-486b71cd.js +0 -1
- package/build/esm/index-5408f5a4.js +0 -113
- package/build/esm/index-5e1af23a.js +0 -1
- package/build/esm/index-79ef3a30.js +0 -1
- package/build/esm/index-7c77273a.js +0 -1
- package/build/esm/index-823fd7c0.js +0 -117
- package/build/esm/index-8c77d7e0.js +0 -1
- package/build/esm/index-93e5b4f3.js +0 -1
- package/build/esm/index-9c7b9011.js +0 -2748
- package/build/esm/index-9e5956c2.js +0 -1
- package/build/esm/index-a83aad1c.js +0 -375
- package/build/esm/index-b7cc3ca2.js +0 -1
- package/build/esm/index-bf11f9e9.js +0 -50
- package/build/esm/index-ce3d38fd.js +0 -1
- package/build/esm/index-d27a0e25.js +0 -1
- package/build/esm/index-e21276e3.js +0 -1
- package/build/esm/index-f9514788.js +0 -177
- package/build/esm/index-fd04ccb7.js +0 -1430
- package/build/esm/index.styles-94af560f.js +0 -817
- package/build/esm/isProduction-00695d80.js +0 -1
- package/build/esm/localizeNumberFormat-8355a44f.js +0 -1
- package/build/esm/normalizeLink-1c194268.js +0 -1
- package/build/esm/number-1347eb7b.js +0 -1
- package/build/esm/paths-749b4b53.js +0 -1
- package/build/esm/routing-2b284b30.js +0 -1
- package/build/esm/theme-3db3c9a8.js +0 -1
- package/build/esm/translationsContext-6d2efd65.js +0 -1
- package/build/esm/tslib.es6-266309d1.js +0 -1
- package/build/esm/types-6d397125.js +0 -3004
- package/build/esm/types-850814a7.js +0 -785
- package/build/esm/types-d3da37d2.js +0 -1
- package/build/esm/useCategory-f5f74749.js +0 -1
- package/build/esm/useHealthToolCache-f1488032.js +0 -1
- package/build/esm/useIsInit-9661c5f5.js +0 -1
- package/build/esm/useOutsideClick-0704b383.js +0 -1
- package/build/esm/usePlacesAutocomplete-0733ec49.js +0 -1
- package/build/esm/useScrollbarSize-90b179a5.js +0 -1
- package/build/esm/useTranslations-df1b3bb8.js +0 -1
- package/build/esm/useUniqueId-03fbaecd.js +0 -1
- package/build/esm/utils-3d2e3f0f.js +0 -141
- package/build/esm/utils-5b4e60da.js +0 -1
- package/build/esm/utils-970ce0c0.js +0 -8
- package/build/esm/utils-b87ec473.js +0 -1
- package/build/getDynamicHealthTool-31f44ca1.js +0 -1
- package/build/getSocialList-29c0a6e8.js +0 -1
- package/build/index-1714c81c.js +0 -2748
- package/build/index-238813a4.js +0 -375
- package/build/index-2438163d.js +0 -1430
- package/build/index-29d302f4.js +0 -137
- package/build/index-3184ae4e.js +0 -1
- package/build/index-34b6bd24.js +0 -1
- package/build/index-35192783.js +0 -1
- package/build/index-41d684a8.js +0 -50
- package/build/index-4a8c8ce6.js +0 -1
- package/build/index-58e0d49f.js +0 -1
- package/build/index-64d2f812.js +0 -1
- package/build/index-85c621a2.js +0 -113
- package/build/index-90f4bc02.js +0 -1
- package/build/index-9a845847.js +0 -117
- package/build/index-9ed509d1.js +0 -1
- package/build/index-aa495d24.js +0 -1
- package/build/index-ad5cf64d.js +0 -1
- package/build/index-b21a1d96.js +0 -1
- package/build/index-b320255d.js +0 -1
- package/build/index-b9af15da.js +0 -1
- package/build/index-bd4b31bf.js +0 -1
- package/build/index-bf81cb71.js +0 -1
- package/build/index-c3cbb8f3.js +0 -1
- package/build/index-d25afe2f.js +0 -1
- package/build/index-e7c1ff53.js +0 -177
- package/build/index-ed8656f9.js +0 -1
- package/build/index-f6217f73.js +0 -1
- package/build/index-f7088d57.js +0 -1
- package/build/index.styles-2ecb9c85.js +0 -817
- package/build/isProduction-28d96804.js +0 -1
- package/build/localizeNumberFormat-22b2d7aa.js +0 -1
- package/build/normalizeLink-594ccff1.js +0 -1
- package/build/number-cf06dcc0.js +0 -1
- package/build/paths-ed72ecb8.js +0 -1
- package/build/routing-f2edd0d0.js +0 -1
- package/build/theme-f2b8aad7.js +0 -1
- package/build/translationsContext-4c4c33c4.js +0 -1
- package/build/tslib.es6-ceb091fd.js +0 -1
- package/build/types-49f0543a.js +0 -785
- package/build/types-5b303b71.js +0 -1
- package/build/types-bfd12e24.js +0 -3004
- package/build/useCategory-94d60dab.js +0 -1
- package/build/useHealthToolCache-7307d240.js +0 -1
- package/build/useIsInit-c3cf1925.js +0 -1
- package/build/useOutsideClick-15fef824.js +0 -1
- package/build/usePlacesAutocomplete-6ab0181b.js +0 -1
- package/build/useScrollbarSize-ab332673.js +0 -1
- package/build/useTranslations-233c68bc.js +0 -1
- package/build/useUniqueId-46834e18.js +0 -1
- package/build/utils-13ea4f2f.js +0 -8
- package/build/utils-45e691a3.js +0 -1
- package/build/utils-bee8be92.js +0 -141
- package/build/utils-d5766c73.js +0 -1
|
@@ -0,0 +1,3432 @@
|
|
|
1
|
+
import { a as __awaiter } from './tslib.es6-1b1533a9.js';
|
|
2
|
+
import React__default, { useState, useCallback, useMemo, useEffect, useRef, useReducer } from 'react';
|
|
3
|
+
import { u as useTranslations } from './useTranslations-4f1db486.js';
|
|
4
|
+
import debounce from 'lodash/debounce';
|
|
5
|
+
import { I as ID_OPTION_ALL_LOCATION, a as LOCALIZED_SLUGS, f as ID_OPTION_CURRENT_LOCATION, M as MAPPING_CLIENT_WITH_SLUG, g as SLUG_VACIN_ID, C as CLIENT_KEY } from './constants-b77ffe3d.js';
|
|
6
|
+
import { I as Input } from './index-8f52dcf3.js';
|
|
7
|
+
import styled, { createGlobalStyle } from 'styled-components';
|
|
8
|
+
import { T as Text } from './index-3474401a.js';
|
|
9
|
+
import { t as theme } from './theme-e74db08c.js';
|
|
10
|
+
import shuffle from 'lodash/shuffle';
|
|
11
|
+
import { a as useOutsideClick } from './useOutsideClick-c8a7ff20.js';
|
|
12
|
+
import { M as MediaQueries } from './utils-2c484c05.js';
|
|
13
|
+
import Skeleton from 'react-loading-skeleton';
|
|
14
|
+
import { P as PATHS } from './paths-a8204db4.js';
|
|
15
|
+
import { Skeleton as Skeleton$1, Input as Input$1, Divider, Tabs, Flex, Button } from '@mantine/core';
|
|
16
|
+
import { U as USER_GEOLOCATION_COORDINATES_COOKIE, d as domainLocales } from './index-e612be9c.js';
|
|
17
|
+
import { g as getCookie, s as setCookie, d as deleteCookie } from './cookieHelper-d314282c.js';
|
|
18
|
+
import { C as Container } from './index-c2da5293.js';
|
|
19
|
+
import { Search } from '@hhgtech/icons/core';
|
|
20
|
+
import { C as ChevronDown } from './ChevronDown-9a8ece61.js';
|
|
21
|
+
import formatString from 'string-format';
|
|
22
|
+
|
|
23
|
+
function useGeolocation() {
|
|
24
|
+
const [permission, setPermission] = useState(() => {
|
|
25
|
+
if (typeof window === 'undefined') {
|
|
26
|
+
return 'unset';
|
|
27
|
+
}
|
|
28
|
+
if (getCookie(USER_GEOLOCATION_COORDINATES_COOKIE)) {
|
|
29
|
+
return 'granted';
|
|
30
|
+
}
|
|
31
|
+
const blocked = !location.protocol.includes('https') && location.hostname !== 'localhost';
|
|
32
|
+
if (!navigator.geolocation || blocked) {
|
|
33
|
+
return 'denied';
|
|
34
|
+
}
|
|
35
|
+
return 'unset';
|
|
36
|
+
});
|
|
37
|
+
const [coordinates, setCoordinates] = useState(() => {
|
|
38
|
+
if (typeof window === 'undefined') {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const cookie = getCookie(USER_GEOLOCATION_COORDINATES_COOKIE);
|
|
42
|
+
if (cookie) {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(cookie);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.log(err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
});
|
|
52
|
+
const request = useCallback(function request() {
|
|
53
|
+
// setPermission()
|
|
54
|
+
if (navigator.geolocation) {
|
|
55
|
+
navigator.geolocation.getCurrentPosition((position) => {
|
|
56
|
+
const gps = {
|
|
57
|
+
lat: `${Math.round(position.coords.latitude * 10000000) / 10000000}`,
|
|
58
|
+
lng: `${Math.round(position.coords.longitude * 10000000) / 10000000}`,
|
|
59
|
+
};
|
|
60
|
+
setCookie(USER_GEOLOCATION_COORDINATES_COOKIE, JSON.stringify(gps), {
|
|
61
|
+
minutes: 15,
|
|
62
|
+
});
|
|
63
|
+
setCoordinates(gps);
|
|
64
|
+
setPermission('granted');
|
|
65
|
+
}, () => {
|
|
66
|
+
deleteCookie(USER_GEOLOCATION_COORDINATES_COOKIE);
|
|
67
|
+
setPermission('denied');
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}, []);
|
|
71
|
+
return useMemo(() => ({
|
|
72
|
+
geoLocationPermission: permission,
|
|
73
|
+
geoLocationCoordinates: coordinates,
|
|
74
|
+
requestGeoLocation: request,
|
|
75
|
+
}), [permission, coordinates]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const StyledSearchBarWrapper$1 = styled.div ``;
|
|
79
|
+
const StyledSearchBarMobileWrapper = styled.div `
|
|
80
|
+
--searchbar-z-index: 305;
|
|
81
|
+
&[data-is-modal='true'] {
|
|
82
|
+
position: fixed;
|
|
83
|
+
left: 0;
|
|
84
|
+
right: 0;
|
|
85
|
+
top: 0;
|
|
86
|
+
height: var(--mobile-care-searchbar-height, 100%);
|
|
87
|
+
overflow-y: auto;
|
|
88
|
+
-webkit-overflow-scrolling: touch;
|
|
89
|
+
background-color: white;
|
|
90
|
+
z-index: var(--searchbar-z-index);
|
|
91
|
+
}
|
|
92
|
+
`;
|
|
93
|
+
const StyledSearchBarMobileModalHeader = styled.section ``;
|
|
94
|
+
const StyledHiddenInputMobile = styled.input `
|
|
95
|
+
position: fixed;
|
|
96
|
+
left: -100%;
|
|
97
|
+
top: -100%;
|
|
98
|
+
`;
|
|
99
|
+
const StyledInput = styled(Input) `
|
|
100
|
+
#booking-search-bar & {
|
|
101
|
+
input {
|
|
102
|
+
font-size: 16px;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
const CareSearchGlobalStyles = createGlobalStyle `
|
|
107
|
+
.care-popup-open {
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
position: fixed;
|
|
110
|
+
&::before {
|
|
111
|
+
content: '';
|
|
112
|
+
inset: 0;
|
|
113
|
+
position: absolute;
|
|
114
|
+
background-color: white;
|
|
115
|
+
min-height: 100vh;
|
|
116
|
+
min-width: 100vw;
|
|
117
|
+
z-index: 2;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
const ClearIcon = ({ className, color }) => (React__default.createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
|
|
123
|
+
React__default.createElement("rect", { x: "4", y: "4", width: "16", height: "16", rx: "8", fill: "white" }),
|
|
124
|
+
React__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' })));
|
|
125
|
+
const CloseIcon = ({ className, color }) => (React__default.createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
|
|
126
|
+
React__default.createElement("path", { d: "M18 6L6 18", stroke: color || 'currentColor', strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
127
|
+
React__default.createElement("path", { d: "M6 6L18 18", stroke: color || 'currentColor', strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })));
|
|
128
|
+
const PinIcon = ({ className, color }) => (React__default.createElement("svg", { width: "14", height: "20", viewBox: "0 0 14 20", className: className },
|
|
129
|
+
React__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' })));
|
|
130
|
+
const MagnifierIcon = ({ className, color }) => (React__default.createElement("svg", { className: className, width: "24", height: "24", viewBox: "0 0 24 24", fill: "none" },
|
|
131
|
+
React__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" }),
|
|
132
|
+
React__default.createElement("path", { d: "M20 20L16 16", stroke: color || 'currentColor', strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })));
|
|
133
|
+
const DefaultThumbnailAny = ({ width, height, }) => (React__default.createElement("svg", { width: width || 30, height: height || 30, viewBox: "0 0 30 30", fill: "none" },
|
|
134
|
+
React__default.createElement("circle", { cx: "15", cy: "15", r: "15", fill: "#F7F9FC" })));
|
|
135
|
+
const DefaultThumbnailDoctor = ({ width, height, }) => (React__default.createElement("svg", { width: width || 32, height: height || 32, viewBox: "0 0 32 32", fill: "none" },
|
|
136
|
+
React__default.createElement("g", { clipPath: "url(#clip0_14712_400114)" },
|
|
137
|
+
React__default.createElement("rect", { width: "32", height: "32", rx: "16", fill: "#E4E8EC" }),
|
|
138
|
+
React__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" })),
|
|
139
|
+
React__default.createElement("defs", null,
|
|
140
|
+
React__default.createElement("clipPath", { id: "clip0_14712_400114" },
|
|
141
|
+
React__default.createElement("rect", { width: "32", height: "32", rx: "16", fill: "white" })))));
|
|
142
|
+
const DefaultThumbnailService = ({ width, height, }) => (React__default.createElement("svg", { width: width || 30, height: height || 30, viewBox: "0 0 30 30", fill: "none" },
|
|
143
|
+
React__default.createElement("circle", { cx: "15", cy: "15", r: "15", fill: "#F7F9FC" }),
|
|
144
|
+
React__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" })));
|
|
145
|
+
|
|
146
|
+
const StyledLiSkeleton$1 = styled.li `
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
gap: 12px;
|
|
150
|
+
padding: 8px 16px;
|
|
151
|
+
|
|
152
|
+
> :first-child {
|
|
153
|
+
flex: 1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
> :nth-child(2) {
|
|
157
|
+
flex: 6;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
& + li::before {
|
|
161
|
+
content: '';
|
|
162
|
+
position: absolute;
|
|
163
|
+
left: 18px;
|
|
164
|
+
right: 18px;
|
|
165
|
+
top: 0;
|
|
166
|
+
height: 1px;
|
|
167
|
+
background-color: ${theme.colors.neutral100};
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
const LiSkeleton = ({ count, className }) => {
|
|
171
|
+
return (React__default.createElement(React__default.Fragment, null, [...Array(count)].map((__v, i) => (React__default.createElement(StyledLiSkeleton$1, { className: className, key: i },
|
|
172
|
+
React__default.createElement(Skeleton, { count: 1, height: 32 }),
|
|
173
|
+
React__default.createElement(Skeleton, { count: 1, height: 24 }))))));
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
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")`;
|
|
177
|
+
const StyledLocationResultsWrapper = styled.div `
|
|
178
|
+
display: flex;
|
|
179
|
+
position: absolute;
|
|
180
|
+
top: 48px;
|
|
181
|
+
min-width: 100%;
|
|
182
|
+
box-shadow: 0px 24px 32px rgba(0, 0, 0, 0.04),
|
|
183
|
+
0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
|
|
184
|
+
0px 0px 1px rgba(0, 0, 0, 0.04);
|
|
185
|
+
border-radius: ${theme.borderRadius};
|
|
186
|
+
background-color: white;
|
|
187
|
+
z-index: 30;
|
|
188
|
+
|
|
189
|
+
${MediaQueries.tdDown} {
|
|
190
|
+
position: relative;
|
|
191
|
+
top: 0;
|
|
192
|
+
box-shadow: initial;
|
|
193
|
+
}
|
|
194
|
+
`;
|
|
195
|
+
const StyledLocationResultsList = styled.ul `
|
|
196
|
+
width: 100%;
|
|
197
|
+
max-height: 600px;
|
|
198
|
+
overflow-y: auto;
|
|
199
|
+
`;
|
|
200
|
+
const StyledPinIcon$1 = styled(PinIcon) `
|
|
201
|
+
width: 12px;
|
|
202
|
+
height: 18px;
|
|
203
|
+
`;
|
|
204
|
+
const StyledLocationItem$1 = styled.li `
|
|
205
|
+
position: relative;
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
padding: 12px 18px;
|
|
208
|
+
display: flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
gap: 14px;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
|
|
213
|
+
${({ isSelected }) => isSelected &&
|
|
214
|
+
`
|
|
215
|
+
&::after {
|
|
216
|
+
content: ${checkMarkIconUrl};
|
|
217
|
+
top: 50%;
|
|
218
|
+
right: 18px;
|
|
219
|
+
position: absolute;
|
|
220
|
+
transform: translateY(-50%);
|
|
221
|
+
}
|
|
222
|
+
`}
|
|
223
|
+
|
|
224
|
+
& + li::before {
|
|
225
|
+
content: '';
|
|
226
|
+
position: absolute;
|
|
227
|
+
left: 18px;
|
|
228
|
+
right: 18px;
|
|
229
|
+
top: 0;
|
|
230
|
+
height: 1px;
|
|
231
|
+
background-color: ${theme.colors.neutral100};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
&:not([data-is-denied='true']):hover {
|
|
235
|
+
background-color: ${theme.colors.neutral50};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
&:last-child:hover {
|
|
239
|
+
border-bottom-right-radius: 6px;
|
|
240
|
+
border-bottom-left-radius: 6px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&:first-child:hover {
|
|
244
|
+
border-top-right-radius: 6px;
|
|
245
|
+
border-top-left-radius: 6px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
&[data-is-denied='true'] {
|
|
249
|
+
cursor: not-allowed;
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
const StyledLiSkeleton = styled(LiSkeleton) `
|
|
253
|
+
&:first-child {
|
|
254
|
+
padding-top: 18px;
|
|
255
|
+
}
|
|
256
|
+
`;
|
|
257
|
+
|
|
258
|
+
const LocationResults = ({ cities, isLoading, onLocationClick, selectedLocation, }) => {
|
|
259
|
+
const { t, locale } = useTranslations();
|
|
260
|
+
const renderContent = () => {
|
|
261
|
+
if (isLoading) {
|
|
262
|
+
return React__default.createElement(StyledLiSkeleton, { count: 5 });
|
|
263
|
+
}
|
|
264
|
+
if (!cities || cities.length < 1) {
|
|
265
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
266
|
+
React__default.createElement(StyledLocationItem$1, { "data-is-denied": "true" },
|
|
267
|
+
React__default.createElement(Text, { size: "sm", color: "#ccc" }, t('booking.searchBar.noResults')))));
|
|
268
|
+
}
|
|
269
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
270
|
+
React__default.createElement(StyledLocationItem$1, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
|
|
271
|
+
var _a;
|
|
272
|
+
if (onLocationClick) {
|
|
273
|
+
onLocationClick({
|
|
274
|
+
name: t('booking.searchBar.allLocations'),
|
|
275
|
+
id: ID_OPTION_ALL_LOCATION,
|
|
276
|
+
slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
} },
|
|
280
|
+
React__default.createElement(StyledPinIcon$1, { color: theme.colors.neutral400 }),
|
|
281
|
+
React__default.createElement(Text, { size: "md" }, t('booking.searchBar.allLocations'))),
|
|
282
|
+
cities.map((city) => (React__default.createElement(StyledLocationItem$1, { key: city.id, onClick: (evt) => {
|
|
283
|
+
evt.nativeEvent.stopImmediatePropagation();
|
|
284
|
+
if (onLocationClick) {
|
|
285
|
+
onLocationClick(city);
|
|
286
|
+
}
|
|
287
|
+
}, role: "button", tabIndex: 0, "aria-label": `Select ${city.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === city.id },
|
|
288
|
+
React__default.createElement(StyledPinIcon$1, { color: theme.colors.neutral400 }),
|
|
289
|
+
React__default.createElement(Text, { size: "md" }, city.name))))));
|
|
290
|
+
};
|
|
291
|
+
return (React__default.createElement(StyledLocationResultsWrapper, { "data-testid": "location-search-results" },
|
|
292
|
+
React__default.createElement(StyledLocationResultsList, null, renderContent())));
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const EVENT_NAMES = {
|
|
296
|
+
TYPE_CHARACTER: 'TYPE_CHARACTER',
|
|
297
|
+
REMOVE_CHARACTER: 'REMOVE_CHARACTER',
|
|
298
|
+
REMOVE_ALL: 'REMOVE_ALL',
|
|
299
|
+
REMOVE_LAST_VISIBLE_NODE: 'REMOVE_LAST_VISIBLE_NODE',
|
|
300
|
+
PAUSE_FOR: 'PAUSE_FOR',
|
|
301
|
+
CHANGE_DELETE_SPEED: 'CHANGE_DELETE_SPEED',
|
|
302
|
+
CHANGE_DELAY: 'CHANGE_DELAY',
|
|
303
|
+
PASTE_STRING: 'PASTE_STRING',
|
|
304
|
+
};
|
|
305
|
+
const getRandomInteger = (min, max) => {
|
|
306
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
307
|
+
};
|
|
308
|
+
const VISIBLE_NODE_TYPES = {
|
|
309
|
+
TEXT_NODE: 'TEXT_NODE',
|
|
310
|
+
};
|
|
311
|
+
class Typewriter {
|
|
312
|
+
constructor(options) {
|
|
313
|
+
this.state = {
|
|
314
|
+
lastFrameTime: null,
|
|
315
|
+
pauseUntil: null,
|
|
316
|
+
eventQueue: [],
|
|
317
|
+
eventLoop: null,
|
|
318
|
+
eventLoopPaused: false,
|
|
319
|
+
reverseCalledEvents: [],
|
|
320
|
+
calledEvents: [],
|
|
321
|
+
visibleNodes: [],
|
|
322
|
+
initialOptions: null,
|
|
323
|
+
};
|
|
324
|
+
this.options = {
|
|
325
|
+
strings: null,
|
|
326
|
+
delay: 'natural',
|
|
327
|
+
pauseFor: 1500,
|
|
328
|
+
deleteSpeed: 'natural',
|
|
329
|
+
loop: false,
|
|
330
|
+
autoStart: false,
|
|
331
|
+
stringSplitter: null,
|
|
332
|
+
onCreateTextNode: null,
|
|
333
|
+
onRemoveNode: null,
|
|
334
|
+
};
|
|
335
|
+
this.start = () => {
|
|
336
|
+
this.state.eventLoopPaused = false;
|
|
337
|
+
this.runEventLoop();
|
|
338
|
+
return this;
|
|
339
|
+
};
|
|
340
|
+
this.pause = () => {
|
|
341
|
+
this.state.eventLoopPaused = true;
|
|
342
|
+
return this;
|
|
343
|
+
};
|
|
344
|
+
this.stop = () => {
|
|
345
|
+
if (this.state.eventLoop) {
|
|
346
|
+
window.cancelAnimationFrame(this.state.eventLoop);
|
|
347
|
+
this.state.eventLoop = null;
|
|
348
|
+
}
|
|
349
|
+
return this;
|
|
350
|
+
};
|
|
351
|
+
this.pauseFor = (ms) => {
|
|
352
|
+
this.addEventToQueue(EVENT_NAMES.PAUSE_FOR, { ms });
|
|
353
|
+
return this;
|
|
354
|
+
};
|
|
355
|
+
this.typeOutAllStrings = () => {
|
|
356
|
+
if (typeof this.options.strings === 'string') {
|
|
357
|
+
this.typeString(this.options.strings).pauseFor(this.options.pauseFor);
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
360
|
+
this.options.strings.forEach((string) => {
|
|
361
|
+
this.typeString(string)
|
|
362
|
+
.pauseFor(this.options.pauseFor)
|
|
363
|
+
.deleteAll(this.options.deleteSpeed);
|
|
364
|
+
});
|
|
365
|
+
return this;
|
|
366
|
+
};
|
|
367
|
+
this.typeString = (string, node = null) => {
|
|
368
|
+
if (string) {
|
|
369
|
+
const { stringSplitter } = this.options || {};
|
|
370
|
+
const characters = typeof stringSplitter === 'function'
|
|
371
|
+
? stringSplitter(string)
|
|
372
|
+
: string.split('');
|
|
373
|
+
this.typeCharacters(characters, node);
|
|
374
|
+
}
|
|
375
|
+
return this;
|
|
376
|
+
};
|
|
377
|
+
this.pasteString = (string, node = null) => {
|
|
378
|
+
if (string) {
|
|
379
|
+
this.addEventToQueue(EVENT_NAMES.PASTE_STRING, {
|
|
380
|
+
character: string,
|
|
381
|
+
node,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
return this;
|
|
385
|
+
};
|
|
386
|
+
this.deleteAll = (speed = 'natural') => {
|
|
387
|
+
this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, { speed });
|
|
388
|
+
return this;
|
|
389
|
+
};
|
|
390
|
+
this.changeDeleteSpeed = (speed) => {
|
|
391
|
+
if (!speed) {
|
|
392
|
+
throw new Error('Must provide new delete speed');
|
|
393
|
+
}
|
|
394
|
+
this.addEventToQueue(EVENT_NAMES.CHANGE_DELETE_SPEED, { speed });
|
|
395
|
+
return this;
|
|
396
|
+
};
|
|
397
|
+
this.changeDelay = (delay) => {
|
|
398
|
+
if (!delay) {
|
|
399
|
+
throw new Error('Must provide new delay');
|
|
400
|
+
}
|
|
401
|
+
this.addEventToQueue(EVENT_NAMES.CHANGE_DELAY, { delay });
|
|
402
|
+
return this;
|
|
403
|
+
};
|
|
404
|
+
this.deleteChars = (amount) => {
|
|
405
|
+
if (!amount) {
|
|
406
|
+
throw new Error('Must provide amount of characters to delete');
|
|
407
|
+
}
|
|
408
|
+
for (let i = 0; i < amount; i++) {
|
|
409
|
+
this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
|
|
410
|
+
}
|
|
411
|
+
return this;
|
|
412
|
+
};
|
|
413
|
+
this.typeCharacters = (characters, node = null) => {
|
|
414
|
+
if (!characters || !Array.isArray(characters)) {
|
|
415
|
+
throw new Error('Characters must be an array');
|
|
416
|
+
}
|
|
417
|
+
characters.forEach((character) => {
|
|
418
|
+
this.addEventToQueue(EVENT_NAMES.TYPE_CHARACTER, { character, node });
|
|
419
|
+
});
|
|
420
|
+
return this;
|
|
421
|
+
};
|
|
422
|
+
this.removeCharacters = (characters) => {
|
|
423
|
+
if (!characters || !Array.isArray(characters)) {
|
|
424
|
+
throw new Error('Characters must be an array');
|
|
425
|
+
}
|
|
426
|
+
characters.forEach(() => {
|
|
427
|
+
this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
|
|
428
|
+
});
|
|
429
|
+
return this;
|
|
430
|
+
};
|
|
431
|
+
this.addEventToQueue = (eventName, eventArgs, prepend = false) => {
|
|
432
|
+
return this.addEventToStateProperty(eventName, eventArgs, prepend, 'eventQueue');
|
|
433
|
+
};
|
|
434
|
+
this.addReverseCalledEvent = (eventName, eventArgs, prepend = false) => {
|
|
435
|
+
const { loop } = this.options;
|
|
436
|
+
if (!loop) {
|
|
437
|
+
return this;
|
|
438
|
+
}
|
|
439
|
+
return this.addEventToStateProperty(eventName, eventArgs, prepend, 'reverseCalledEvents');
|
|
440
|
+
};
|
|
441
|
+
this.addEventToStateProperty = (eventName, eventArgs, prepend = false, property) => {
|
|
442
|
+
const eventItem = {
|
|
443
|
+
eventName,
|
|
444
|
+
eventArgs: eventArgs || {},
|
|
445
|
+
};
|
|
446
|
+
if (prepend) {
|
|
447
|
+
this.state[property] = [eventItem, ...this.state[property]];
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
this.state[property] = [...this.state[property], eventItem];
|
|
451
|
+
}
|
|
452
|
+
return this;
|
|
453
|
+
};
|
|
454
|
+
this.runEventLoop = () => {
|
|
455
|
+
if (!this.state.lastFrameTime) {
|
|
456
|
+
this.state.lastFrameTime = Date.now();
|
|
457
|
+
}
|
|
458
|
+
// Setup variables to calculate if this frame should run
|
|
459
|
+
const nowTime = Date.now();
|
|
460
|
+
const delta = nowTime - this.state.lastFrameTime;
|
|
461
|
+
if (!this.state.eventQueue.length) {
|
|
462
|
+
if (!this.options.loop) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
// Reset event queue if we are looping
|
|
466
|
+
this.state.eventQueue = [...this.state.calledEvents];
|
|
467
|
+
this.state.calledEvents = [];
|
|
468
|
+
this.options = Object.assign({}, this.state.initialOptions);
|
|
469
|
+
}
|
|
470
|
+
// Request next frame
|
|
471
|
+
this.state.eventLoop = window.requestAnimationFrame(this.runEventLoop);
|
|
472
|
+
// Check if event loop is paused
|
|
473
|
+
if (this.state.eventLoopPaused) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
// Check if state has pause until time
|
|
477
|
+
if (this.state.pauseUntil) {
|
|
478
|
+
// Check if event loop should be paused
|
|
479
|
+
if (nowTime < this.state.pauseUntil) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
// Reset pause time
|
|
483
|
+
this.state.pauseUntil = null;
|
|
484
|
+
}
|
|
485
|
+
// Make a clone of event queue
|
|
486
|
+
const eventQueue = [...this.state.eventQueue];
|
|
487
|
+
// Get first event from queue
|
|
488
|
+
const currentEvent = eventQueue.shift();
|
|
489
|
+
// Setup delay variable
|
|
490
|
+
let delay = 0;
|
|
491
|
+
// Check if frame should run or be
|
|
492
|
+
// skipped based on fps interval
|
|
493
|
+
if (currentEvent.eventName === EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE ||
|
|
494
|
+
currentEvent.eventName === EVENT_NAMES.REMOVE_CHARACTER) {
|
|
495
|
+
delay =
|
|
496
|
+
this.options.deleteSpeed === 'natural'
|
|
497
|
+
? getRandomInteger(40, 80)
|
|
498
|
+
: this.options.deleteSpeed;
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
delay =
|
|
502
|
+
this.options.delay === 'natural'
|
|
503
|
+
? getRandomInteger(120, 160)
|
|
504
|
+
: this.options.delay;
|
|
505
|
+
}
|
|
506
|
+
if (delta <= delay) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
// Get current event args
|
|
510
|
+
const { eventName, eventArgs } = currentEvent;
|
|
511
|
+
// Run item from event loop
|
|
512
|
+
switch (eventName) {
|
|
513
|
+
case EVENT_NAMES.PASTE_STRING:
|
|
514
|
+
case EVENT_NAMES.TYPE_CHARACTER: {
|
|
515
|
+
const { character } = eventArgs;
|
|
516
|
+
const textNode = document.createTextNode(character);
|
|
517
|
+
let textNodeToUse = textNode;
|
|
518
|
+
if (this.options.onCreateTextNode &&
|
|
519
|
+
typeof this.options.onCreateTextNode === 'function') {
|
|
520
|
+
textNodeToUse = this.options.onCreateTextNode(character, textNode);
|
|
521
|
+
}
|
|
522
|
+
this.state.visibleNodes = [
|
|
523
|
+
...this.state.visibleNodes,
|
|
524
|
+
{
|
|
525
|
+
type: VISIBLE_NODE_TYPES.TEXT_NODE,
|
|
526
|
+
character,
|
|
527
|
+
node: textNodeToUse,
|
|
528
|
+
},
|
|
529
|
+
];
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
case EVENT_NAMES.REMOVE_CHARACTER: {
|
|
533
|
+
eventQueue.unshift({
|
|
534
|
+
eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
|
|
535
|
+
eventArgs: { removingCharacterNode: true },
|
|
536
|
+
});
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
case EVENT_NAMES.PAUSE_FOR: {
|
|
540
|
+
const { ms } = currentEvent.eventArgs;
|
|
541
|
+
this.state.pauseUntil = Date.now() + parseInt(ms);
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
case EVENT_NAMES.REMOVE_ALL: {
|
|
545
|
+
const { visibleNodes } = this.state;
|
|
546
|
+
const { speed } = eventArgs;
|
|
547
|
+
const removeAllEventItems = [];
|
|
548
|
+
if (speed) {
|
|
549
|
+
removeAllEventItems.push({
|
|
550
|
+
eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
|
|
551
|
+
eventArgs: { speed, temp: true },
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
for (let i = 0, length = visibleNodes.length; i < length; i++) {
|
|
555
|
+
removeAllEventItems.push({
|
|
556
|
+
eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
|
|
557
|
+
eventArgs: { removingCharacterNode: false },
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
if (speed) {
|
|
561
|
+
removeAllEventItems.push({
|
|
562
|
+
eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
|
|
563
|
+
eventArgs: { speed: this.options.deleteSpeed, temp: true },
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
eventQueue.unshift(...removeAllEventItems);
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
case EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE: {
|
|
570
|
+
if (this.state.visibleNodes.length) {
|
|
571
|
+
const { node, character } = this.state.visibleNodes.pop();
|
|
572
|
+
if (this.options.onRemoveNode &&
|
|
573
|
+
typeof this.options.onRemoveNode === 'function') {
|
|
574
|
+
this.options.onRemoveNode({
|
|
575
|
+
node,
|
|
576
|
+
character,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
if (node) {
|
|
580
|
+
node.parentNode.removeChild(node);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
case EVENT_NAMES.CHANGE_DELETE_SPEED: {
|
|
586
|
+
this.options.deleteSpeed = currentEvent.eventArgs.speed;
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
case EVENT_NAMES.CHANGE_DELAY: {
|
|
590
|
+
this.options.delay = currentEvent.eventArgs.delay;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
// Add que item to called queue if we are looping
|
|
595
|
+
if (this.options.loop) {
|
|
596
|
+
if (currentEvent.eventName !== EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE &&
|
|
597
|
+
!(currentEvent.eventArgs && currentEvent.eventArgs.temp)) {
|
|
598
|
+
this.state.calledEvents = [...this.state.calledEvents, currentEvent];
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
// Replace state event queue with cloned queue
|
|
602
|
+
this.state.eventQueue = eventQueue;
|
|
603
|
+
// Set last frame time so it can be used to calculate next frame
|
|
604
|
+
this.state.lastFrameTime = nowTime;
|
|
605
|
+
};
|
|
606
|
+
if (options) {
|
|
607
|
+
this.options = Object.assign(Object.assign({}, this.options), options);
|
|
608
|
+
}
|
|
609
|
+
this.state.initialOptions = Object.assign({}, this.options);
|
|
610
|
+
this.init();
|
|
611
|
+
}
|
|
612
|
+
init() {
|
|
613
|
+
this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, null, true);
|
|
614
|
+
if (this.options.autoStart === true && this.options.strings) {
|
|
615
|
+
this.typeOutAllStrings().start();
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function useAnimatedPlaceholder({ inputRef, wrapperRef, disabled, }) {
|
|
621
|
+
const { t, locale } = useTranslations();
|
|
622
|
+
const values = useMemo(() => {
|
|
623
|
+
if (disabled) {
|
|
624
|
+
return [];
|
|
625
|
+
}
|
|
626
|
+
const shuffleKeys = [
|
|
627
|
+
'booking.searchBar.placeholder.hospital',
|
|
628
|
+
'booking.searchBar.placeholder.doctor',
|
|
629
|
+
];
|
|
630
|
+
if (locale !== 'zh-TW') {
|
|
631
|
+
shuffleKeys.push('booking.searchBar.placeholder.specialty', 'booking.searchBar.placeholder.service');
|
|
632
|
+
}
|
|
633
|
+
return shuffle(shuffleKeys).map((s) => t(s));
|
|
634
|
+
}, [t, locale]);
|
|
635
|
+
useEffect(() => {
|
|
636
|
+
if (disabled) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const input = getInput();
|
|
640
|
+
if (input) {
|
|
641
|
+
input.placeholder = '';
|
|
642
|
+
new Typewriter({
|
|
643
|
+
strings: values,
|
|
644
|
+
autoStart: true,
|
|
645
|
+
loop: true,
|
|
646
|
+
delay: 32,
|
|
647
|
+
deleteSpeed: 32,
|
|
648
|
+
pauseFor: 1500,
|
|
649
|
+
onCreateTextNode: customNodeCreator,
|
|
650
|
+
onRemoveNode: onRemoveNode,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
}, [inputRef, wrapperRef]);
|
|
654
|
+
function customNodeCreator(character) {
|
|
655
|
+
const input = getInput();
|
|
656
|
+
if (input) {
|
|
657
|
+
input.placeholder = input.placeholder + character;
|
|
658
|
+
}
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
function onRemoveNode() {
|
|
662
|
+
const input = getInput();
|
|
663
|
+
if (input) {
|
|
664
|
+
input.placeholder = input.placeholder.slice(0, -1);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
function getInput() {
|
|
668
|
+
if (inputRef && inputRef.current) {
|
|
669
|
+
return inputRef.current;
|
|
670
|
+
}
|
|
671
|
+
else if (wrapperRef && wrapperRef.current) {
|
|
672
|
+
return wrapperRef.current.querySelector('input') || null;
|
|
673
|
+
}
|
|
674
|
+
return null;
|
|
675
|
+
}
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const StyledFakeInputSearchMobile = styled.div `
|
|
680
|
+
user-select: none;
|
|
681
|
+
input {
|
|
682
|
+
pointer-events: none;
|
|
683
|
+
background-color: white;
|
|
684
|
+
}
|
|
685
|
+
`;
|
|
686
|
+
function MobileFakeInput({ focused, value = '', onClick, trackingAttributes, inputSearchPlaceholder, }) {
|
|
687
|
+
const { t } = useTranslations();
|
|
688
|
+
const wrapperRef = useRef(null);
|
|
689
|
+
useAnimatedPlaceholder({ wrapperRef, disabled: !!inputSearchPlaceholder });
|
|
690
|
+
const gaAttributes = useMemo(() => {
|
|
691
|
+
if (trackingAttributes) {
|
|
692
|
+
return {
|
|
693
|
+
'data-event-category': trackingAttributes.dataEventCategory,
|
|
694
|
+
'data-event-action': trackingAttributes.dataEventAction,
|
|
695
|
+
'data-event-label': trackingAttributes.dataEventLabel,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
return {};
|
|
700
|
+
}
|
|
701
|
+
}, [trackingAttributes]);
|
|
702
|
+
return (React__default.createElement(StyledFakeInputSearchMobile, Object.assign({ onClick: () => onClick && onClick(), ref: wrapperRef }, gaAttributes),
|
|
703
|
+
React__default.createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, name: "booking-search-placeholder", displayIcon: React__default.createElement(MagnifierIcon, { color: theme.colors.gray400 }), placeholder: t('booking.searchBar.searchInput.placeholder'), value: value, size: "md" })));
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const StyledTopBar = styled.header `
|
|
707
|
+
display: flex;
|
|
708
|
+
height: 64px;
|
|
709
|
+
align-items: center;
|
|
710
|
+
justify-content: space-between;
|
|
711
|
+
margin: 0 auto;
|
|
712
|
+
position: sticky;
|
|
713
|
+
z-index: 99;
|
|
714
|
+
background-color: white;
|
|
715
|
+
top: 0;
|
|
716
|
+
left: 0;
|
|
717
|
+
`;
|
|
718
|
+
const StyledTopBarHeaderRight = styled.div `
|
|
719
|
+
display: inline-flex;
|
|
720
|
+
flex: 1;
|
|
721
|
+
justify-content: flex-end;
|
|
722
|
+
cursor: pointer;
|
|
723
|
+
text-decoration: underline;
|
|
724
|
+
`;
|
|
725
|
+
const StyledTopBarIcon = styled.div `
|
|
726
|
+
display: flex;
|
|
727
|
+
align-items: center;
|
|
728
|
+
margin-left: 16px;
|
|
729
|
+
cursor: pointer;
|
|
730
|
+
`;
|
|
731
|
+
const StyledTopbarHeading = styled.div `
|
|
732
|
+
width: 100%;
|
|
733
|
+
margin-left: 24px;
|
|
734
|
+
`;
|
|
735
|
+
const StyledTopbarHeadingText = styled(Text) `
|
|
736
|
+
color: ${theme.colors.secondaryDark};
|
|
737
|
+
text-align: start;
|
|
738
|
+
`;
|
|
739
|
+
|
|
740
|
+
const MobileTopBar = ({ className, onLeftClick, headingText, onRightClick, iconLeft, textRight, }) => {
|
|
741
|
+
return (React__default.createElement(StyledTopBar, { className: className },
|
|
742
|
+
React__default.createElement(StyledTopBarIcon, { onClick: onLeftClick }, iconLeft || React__default.createElement(CloseIcon, { color: theme.colors.gray800 })),
|
|
743
|
+
React__default.createElement(StyledTopbarHeading, null,
|
|
744
|
+
React__default.createElement(StyledTopbarHeadingText, { size: "md", weight: "bold" }, headingText)),
|
|
745
|
+
React__default.createElement(StyledTopBarHeaderRight, { onClick: onRightClick }, textRight && React__default.createElement("p", null, textRight))));
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
const SEARCH_KEYWORD_MIN_LENGTH$1 = {
|
|
749
|
+
'en-PH': 3,
|
|
750
|
+
'tl-PH': 2,
|
|
751
|
+
'id-ID': 3,
|
|
752
|
+
'vi-VN': 2,
|
|
753
|
+
'zh-TW': 0,
|
|
754
|
+
'ms-MY': 2,
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
const initialState$1 = {
|
|
758
|
+
isMobile: false,
|
|
759
|
+
isDebug: false,
|
|
760
|
+
navigateTo: null,
|
|
761
|
+
geoLocationPermission: 'unset',
|
|
762
|
+
geoLocationCoordinates: null,
|
|
763
|
+
focused: 'none',
|
|
764
|
+
searchLocationKeywords: '',
|
|
765
|
+
searchKeywords: '',
|
|
766
|
+
selectedLocation: null,
|
|
767
|
+
defaultCity: null,
|
|
768
|
+
initialCities: [],
|
|
769
|
+
cities: [],
|
|
770
|
+
searchResults: [],
|
|
771
|
+
initialSearchResults: [],
|
|
772
|
+
isLoadingCities: false,
|
|
773
|
+
isLoadingSearchResults: false,
|
|
774
|
+
isMobileModalOpened: false,
|
|
775
|
+
initialSelectedCity: null,
|
|
776
|
+
autoCompleteDisabled: false,
|
|
777
|
+
inputSearchPlaceholder: '',
|
|
778
|
+
locale: 'vi-VN',
|
|
779
|
+
};
|
|
780
|
+
var ActionTypes$1;
|
|
781
|
+
(function (ActionTypes) {
|
|
782
|
+
ActionTypes["NavigateTo"] = "navigate to url";
|
|
783
|
+
ActionTypes["ClickOutsideInputLocation"] = "click outside input location";
|
|
784
|
+
ActionTypes["ClickOutsideInputSearch"] = "click outside input search";
|
|
785
|
+
ActionTypes["SelectCurrentLocation"] = "select current location";
|
|
786
|
+
ActionTypes["FocusInputLocation"] = "focus input location";
|
|
787
|
+
ActionTypes["FocusInputSearch"] = "focus input search";
|
|
788
|
+
ActionTypes["ChangeInputLocation"] = "change input location";
|
|
789
|
+
ActionTypes["ChangeInputSearch"] = "change input search";
|
|
790
|
+
ActionTypes["ClearInputLocation"] = "clear input location";
|
|
791
|
+
ActionTypes["ClearInputSearch"] = "clear input search";
|
|
792
|
+
ActionTypes["SelectLocation"] = "select location";
|
|
793
|
+
ActionTypes["FetchCitiesStart"] = "fetch cities start";
|
|
794
|
+
ActionTypes["FetchCitiesFinish"] = "fetch cities finish";
|
|
795
|
+
ActionTypes["FetchSearchResultsStart"] = "fetch search results start";
|
|
796
|
+
ActionTypes["FetchSearchResultsComplete"] = "fetch search results complete";
|
|
797
|
+
ActionTypes["FetchSearchResultsFinish"] = "fetch search results finish";
|
|
798
|
+
ActionTypes["FetchCitiesByGeoIpComplete"] = "fetch cities by geo IP finish";
|
|
799
|
+
ActionTypes["FetchCitiesByKeywordComplete"] = "fetch cities by keyword finish";
|
|
800
|
+
ActionTypes["DisplayInitialCities"] = "display initial cities";
|
|
801
|
+
ActionTypes["DisplayInitialSearchResults"] = "display initial search results";
|
|
802
|
+
ActionTypes["GrantGeoLocationPermission"] = "grant geolocation permission";
|
|
803
|
+
ActionTypes["DenyGeoLocationPermission"] = "deny geolocation permission";
|
|
804
|
+
ActionTypes["OpenMobileModal"] = "open mobile modal";
|
|
805
|
+
ActionTypes["CloseMobileModal"] = "close mobile modal";
|
|
806
|
+
ActionTypes["UpdateInitialSearchValue"] = "update initial search value";
|
|
807
|
+
ActionTypes["SelectSearchResult"] = "select search result";
|
|
808
|
+
ActionTypes["SetInputSearchPlaceholder"] = "set input search placeholder";
|
|
809
|
+
})(ActionTypes$1 || (ActionTypes$1 = {}));
|
|
810
|
+
function resetSearchLocationKeywords$1(state) {
|
|
811
|
+
const { selectedLocation, searchLocationKeywords } = state;
|
|
812
|
+
if (selectedLocation && searchLocationKeywords !== selectedLocation.name) {
|
|
813
|
+
return Object.assign(Object.assign({}, state), { searchLocationKeywords: selectedLocation.name });
|
|
814
|
+
}
|
|
815
|
+
return state;
|
|
816
|
+
}
|
|
817
|
+
function reducer$1(state, action) {
|
|
818
|
+
var _a;
|
|
819
|
+
if (state.isDebug) {
|
|
820
|
+
console.log('bookingSearchBar', { action, state });
|
|
821
|
+
}
|
|
822
|
+
switch (action.type) {
|
|
823
|
+
case ActionTypes$1.NavigateTo:
|
|
824
|
+
return Object.assign(Object.assign({}, state), { navigateTo: action.payload, focused: 'none', isMobileModalOpened: false });
|
|
825
|
+
case ActionTypes$1.ClickOutsideInputLocation: {
|
|
826
|
+
if (state.isMobile || state.focused !== 'location') {
|
|
827
|
+
return state;
|
|
828
|
+
}
|
|
829
|
+
return resetSearchLocationKeywords$1(Object.assign(Object.assign({}, state), { focused: 'none' }));
|
|
830
|
+
}
|
|
831
|
+
case ActionTypes$1.ClickOutsideInputSearch: {
|
|
832
|
+
if (state.isMobile || state.focused !== 'search') {
|
|
833
|
+
return state;
|
|
834
|
+
}
|
|
835
|
+
return Object.assign(Object.assign({}, state), { focused: 'none' });
|
|
836
|
+
}
|
|
837
|
+
case ActionTypes$1.FocusInputLocation: {
|
|
838
|
+
const nextState = Object.assign(Object.assign({}, state), { focused: 'location' });
|
|
839
|
+
if (((_a = state.selectedLocation) === null || _a === void 0 ? void 0 : _a.id) === ID_OPTION_CURRENT_LOCATION) {
|
|
840
|
+
nextState.searchLocationKeywords = '';
|
|
841
|
+
}
|
|
842
|
+
return nextState;
|
|
843
|
+
}
|
|
844
|
+
case ActionTypes$1.FocusInputSearch:
|
|
845
|
+
const nextState = Object.assign(Object.assign({}, state), { focused: 'search' });
|
|
846
|
+
if (state.isMobile) {
|
|
847
|
+
return resetSearchLocationKeywords$1(nextState);
|
|
848
|
+
}
|
|
849
|
+
return nextState;
|
|
850
|
+
case ActionTypes$1.ChangeInputLocation:
|
|
851
|
+
return Object.assign(Object.assign({}, state), { searchLocationKeywords: action.payload });
|
|
852
|
+
case ActionTypes$1.ChangeInputSearch: {
|
|
853
|
+
const keyword = action.payload;
|
|
854
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: keyword, isLoadingSearchResults: keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale] });
|
|
855
|
+
}
|
|
856
|
+
case ActionTypes$1.SelectCurrentLocation:
|
|
857
|
+
return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
|
|
858
|
+
case ActionTypes$1.ClearInputLocation:
|
|
859
|
+
return Object.assign(Object.assign({}, state), { focused: 'location', cities: state.initialCities, searchLocationKeywords: '' });
|
|
860
|
+
case ActionTypes$1.ClearInputSearch:
|
|
861
|
+
return Object.assign(Object.assign({}, state), { focused: 'search', searchKeywords: '' });
|
|
862
|
+
case ActionTypes$1.SelectLocation:
|
|
863
|
+
return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
|
|
864
|
+
case ActionTypes$1.SelectSearchResult:
|
|
865
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: action.payload.name, isMobileModalOpened: false, focused: 'none', navigateTo: action.payload.url });
|
|
866
|
+
case ActionTypes$1.FetchCitiesStart:
|
|
867
|
+
return Object.assign(Object.assign({}, state), { isLoadingCities: true });
|
|
868
|
+
case ActionTypes$1.FetchCitiesFinish:
|
|
869
|
+
return Object.assign(Object.assign({}, state), { isLoadingCities: false });
|
|
870
|
+
case ActionTypes$1.FetchSearchResultsStart:
|
|
871
|
+
return Object.assign(Object.assign({}, state), { isLoadingSearchResults: true });
|
|
872
|
+
case ActionTypes$1.FetchSearchResultsFinish:
|
|
873
|
+
return Object.assign(Object.assign({}, state), { isLoadingSearchResults: false });
|
|
874
|
+
case ActionTypes$1.FetchSearchResultsComplete: {
|
|
875
|
+
const nextState = Object.assign(Object.assign({}, state), { searchResults: action.payload });
|
|
876
|
+
if (state.initialSearchResults.length === 0) {
|
|
877
|
+
nextState.initialSearchResults = action.payload;
|
|
878
|
+
}
|
|
879
|
+
return nextState;
|
|
880
|
+
}
|
|
881
|
+
case ActionTypes$1.FetchCitiesByGeoIpComplete: {
|
|
882
|
+
let { cities } = action.payload;
|
|
883
|
+
const { default: defaultCity } = action.payload;
|
|
884
|
+
cities = cities.filter((c) => c.id !== defaultCity.id);
|
|
885
|
+
cities.unshift(defaultCity);
|
|
886
|
+
if (state.initialSelectedCity &&
|
|
887
|
+
!cities.find((c) => c.id === state.initialSelectedCity.id)) {
|
|
888
|
+
cities.unshift(state.initialSelectedCity);
|
|
889
|
+
}
|
|
890
|
+
const nextState = Object.assign(Object.assign({}, state), { defaultCity, initialCities: cities, cities });
|
|
891
|
+
if (state.geoLocationPermission === 'denied' &&
|
|
892
|
+
!state.initialSelectedCity) {
|
|
893
|
+
nextState.selectedLocation = defaultCity;
|
|
894
|
+
nextState.searchLocationKeywords = defaultCity.name;
|
|
895
|
+
}
|
|
896
|
+
return nextState;
|
|
897
|
+
}
|
|
898
|
+
case ActionTypes$1.FetchCitiesByKeywordComplete:
|
|
899
|
+
return Object.assign(Object.assign({}, state), { cities: action.payload });
|
|
900
|
+
case ActionTypes$1.DisplayInitialCities:
|
|
901
|
+
return Object.assign(Object.assign({}, state), { cities: state.initialCities });
|
|
902
|
+
case ActionTypes$1.DisplayInitialSearchResults:
|
|
903
|
+
return Object.assign(Object.assign({}, state), { searchResults: state.initialSearchResults, isLoadingSearchResults: false });
|
|
904
|
+
case ActionTypes$1.GrantGeoLocationPermission:
|
|
905
|
+
return Object.assign(Object.assign({}, state), { geoLocationPermission: 'granted', geoLocationCoordinates: action.payload });
|
|
906
|
+
case ActionTypes$1.DenyGeoLocationPermission:
|
|
907
|
+
return Object.assign(Object.assign({}, state), { geoLocationPermission: 'denied', geoLocationCoordinates: null });
|
|
908
|
+
case ActionTypes$1.OpenMobileModal:
|
|
909
|
+
return Object.assign(Object.assign({}, state), { isMobileModalOpened: true });
|
|
910
|
+
case ActionTypes$1.CloseMobileModal:
|
|
911
|
+
return Object.assign(Object.assign({}, state), { isMobileModalOpened: false });
|
|
912
|
+
case ActionTypes$1.UpdateInitialSearchValue:
|
|
913
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: action.payload });
|
|
914
|
+
case ActionTypes$1.SetInputSearchPlaceholder:
|
|
915
|
+
return Object.assign(Object.assign({}, state), { inputSearchPlaceholder: action.payload });
|
|
916
|
+
default:
|
|
917
|
+
return state;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
const StyledSearchBarInputsWrapper = styled.div `
|
|
922
|
+
display: flex;
|
|
923
|
+
gap: 16px;
|
|
924
|
+
${MediaQueries.mbDown} {
|
|
925
|
+
flex-direction: column;
|
|
926
|
+
padding: 14px;
|
|
927
|
+
background-color: ${theme.colors.primary50};
|
|
928
|
+
|
|
929
|
+
input {
|
|
930
|
+
filter: drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.04))
|
|
931
|
+
drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.06))
|
|
932
|
+
drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.04));
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
input {
|
|
937
|
+
background-color: white;
|
|
938
|
+
}
|
|
939
|
+
`;
|
|
940
|
+
const StyledInputWrapper = styled.div `
|
|
941
|
+
position: relative;
|
|
942
|
+
`;
|
|
943
|
+
const StyledInputLocationWrapper = styled(StyledInputWrapper) `
|
|
944
|
+
flex: 1;
|
|
945
|
+
`;
|
|
946
|
+
const StyledInputSearchWrapper = styled(StyledInputWrapper) `
|
|
947
|
+
flex: 2;
|
|
948
|
+
`;
|
|
949
|
+
const StyledClearIcon = styled(ClearIcon) `
|
|
950
|
+
display: none;
|
|
951
|
+
&.shown {
|
|
952
|
+
display: block;
|
|
953
|
+
}
|
|
954
|
+
`;
|
|
955
|
+
|
|
956
|
+
const SearchIcon = () => (React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
|
|
957
|
+
React__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" })));
|
|
958
|
+
const StyledSearchIcon = styled.button `
|
|
959
|
+
min-height: 100%;
|
|
960
|
+
border-radius: 6px;
|
|
961
|
+
background-color: ${theme.colors.primaryBase};
|
|
962
|
+
display: flex;
|
|
963
|
+
justify-content: center;
|
|
964
|
+
align-items: center;
|
|
965
|
+
gap: 11px;
|
|
966
|
+
cursor: pointer;
|
|
967
|
+
flex: 0.3;
|
|
968
|
+
|
|
969
|
+
${MediaQueries.mbDown} {
|
|
970
|
+
--margin: 16px;
|
|
971
|
+
min-height: 44px;
|
|
972
|
+
margin: var(--margin);
|
|
973
|
+
width: calc(100% - var(--margin) * 2);
|
|
974
|
+
position: absolute;
|
|
975
|
+
bottom: 0;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
&:hover {
|
|
979
|
+
background-color: ${theme.colors.primaryHover};
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
&:active {
|
|
983
|
+
background-color: ${theme.colors.primaryActive};
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
&:focus-visible {
|
|
987
|
+
outline: 1px solid black;
|
|
988
|
+
}
|
|
989
|
+
`;
|
|
990
|
+
const StyledText$1 = styled(Text) `
|
|
991
|
+
font-weight: ${theme.sizes.fwSemiBold};
|
|
992
|
+
`;
|
|
993
|
+
const SearchButton = ({ onClick }) => {
|
|
994
|
+
const { t } = useTranslations();
|
|
995
|
+
const title = t('booking.searchBar.searchButton');
|
|
996
|
+
return (React__default.createElement(StyledSearchIcon, { onClick: onClick, title: title },
|
|
997
|
+
React__default.createElement(SearchIcon, null),
|
|
998
|
+
React__default.createElement(StyledText$1, { size: "s3", color: "white" }, title)));
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
function SearchInputs$1({ isMobile, state, dispatch, debouncedFetchCitiesByKeyword, debouncedFetchSearchResults, focusLocationInput, focusSearchInput, renderLocationResults, renderSearchResults, locationTrackingAttributes, trackingAttributes, onSearch, initalSearchValue, }) {
|
|
1002
|
+
const inputLocationWrapperRef = useRef(null);
|
|
1003
|
+
const inputSearchWrapperRef = useRef(null);
|
|
1004
|
+
const { focused, searchLocationKeywords, geoLocationPermission, selectedLocation, searchKeywords, inputSearchPlaceholder, } = state;
|
|
1005
|
+
const { t } = useTranslations();
|
|
1006
|
+
useAnimatedPlaceholder({
|
|
1007
|
+
wrapperRef: inputSearchWrapperRef,
|
|
1008
|
+
disabled: !!inputSearchPlaceholder,
|
|
1009
|
+
});
|
|
1010
|
+
useOutsideClick(inputLocationWrapperRef, () => {
|
|
1011
|
+
if (!isMobile) {
|
|
1012
|
+
dispatch({ type: ActionTypes$1.ClickOutsideInputLocation });
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
1015
|
+
useOutsideClick(inputSearchWrapperRef, () => {
|
|
1016
|
+
if (!isMobile) {
|
|
1017
|
+
dispatch({ type: ActionTypes$1.ClickOutsideInputSearch });
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
function handleLocationInputClear() {
|
|
1021
|
+
dispatch({ type: ActionTypes$1.ClearInputLocation });
|
|
1022
|
+
debouncedFetchCitiesByKeyword.cancel();
|
|
1023
|
+
focusLocationInput();
|
|
1024
|
+
}
|
|
1025
|
+
function handleSearchInputClear() {
|
|
1026
|
+
dispatch({ type: ActionTypes$1.ClearInputSearch });
|
|
1027
|
+
debouncedFetchSearchResults.cancel();
|
|
1028
|
+
debouncedFetchSearchResults('', state);
|
|
1029
|
+
focusSearchInput();
|
|
1030
|
+
}
|
|
1031
|
+
const searchInputPinIconColor = useMemo(() => {
|
|
1032
|
+
if (geoLocationPermission === 'granted' &&
|
|
1033
|
+
(selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === ID_OPTION_CURRENT_LOCATION) {
|
|
1034
|
+
return theme.colors.primaryBase;
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
return theme.colors.gray400;
|
|
1038
|
+
}
|
|
1039
|
+
}, [geoLocationPermission, selectedLocation]);
|
|
1040
|
+
const handleSearchInputChange = useCallback(function handleSearchInputChange(value) {
|
|
1041
|
+
dispatch({ type: ActionTypes$1.ChangeInputSearch, payload: value });
|
|
1042
|
+
if (typeof onSearch === 'function') {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale] ||
|
|
1046
|
+
initalSearchValue) {
|
|
1047
|
+
debouncedFetchSearchResults(value.trim(), state);
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
debouncedFetchSearchResults.cancel();
|
|
1051
|
+
dispatch({ type: ActionTypes$1.DisplayInitialSearchResults });
|
|
1052
|
+
}
|
|
1053
|
+
}, [dispatch, state]);
|
|
1054
|
+
const handleSearchLocationInputChange = useCallback(function handleSearchLocationInputChange(value) {
|
|
1055
|
+
dispatch({ type: ActionTypes$1.ChangeInputLocation, payload: value });
|
|
1056
|
+
if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[state.locale]) {
|
|
1057
|
+
debouncedFetchCitiesByKeyword(value.trim());
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
debouncedFetchCitiesByKeyword.cancel();
|
|
1061
|
+
dispatch({ type: ActionTypes$1.DisplayInitialCities });
|
|
1062
|
+
}
|
|
1063
|
+
}, [debouncedFetchCitiesByKeyword, dispatch]);
|
|
1064
|
+
const handleKeyPress = (e) => {
|
|
1065
|
+
if (state.autoCompleteDisabled && e.key === 'Enter' && onSearch) {
|
|
1066
|
+
onSearch({
|
|
1067
|
+
cityId: state.selectedLocation.id,
|
|
1068
|
+
keyword: searchKeywords,
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
return (React__default.createElement(StyledSearchBarInputsWrapper, null,
|
|
1073
|
+
React__default.createElement(StyledInputLocationWrapper, { ref: inputLocationWrapperRef },
|
|
1074
|
+
React__default.createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, placeholder: t('booking.searchBar.locationPlaceholder'), autoComplete: "off", name: "search-location", displayIcon: React__default.createElement(PinIcon, { className: "location-pin-icon", color: searchInputPinIconColor }), actionIcon: React__default.createElement(StyledClearIcon, { color: theme.colors.gray300, className: searchLocationKeywords !== '' ? 'shown' : '' }), onActionClick: handleLocationInputClear, value: searchLocationKeywords, onChange: handleSearchLocationInputChange, onFocus: () => dispatch({ type: ActionTypes$1.FocusInputLocation }), size: "md", trackingAttributes: locationTrackingAttributes }),
|
|
1075
|
+
!isMobile && renderLocationResults()),
|
|
1076
|
+
React__default.createElement(StyledInputSearchWrapper, { ref: inputSearchWrapperRef },
|
|
1077
|
+
React__default.createElement(StyledInput, { placeholder: inputSearchPlaceholder ||
|
|
1078
|
+
t('booking.searchBar.searchInput.placeholder'), autoComplete: "off", name: "search-results", actionIcon: React__default.createElement(StyledClearIcon, { color: 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 }),
|
|
1079
|
+
!isMobile && renderSearchResults()),
|
|
1080
|
+
state.autoCompleteDisabled && !state.isMobile && (React__default.createElement(SearchButton, { onClick: () => {
|
|
1081
|
+
onSearch({
|
|
1082
|
+
cityId: state.selectedLocation.id,
|
|
1083
|
+
keyword: searchKeywords,
|
|
1084
|
+
});
|
|
1085
|
+
} }))));
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
const DoctorIcon$1 = () => (React__default.createElement("svg", { width: "14", height: "18", viewBox: "0 0 14 18" },
|
|
1089
|
+
React__default.createElement("path", { d: "M7.00004 0.666992C5.29757 0.666992 3.64067 0.813476 2.52087 1.03158C1.73311 1.18457 1.16671 1.86816 1.16671 2.6722V4.83366C1.16671 5.29264 1.54106 5.66699 2.00004 5.66699H12C12.459 5.66699 12.8334 5.29264 12.8334 4.83366V2.69824C12.8334 1.89421 12.267 1.21061 11.4792 1.05762C10.3562 0.839518 8.69275 0.666992 7.00004 0.666992ZM6.16671 1.50033H7.83337V2.33366H8.66671V4.00033H7.83337V4.83366H6.16671V4.00033H5.33337V2.33366H6.16671V1.50033ZM1.42712 6.50033C1.3197 6.89421 1.24158 7.32389 1.19275 7.77637C1.14718 8.18001 1.05603 9.25423 1.06254 9.36491C0.603556 9.72624 0.333374 10.2861 0.333374 10.9014C0.333374 11.8356 0.977906 12.6364 1.84379 12.8285C2.74548 15.0192 4.55212 17.3337 7.00004 17.3337C9.44796 17.3337 11.2546 14.9964 12.1563 12.8024C13.0222 12.6136 13.6667 11.8356 13.6667 10.9014C13.6667 10.2861 13.3965 9.72624 12.9375 9.36491C12.9441 9.25423 12.8562 8.16048 12.8073 7.75033C12.7552 7.30436 12.6804 6.89095 12.573 6.50033H5.35942C6.52804 8.20606 9.27543 7.18717 11.0365 7.62012C11.5736 8.79199 11.1667 10.4326 11.1667 10.4326L11.8177 10.641C11.9121 10.6702 12 10.7549 12 10.9014C12 11.0576 11.8861 11.1943 11.6875 11.1878L11.0105 11.0837L10.7761 11.7347C9.96554 14.0492 8.4128 15.667 7.00004 15.667C5.58728 15.667 4.03455 14.0492 3.224 11.7347L2.96358 11.0837L2.26046 11.1878C2.11723 11.1878 2.00004 11.0576 2.00004 10.9014C2.00004 10.7549 2.08793 10.6702 2.18233 10.641L2.83337 10.4326C2.73246 10.5531 2.4102 8.7041 2.83337 8.03678C3.59184 7.5127 4.2266 7.87728 5.12504 6.50033H1.42712ZM5.17712 9.05241C4.57166 9.05241 4.08337 9.55371 4.08337 10.1722C4.08337 10.7907 4.57166 11.292 5.17712 11.292C5.78259 11.292 6.27087 10.7907 6.27087 10.1722C6.27087 9.55371 5.78259 9.05241 5.17712 9.05241ZM8.82296 9.05241C8.21749 9.05241 7.72921 9.55371 7.72921 10.1722C7.72921 10.7907 8.21749 11.292 8.82296 11.292C9.42843 11.292 9.91671 10.7907 9.91671 10.1722C9.91671 9.55371 9.42843 9.05241 8.82296 9.05241Z", fill: "#9AA2AC" })));
|
|
1090
|
+
const ServiceIcon$1 = () => (React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
|
|
1091
|
+
React__default.createElement("path", { d: "M8.99996 0.666992C6.27535 0.666992 3.85348 1.97884 2.33329 4.00033H4.59892C5.80009 2.94564 7.36259 2.33366 8.99996 2.33366C10.6373 2.33366 12.1998 2.94564 13.401 4.00033H15.6666C14.1464 1.97884 11.7246 0.666992 8.99996 0.666992ZM1.78642 4.83366C1.07678 7.04069 0.666626 9.59928 0.666626 12.3337C0.666626 14.085 0.826131 15.7679 1.13538 17.3337H16.8645C17.1738 15.7679 17.3333 14.085 17.3333 12.3337C17.3333 9.59928 16.9231 7.04069 16.2135 4.83366H1.78642ZM8.99996 7.33366C11.3014 7.33366 13.1666 9.19889 13.1666 11.5003C13.1666 13.8018 11.3014 15.667 8.99996 15.667C6.69853 15.667 4.83329 13.8018 4.83329 11.5003C4.83329 9.19889 6.69853 7.33366 8.99996 7.33366ZM8.16663 9.00033V10.667H6.49996V12.3337H8.16663V14.0003H9.83329V12.3337H11.5V10.667H9.83329V9.00033H8.16663Z", fill: "#9AA2AC" })));
|
|
1092
|
+
const HospitalIcon$1 = () => (React__default.createElement("svg", { width: "16", height: "17", viewBox: "0 0 16 17" },
|
|
1093
|
+
React__default.createElement("path", { d: "M8 0.666992L0.5 5.63533V14.8337C0.5 15.7545 1.24583 16.5003 2.16667 16.5003H13.8333C14.7542 16.5003 15.5 15.7545 15.5 14.8337V5.63533L8 0.666992ZM11.3333 10.667H8.83333V13.167H7.16667V10.667H4.66667V9.00033H7.16667V6.50033H8.83333V9.00033H11.3333V10.667Z", fill: "#9AA2AC" })));
|
|
1094
|
+
const SpecialtyIcon$1 = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" },
|
|
1095
|
+
React__default.createElement("path", { d: "M3.83333 0.5C2.94928 0.5 2.10143 0.851189 1.47631 1.47631C0.851189 2.10143 0.5 2.94928 0.5 3.83333C0.5 4.71739 0.851189 5.56523 1.47631 6.19036C2.10143 6.81548 2.94928 7.16667 3.83333 7.16667C4.71739 7.16667 5.56523 6.81548 6.19036 6.19036C6.81548 5.56523 7.16667 4.71739 7.16667 3.83333C7.16667 2.94928 6.81548 2.10143 6.19036 1.47631C5.56523 0.851189 4.71739 0.5 3.83333 0.5V0.5ZM10.5 0.5C9.57917 0.5 8.83333 1.24583 8.83333 2.16667V5.5C8.83333 6.42083 9.57917 7.16667 10.5 7.16667H13.8333C14.7542 7.16667 15.5 6.42083 15.5 5.5V2.16667C15.5 1.24583 14.7542 0.5 13.8333 0.5H10.5ZM3.83333 8.83333C2.94928 8.83333 2.10143 9.18452 1.47631 9.80964C0.851189 10.4348 0.5 11.2826 0.5 12.1667C0.5 13.0507 0.851189 13.8986 1.47631 14.5237C2.10143 15.1488 2.94928 15.5 3.83333 15.5C4.71739 15.5 5.56523 15.1488 6.19036 14.5237C6.81548 13.8986 7.16667 13.0507 7.16667 12.1667C7.16667 11.2826 6.81548 10.4348 6.19036 9.80964C5.56523 9.18452 4.71739 8.83333 3.83333 8.83333V8.83333ZM12.1667 8.83333C11.2826 8.83333 10.4348 9.18452 9.80964 9.80964C9.18452 10.4348 8.83333 11.2826 8.83333 12.1667C8.83333 13.0507 9.18452 13.8986 9.80964 14.5237C10.4348 15.1488 11.2826 15.5 12.1667 15.5C13.0507 15.5 13.8986 15.1488 14.5237 14.5237C15.1488 13.8986 15.5 13.0507 15.5 12.1667C15.5 11.2826 15.1488 10.4348 14.5237 9.80964C13.8986 9.18452 13.0507 8.83333 12.1667 8.83333V8.83333Z", fill: "#9AA2AC" })));
|
|
1096
|
+
|
|
1097
|
+
const StyledTypeHeader = styled.header `
|
|
1098
|
+
display: flex;
|
|
1099
|
+
justify-content: space-between;
|
|
1100
|
+
padding: 12px 24px;
|
|
1101
|
+
background-color: ${theme.colors.neutral50};
|
|
1102
|
+
box-shadow: inset 0px 1px 0px #e4e8ec;
|
|
1103
|
+
`;
|
|
1104
|
+
const StyledInfoWrapper = styled.div `
|
|
1105
|
+
display: grid;
|
|
1106
|
+
flex: 2;
|
|
1107
|
+
align-items: center;
|
|
1108
|
+
gap: 16px;
|
|
1109
|
+
grid-template-columns: 16px 1fr;
|
|
1110
|
+
`;
|
|
1111
|
+
const StyledTypeName = styled.p `
|
|
1112
|
+
color: ${theme.colors.neutral800};
|
|
1113
|
+
font-size: 14px;
|
|
1114
|
+
font-weight: ${theme.sizes.fwSemiBold};
|
|
1115
|
+
letter-spacing: -0.2px;
|
|
1116
|
+
line-height: 22px;
|
|
1117
|
+
`;
|
|
1118
|
+
const StyledSeeMoreButton = styled.button `
|
|
1119
|
+
flex: 1;
|
|
1120
|
+
cursor: pointer;
|
|
1121
|
+
text-align: end;
|
|
1122
|
+
`;
|
|
1123
|
+
const StyledResultsContainer = styled.section `
|
|
1124
|
+
padding: 12px 16px;
|
|
1125
|
+
--rowGap: 16px;
|
|
1126
|
+
--graphicSize: 32px;
|
|
1127
|
+
|
|
1128
|
+
${MediaQueries.tdUp} {
|
|
1129
|
+
--rowGap: 8px;
|
|
1130
|
+
}
|
|
1131
|
+
`;
|
|
1132
|
+
const StyledItemsWrapper = styled.ul `
|
|
1133
|
+
--gap: 16px;
|
|
1134
|
+
${MediaQueries.tdUp} {
|
|
1135
|
+
--gap: 8px;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
display: grid;
|
|
1139
|
+
overflow: hidden;
|
|
1140
|
+
gap: var(--gap);
|
|
1141
|
+
transition: max-height 0.8s ease-out;
|
|
1142
|
+
|
|
1143
|
+
${({ isMore }) => isMore &&
|
|
1144
|
+
`
|
|
1145
|
+
height: auto;
|
|
1146
|
+
max-height: 0;
|
|
1147
|
+
margin-top: var(--gap);
|
|
1148
|
+
`}
|
|
1149
|
+
|
|
1150
|
+
${({ isShown }) => isShown &&
|
|
1151
|
+
`
|
|
1152
|
+
max-height: 600px;
|
|
1153
|
+
`}
|
|
1154
|
+
|
|
1155
|
+
@media (prefers-reduced-motion) {
|
|
1156
|
+
transition: none;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
${MediaQueries.tdUp} {
|
|
1160
|
+
grid-template-columns: 1fr 1fr;
|
|
1161
|
+
}
|
|
1162
|
+
`;
|
|
1163
|
+
const StyledSeeMore = styled(Text) `
|
|
1164
|
+
margin-top: 12px;
|
|
1165
|
+
margin-bottom: 8px;
|
|
1166
|
+
cursor: pointer;
|
|
1167
|
+
text-align: start;
|
|
1168
|
+
text-transform: capitalize;
|
|
1169
|
+
`;
|
|
1170
|
+
|
|
1171
|
+
const StyledResult = styled.li `
|
|
1172
|
+
display: flex;
|
|
1173
|
+
align-items: center;
|
|
1174
|
+
gap: var(--rowGap);
|
|
1175
|
+
cursor: pointer;
|
|
1176
|
+
&.not-nav {
|
|
1177
|
+
cursor: default;
|
|
1178
|
+
}
|
|
1179
|
+
`;
|
|
1180
|
+
const StyledRoundedIconWrapper = styled.div `
|
|
1181
|
+
--wrapper-size: var(--graphicSize);
|
|
1182
|
+
border-radius: calc(var(--wrapper-size) / 2);
|
|
1183
|
+
background-color: var(--neutral50);
|
|
1184
|
+
width: var(--wrapper-size);
|
|
1185
|
+
height: var(--wrapper-size);
|
|
1186
|
+
aspect-ratio: 1/1;
|
|
1187
|
+
overflow: hidden;
|
|
1188
|
+
|
|
1189
|
+
${({ type }) => type &&
|
|
1190
|
+
type === 'doctors' &&
|
|
1191
|
+
`
|
|
1192
|
+
border-radius: calc(var(--graphicSize) / 2);
|
|
1193
|
+
`}
|
|
1194
|
+
|
|
1195
|
+
img {
|
|
1196
|
+
width: var(--graphicSize);
|
|
1197
|
+
height: var(--graphicSize);
|
|
1198
|
+
${({ type }) => type && type === 'doctors'
|
|
1199
|
+
? `
|
|
1200
|
+
|
|
1201
|
+
object-fit: cover;
|
|
1202
|
+
`
|
|
1203
|
+
: `
|
|
1204
|
+
object-fit: contain;
|
|
1205
|
+
`}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
&:focus-visible {
|
|
1209
|
+
outline: 1px solid ${theme.colors.gray600};
|
|
1210
|
+
}
|
|
1211
|
+
`;
|
|
1212
|
+
const StyledText = styled(Text) `
|
|
1213
|
+
line-height: 22px;
|
|
1214
|
+
letter-spacing: -0.2px;
|
|
1215
|
+
|
|
1216
|
+
${MediaQueries.tdUp} {
|
|
1217
|
+
&[data-size='p3'] {
|
|
1218
|
+
font-size: 14px;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
`;
|
|
1222
|
+
const StyledPictureWrapper = styled.figure `
|
|
1223
|
+
max-width: var(--graphicSize);
|
|
1224
|
+
min-width: var(--graphicSize);
|
|
1225
|
+
`;
|
|
1226
|
+
const StyledLocationPin = styled.svg `
|
|
1227
|
+
margin: 0 auto;
|
|
1228
|
+
display: block;
|
|
1229
|
+
`;
|
|
1230
|
+
const StyledImageSkeletonWrapper = styled.div `
|
|
1231
|
+
display: grid;
|
|
1232
|
+
place-items: center;
|
|
1233
|
+
`;
|
|
1234
|
+
|
|
1235
|
+
const defaultThumbnailByType = {
|
|
1236
|
+
doctors: DefaultThumbnailDoctor,
|
|
1237
|
+
services: DefaultThumbnailService,
|
|
1238
|
+
};
|
|
1239
|
+
const ResultSectionItem = ({ type, item, imageUrl, className, onClickItem, }) => {
|
|
1240
|
+
const onKeyDown = (e) => {
|
|
1241
|
+
if (e.key === 'Enter' || e.key === 'Space') {
|
|
1242
|
+
if (onClickItem) {
|
|
1243
|
+
onClickItem(item);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
const defaultThumbnail = useMemo(() => {
|
|
1248
|
+
const Cmp = defaultThumbnailByType[type] || DefaultThumbnailAny;
|
|
1249
|
+
return React__default.createElement(Cmp, { width: 32, height: type === 'services' ? 32 : 24 });
|
|
1250
|
+
}, [type]);
|
|
1251
|
+
return (React__default.createElement(StyledResult, { onClick: () => onClickItem && onClickItem(item), onKeyDown: onKeyDown, tabIndex: 0, role: "button", className: className },
|
|
1252
|
+
React__default.createElement(StyledPictureWrapper, null, type === 'hospitals' ? (React__default.createElement(StyledLocationPin, { width: "12", height: "16", viewBox: "0 0 12 16" },
|
|
1253
|
+
React__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.createElement(StyledRoundedIconWrapper, { type: type }, imageUrl ? (React__default.createElement("img", { src: imageUrl, width: 32, height: type === 'services' ? 32 : 24, loading: "lazy" })) : (defaultThumbnail)))),
|
|
1254
|
+
React__default.createElement(StyledText, { color: theme.colors.gray800, size: "p3" }, item.name)));
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
const ResultSection = ({ type, data, state, dispatch, itemsToShow, itemsToShowDesktop, isMobile, isLoading, keyword, isNavResultItem, }) => {
|
|
1258
|
+
const [seeMoreOpen, setSeeMoreOpen] = useState(false);
|
|
1259
|
+
const { t, locale } = useTranslations();
|
|
1260
|
+
const { selectedLocation, searchKeywords } = state;
|
|
1261
|
+
const slugs = useMemo(() => LOCALIZED_SLUGS[locale], [locale]);
|
|
1262
|
+
const isMalay = locale === 'ms-MY';
|
|
1263
|
+
const typeInformation = useMemo(() => {
|
|
1264
|
+
return {
|
|
1265
|
+
doctors: {
|
|
1266
|
+
name: t('booking.searchPopup.doctors'),
|
|
1267
|
+
icon: React__default.createElement(DoctorIcon$1, null),
|
|
1268
|
+
slug: slugs.DOCTOR,
|
|
1269
|
+
},
|
|
1270
|
+
services: {
|
|
1271
|
+
name: t('booking.searchPopup.services'),
|
|
1272
|
+
icon: React__default.createElement(ServiceIcon$1, null),
|
|
1273
|
+
slug: slugs.SERVICE,
|
|
1274
|
+
},
|
|
1275
|
+
hospitals: {
|
|
1276
|
+
name: t('booking.searchPopup.hospitals'),
|
|
1277
|
+
icon: React__default.createElement(HospitalIcon$1, null),
|
|
1278
|
+
slug: slugs.HOSPITAL,
|
|
1279
|
+
},
|
|
1280
|
+
specialties: {
|
|
1281
|
+
name: t('booking.searchPopup.specialties'),
|
|
1282
|
+
icon: React__default.createElement(SpecialtyIcon$1, null),
|
|
1283
|
+
slug: slugs.SPECIALTIES,
|
|
1284
|
+
},
|
|
1285
|
+
};
|
|
1286
|
+
}, [type, slugs]);
|
|
1287
|
+
const typeSlug = useMemo(() => typeInformation[type].slug, [typeInformation]);
|
|
1288
|
+
const showItemCount = isMobile ? itemsToShow : itemsToShowDesktop;
|
|
1289
|
+
function onClickItem(item) {
|
|
1290
|
+
let url = '';
|
|
1291
|
+
switch (type) {
|
|
1292
|
+
case 'specialties':
|
|
1293
|
+
url = `/${selectedLocation.slug}/${typeInformation.doctors.slug}/${item.slug}`;
|
|
1294
|
+
break;
|
|
1295
|
+
case 'services':
|
|
1296
|
+
url = `/${selectedLocation.slug}/${typeSlug}/${item.slug}`;
|
|
1297
|
+
break;
|
|
1298
|
+
case 'doctors':
|
|
1299
|
+
case 'hospitals':
|
|
1300
|
+
url = `/${typeSlug}/${item.slug}-${item.id}`;
|
|
1301
|
+
break;
|
|
1302
|
+
}
|
|
1303
|
+
if (url) {
|
|
1304
|
+
dispatch({
|
|
1305
|
+
type: ActionTypes$1.SelectSearchResult,
|
|
1306
|
+
payload: { name: item.name, url },
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
function renderItem(item) {
|
|
1311
|
+
return (React__default.createElement(ResultSectionItem, { key: item.id, item: item, type: type, imageUrl: item.logo || item.avatar || item.thumbnail, className: !isNavResultItem ? 'not-nav' : '', onClickItem: isNavResultItem && onClickItem }));
|
|
1312
|
+
}
|
|
1313
|
+
function onSeeAllClick() {
|
|
1314
|
+
let url = '';
|
|
1315
|
+
switch (type) {
|
|
1316
|
+
case 'specialties':
|
|
1317
|
+
url = `/${typeSlug}`;
|
|
1318
|
+
break;
|
|
1319
|
+
case 'services':
|
|
1320
|
+
case 'doctors':
|
|
1321
|
+
case 'hospitals':
|
|
1322
|
+
url = `/${selectedLocation.slug}/${typeSlug}`;
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
if (url) {
|
|
1326
|
+
dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
function onClickSearchByKeyword() {
|
|
1330
|
+
const { slug: typeSlug } = typeInformation[type];
|
|
1331
|
+
const url = `/${selectedLocation.slug}/${typeSlug}?q=${searchKeywords}`;
|
|
1332
|
+
dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
|
|
1333
|
+
}
|
|
1334
|
+
return (React__default.createElement("section", null,
|
|
1335
|
+
React__default.createElement(StyledTypeHeader, null,
|
|
1336
|
+
React__default.createElement(StyledInfoWrapper, null,
|
|
1337
|
+
typeInformation[type].icon,
|
|
1338
|
+
React__default.createElement(StyledTypeName, null, typeInformation[type].name)),
|
|
1339
|
+
(keyword.trim().length <= SEARCH_KEYWORD_MIN_LENGTH$1[locale] ||
|
|
1340
|
+
isMalay) && (React__default.createElement(StyledSeeMoreButton, { onClick: onSeeAllClick },
|
|
1341
|
+
React__default.createElement(Text, { size: "p3", color: theme.colors.primaryBase }, t('booking.searchPopup.seeAll'))))),
|
|
1342
|
+
(isLoading || (data && data.length > 0)) && (React__default.createElement(StyledResultsContainer, null,
|
|
1343
|
+
React__default.createElement(StyledItemsWrapper, null,
|
|
1344
|
+
isLoading &&
|
|
1345
|
+
Array(2)
|
|
1346
|
+
.fill(undefined)
|
|
1347
|
+
.map((_, i) => (React__default.createElement(StyledResult, { key: type + 'loading' + i },
|
|
1348
|
+
React__default.createElement(StyledPictureWrapper, null,
|
|
1349
|
+
React__default.createElement(StyledImageSkeletonWrapper, null,
|
|
1350
|
+
React__default.createElement(Skeleton, { height: 14, width: type === 'hospitals' ? 12 : 32, style: {
|
|
1351
|
+
maxWidth: 'var(--graphicSize)',
|
|
1352
|
+
minHeight: 'var(--graphicSize)',
|
|
1353
|
+
} }))),
|
|
1354
|
+
React__default.createElement(Skeleton, { width: 120, height: 24 })))),
|
|
1355
|
+
!isLoading &&
|
|
1356
|
+
data &&
|
|
1357
|
+
data.length > 0 &&
|
|
1358
|
+
data.slice(0, showItemCount).map(renderItem)),
|
|
1359
|
+
React__default.createElement(StyledItemsWrapper, { isShown: seeMoreOpen, isMore: true }, data.slice(showItemCount, -1).map(renderItem)),
|
|
1360
|
+
type === 'specialties' &&
|
|
1361
|
+
showItemCount < data.length &&
|
|
1362
|
+
!isLoading && (React__default.createElement("button", { onClick: () => setSeeMoreOpen(!seeMoreOpen) },
|
|
1363
|
+
React__default.createElement(StyledSeeMore, { size: "p3", color: theme.colors.primaryBase }, seeMoreOpen
|
|
1364
|
+
? t('booking.searchPopup.seeLessSpecialties')
|
|
1365
|
+
: t('booking.searchPopup.seeMoreSpecialties')))),
|
|
1366
|
+
type !== 'specialties' &&
|
|
1367
|
+
(showItemCount < data.length || isMalay) &&
|
|
1368
|
+
!isLoading &&
|
|
1369
|
+
keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[locale] && (React__default.createElement("button", { onClick: onClickSearchByKeyword },
|
|
1370
|
+
React__default.createElement(StyledSeeMore, { size: "p3", color: theme.colors.primaryBase }, t(`booking.searchPopup.searchIn.${type}`, {
|
|
1371
|
+
name: keyword,
|
|
1372
|
+
})))))),
|
|
1373
|
+
!isLoading && (data === null || data === void 0 ? void 0 : data.length) === 0 && (React__default.createElement(StyledResultsContainer, null,
|
|
1374
|
+
React__default.createElement(Text, { size: "sm", color: theme.colors.gray400 }, t('booking.searchBar.noResults'))))));
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
const StyledSection = styled.section `
|
|
1378
|
+
background-color: white;
|
|
1379
|
+
border-radius: 4px;
|
|
1380
|
+
position: absolute;
|
|
1381
|
+
width: 100%;
|
|
1382
|
+
z-index: 30;
|
|
1383
|
+
|
|
1384
|
+
${MediaQueries.tdUp} {
|
|
1385
|
+
box-shadow: 0px 24px 32px rgba(0, 0, 0, 0.04),
|
|
1386
|
+
0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
|
|
1387
|
+
0px 0px 1px rgba(0, 0, 0, 0.04);
|
|
1388
|
+
}
|
|
1389
|
+
`;
|
|
1390
|
+
const SearchResults = ({ data, state, dispatch, isMobile, isLoading, keyword, hideResults, isNavResultItem, }) => {
|
|
1391
|
+
return (React__default.createElement(StyledSection, null, data &&
|
|
1392
|
+
data.map((data) => {
|
|
1393
|
+
if (hideResults && hideResults.includes(data.type)) {
|
|
1394
|
+
return React__default.createElement(React__default.Fragment, null);
|
|
1395
|
+
}
|
|
1396
|
+
return (React__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 }));
|
|
1397
|
+
})));
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
const getApiPath = (path, params, locale) => {
|
|
1401
|
+
return formatString(path, Object.assign(Object.assign({}, params), { domain: domainLocales[locale || 'en-PH'] }));
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
function useSearchBarApi$1({ dispatch, careApiDomain, locale = 'vi-VN', }) {
|
|
1405
|
+
const fetchCitiesApi = useCallback(function fetchCitiesApi(path, params = {}) {
|
|
1406
|
+
const url = `${careApiDomain}${path}`;
|
|
1407
|
+
dispatch({ type: ActionTypes$1.FetchCitiesStart });
|
|
1408
|
+
return fetch(getApiPath(url, params, locale), { method: 'GET' })
|
|
1409
|
+
.then((res) => res.json())
|
|
1410
|
+
.then((data) => {
|
|
1411
|
+
if (data._status !== 1 || !data._data) {
|
|
1412
|
+
console.log('error loading cities', data);
|
|
1413
|
+
return Promise.reject(data);
|
|
1414
|
+
}
|
|
1415
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
1416
|
+
})
|
|
1417
|
+
.finally(() => dispatch({ type: ActionTypes$1.FetchCitiesFinish }));
|
|
1418
|
+
}, [locale]);
|
|
1419
|
+
const fetchCitiesByLocation = useCallback(function fetchCitiesByLocation({ coordinates }) {
|
|
1420
|
+
let params = {};
|
|
1421
|
+
const moreParams = {};
|
|
1422
|
+
if (coordinates) {
|
|
1423
|
+
params = {
|
|
1424
|
+
lat: coordinates.lat,
|
|
1425
|
+
lng: coordinates.lng,
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
if (locale === 'ms-MY') {
|
|
1429
|
+
moreParams.noPaging = 1;
|
|
1430
|
+
}
|
|
1431
|
+
const requests = [
|
|
1432
|
+
fetchCitiesApi(PATHS.GET_CITY_BY_IP, Object.assign(Object.assign({}, params), moreParams)),
|
|
1433
|
+
];
|
|
1434
|
+
if (locale === 'zh-TW') {
|
|
1435
|
+
requests.push(fetchCitiesApi(PATHS.GET_CITIES_LIST, { noPaging: 1 }));
|
|
1436
|
+
}
|
|
1437
|
+
return Promise.all(requests)
|
|
1438
|
+
.then(([data1, data2]) => {
|
|
1439
|
+
const data = Object.assign({}, data1);
|
|
1440
|
+
if (data2) {
|
|
1441
|
+
const citiesIds = data.cities.map((c) => c.id);
|
|
1442
|
+
data.cities = data.cities.concat(data2.cities.filter((c) => !citiesIds.includes(c.id)));
|
|
1443
|
+
}
|
|
1444
|
+
dispatch({
|
|
1445
|
+
type: ActionTypes$1.FetchCitiesByGeoIpComplete,
|
|
1446
|
+
payload: data,
|
|
1447
|
+
});
|
|
1448
|
+
})
|
|
1449
|
+
.catch((err) => console.error('error loading cities by location', err));
|
|
1450
|
+
}, [locale, careApiDomain, dispatch]);
|
|
1451
|
+
const fetchCitiesByKeyword = useCallback(function fetchCitiesByKeyword(keyword) {
|
|
1452
|
+
return fetchCitiesApi(PATHS.GET_CITIES_LIST, { keyword })
|
|
1453
|
+
.then((data) => {
|
|
1454
|
+
dispatch({
|
|
1455
|
+
type: ActionTypes$1.FetchCitiesByKeywordComplete,
|
|
1456
|
+
payload: data.cities,
|
|
1457
|
+
});
|
|
1458
|
+
})
|
|
1459
|
+
.catch((err) => console.error('error loading cities by keyword', err));
|
|
1460
|
+
}, [locale, careApiDomain, dispatch]);
|
|
1461
|
+
const fetchSearchResults = useCallback(function fetchSearchResults(searchKeywords, state) {
|
|
1462
|
+
const url = `${careApiDomain}${PATHS.GET_SEARCH_V2}`;
|
|
1463
|
+
dispatch({ type: ActionTypes$1.FetchSearchResultsStart });
|
|
1464
|
+
const { defaultCity, selectedLocation, geoLocationCoordinates } = state;
|
|
1465
|
+
let cityId = '';
|
|
1466
|
+
if (!selectedLocation || !defaultCity) {
|
|
1467
|
+
dispatch({ type: ActionTypes$1.FetchSearchResultsFinish });
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
const isCurrentLocationSelected = selectedLocation.id === ID_OPTION_CURRENT_LOCATION;
|
|
1471
|
+
if (isCurrentLocationSelected) {
|
|
1472
|
+
if (!geoLocationCoordinates) {
|
|
1473
|
+
cityId = defaultCity.id;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
else if (selectedLocation.id === ID_OPTION_ALL_LOCATION) {
|
|
1477
|
+
cityId = '';
|
|
1478
|
+
}
|
|
1479
|
+
else {
|
|
1480
|
+
cityId = selectedLocation.id;
|
|
1481
|
+
}
|
|
1482
|
+
const lat = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lat) || '';
|
|
1483
|
+
const lng = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lng) || '';
|
|
1484
|
+
return fetch(getApiPath(url, {
|
|
1485
|
+
domain: careApiDomain,
|
|
1486
|
+
searchType: 'global',
|
|
1487
|
+
keyword: searchKeywords.trim().length > SEARCH_KEYWORD_MIN_LENGTH$1[locale]
|
|
1488
|
+
? searchKeywords.trim()
|
|
1489
|
+
: '',
|
|
1490
|
+
city: cityId === ID_OPTION_CURRENT_LOCATION ? '' : cityId,
|
|
1491
|
+
lat,
|
|
1492
|
+
lng,
|
|
1493
|
+
}, locale), {
|
|
1494
|
+
method: 'GET',
|
|
1495
|
+
headers: {
|
|
1496
|
+
accept: 'version=2.0.0.0',
|
|
1497
|
+
},
|
|
1498
|
+
})
|
|
1499
|
+
.then((res) => res.json())
|
|
1500
|
+
.then((data) => {
|
|
1501
|
+
if (data._status !== 1 || !data._data) {
|
|
1502
|
+
return Promise.reject(data);
|
|
1503
|
+
}
|
|
1504
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
1505
|
+
})
|
|
1506
|
+
.then((results) => dispatch({
|
|
1507
|
+
type: ActionTypes$1.FetchSearchResultsComplete,
|
|
1508
|
+
payload: results,
|
|
1509
|
+
}))
|
|
1510
|
+
.catch((error) => {
|
|
1511
|
+
console.log('error loading search results', { url, error });
|
|
1512
|
+
})
|
|
1513
|
+
.finally(() => dispatch({ type: ActionTypes$1.FetchSearchResultsFinish }));
|
|
1514
|
+
}, [locale, careApiDomain, dispatch]);
|
|
1515
|
+
return {
|
|
1516
|
+
fetchCitiesByLocation,
|
|
1517
|
+
fetchCitiesByKeyword,
|
|
1518
|
+
fetchSearchResults,
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
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, }) => {
|
|
1523
|
+
const { t, locale } = useTranslations();
|
|
1524
|
+
const wrapperRef = useRef(null);
|
|
1525
|
+
const hiddenInputRef = useRef(null);
|
|
1526
|
+
const [viewportHeight, setViewportHeight] = useState(undefined);
|
|
1527
|
+
const [isNavResultPage, setIsNavResultPage] = useState(false);
|
|
1528
|
+
const { geoLocationPermission: geoLocationPermissionFromHook, geoLocationCoordinates: geoLocationCoordinatesFromHook, requestGeoLocation, } = useGeolocation();
|
|
1529
|
+
const [state, dispatch] = useReducer(reducer$1, initialState$1, (s) => (Object.assign(Object.assign({}, s), { isDebug,
|
|
1530
|
+
isMobile, geoLocationPermission: geoLocationPermissionFromProps ||
|
|
1531
|
+
geoLocationPermissionFromHook ||
|
|
1532
|
+
'unset', geoLocationCoordinates: geoLocationCoordinatesFromProps ||
|
|
1533
|
+
geoLocationCoordinatesFromHook ||
|
|
1534
|
+
null, searchKeywords: initialSearchValue, initialSelectedCity: initialSelectedCityFromProps || null, selectedLocation: initialSelectedCityFromProps || s.selectedLocation || null, searchLocationKeywords: (initialSelectedCityFromProps === null || initialSelectedCityFromProps === void 0 ? void 0 : initialSelectedCityFromProps.name) || s.searchLocationKeywords, autoCompleteDisabled,
|
|
1535
|
+
inputSearchPlaceholder,
|
|
1536
|
+
locale })));
|
|
1537
|
+
const { navigateTo, focused, isLoadingCities, cities, searchKeywords, geoLocationPermission, selectedLocation, initialSelectedCity, defaultCity, searchResults, isLoadingSearchResults, isMobileModalOpened, inputSearchPlaceholder: inputSearchPlaceholderState, } = state;
|
|
1538
|
+
const { fetchCitiesByLocation, fetchCitiesByKeyword, fetchSearchResults } = useSearchBarApi$1({
|
|
1539
|
+
dispatch,
|
|
1540
|
+
locale,
|
|
1541
|
+
careApiDomain,
|
|
1542
|
+
});
|
|
1543
|
+
const currentLocationCityItem = useMemo(() => {
|
|
1544
|
+
var _a;
|
|
1545
|
+
return ({
|
|
1546
|
+
id: ID_OPTION_CURRENT_LOCATION,
|
|
1547
|
+
name: t('booking.searchBar.currentLocation'),
|
|
1548
|
+
slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.CURRENT,
|
|
1549
|
+
});
|
|
1550
|
+
}, [t, locale]);
|
|
1551
|
+
const debouncedFetchCitiesByKeyword = useMemo(() => debounce(fetchCitiesByKeyword, 400), [fetchCitiesByKeyword]);
|
|
1552
|
+
const debouncedFetchSearchResults = useMemo(() => debounce(fetchSearchResults, 400), [fetchSearchResults]);
|
|
1553
|
+
useEffect(() => {
|
|
1554
|
+
if (initialSearchValue !== '' &&
|
|
1555
|
+
initialSearchValue !== state.searchKeywords) {
|
|
1556
|
+
dispatch({
|
|
1557
|
+
type: ActionTypes$1.UpdateInitialSearchValue,
|
|
1558
|
+
payload: initialSearchValue,
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
}, [initialSearchValue]);
|
|
1562
|
+
useEffect(() => {
|
|
1563
|
+
if (askForGeolocationPermission &&
|
|
1564
|
+
(selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === ID_OPTION_CURRENT_LOCATION &&
|
|
1565
|
+
geoLocationPermission === 'unset') {
|
|
1566
|
+
requestGeoLocation();
|
|
1567
|
+
}
|
|
1568
|
+
}, [askForGeolocationPermission, selectedLocation, geoLocationPermission]);
|
|
1569
|
+
useEffect(() => {
|
|
1570
|
+
if (!geoLocationPermissionFromProps &&
|
|
1571
|
+
geoLocationPermission !== geoLocationPermissionFromHook) {
|
|
1572
|
+
if (geoLocationPermissionFromHook === 'granted' &&
|
|
1573
|
+
geoLocationCoordinatesFromHook) {
|
|
1574
|
+
dispatch({
|
|
1575
|
+
type: ActionTypes$1.GrantGeoLocationPermission,
|
|
1576
|
+
payload: geoLocationCoordinatesFromHook,
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
else if (geoLocationPermissionFromHook === 'denied') {
|
|
1580
|
+
dispatch({ type: ActionTypes$1.DenyGeoLocationPermission });
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
}, [
|
|
1584
|
+
geoLocationPermission,
|
|
1585
|
+
geoLocationPermissionFromHook,
|
|
1586
|
+
geoLocationCoordinatesFromHook,
|
|
1587
|
+
geoLocationPermissionFromProps,
|
|
1588
|
+
]);
|
|
1589
|
+
useEffect(() => {
|
|
1590
|
+
if (navigateTo) {
|
|
1591
|
+
if (routerPush) {
|
|
1592
|
+
routerPush(navigateTo);
|
|
1593
|
+
}
|
|
1594
|
+
else {
|
|
1595
|
+
window.location.href = `${careFrontDomain}${navigateTo}`;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}, [navigateTo]);
|
|
1599
|
+
const selectCurrentLocation = useCallback(function selectCurrentLocation() {
|
|
1600
|
+
dispatch({
|
|
1601
|
+
type: ActionTypes$1.SelectCurrentLocation,
|
|
1602
|
+
payload: currentLocationCityItem,
|
|
1603
|
+
});
|
|
1604
|
+
}, [t, dispatch]);
|
|
1605
|
+
useEffect(() => {
|
|
1606
|
+
var _a;
|
|
1607
|
+
if (geoLocationPermission !== 'denied' && !initialSelectedCity) {
|
|
1608
|
+
dispatch({
|
|
1609
|
+
type: ActionTypes$1.SelectLocation,
|
|
1610
|
+
payload: {
|
|
1611
|
+
name: t('booking.searchBar.allLocations'),
|
|
1612
|
+
id: ID_OPTION_ALL_LOCATION,
|
|
1613
|
+
slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
|
|
1614
|
+
},
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
if (onGeoLocationPermissionChange) {
|
|
1618
|
+
onGeoLocationPermissionChange(geoLocationPermission, state.geoLocationCoordinates);
|
|
1619
|
+
}
|
|
1620
|
+
if (isMobile && geoLocationPermission === 'granted' && selectedLocation) {
|
|
1621
|
+
dispatch({ type: ActionTypes$1.FocusInputSearch });
|
|
1622
|
+
}
|
|
1623
|
+
fetchCitiesByLocation({ coordinates: state.geoLocationCoordinates });
|
|
1624
|
+
}, [geoLocationPermission]);
|
|
1625
|
+
useEffect(() => {
|
|
1626
|
+
if (selectedLocation && defaultCity) {
|
|
1627
|
+
fetchSearchResults(state.searchKeywords, state);
|
|
1628
|
+
}
|
|
1629
|
+
}, [selectedLocation, defaultCity]);
|
|
1630
|
+
useEffect(() => {
|
|
1631
|
+
if (inputSearchPlaceholder !== inputSearchPlaceholderState) {
|
|
1632
|
+
dispatch({
|
|
1633
|
+
type: ActionTypes$1.SetInputSearchPlaceholder,
|
|
1634
|
+
payload: inputSearchPlaceholder,
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
}, [inputSearchPlaceholder, inputSearchPlaceholderState]);
|
|
1638
|
+
useEffect(() => {
|
|
1639
|
+
if (isMobileModalOpened) {
|
|
1640
|
+
document.body.classList.add('care-popup-open');
|
|
1641
|
+
}
|
|
1642
|
+
else {
|
|
1643
|
+
document.body.classList.remove('care-popup-open');
|
|
1644
|
+
}
|
|
1645
|
+
}, [isMobileModalOpened]);
|
|
1646
|
+
const handleLocationClick = useCallback(function handleLocationClick(city) {
|
|
1647
|
+
if (locale === 'ms-MY') {
|
|
1648
|
+
setIsNavResultPage(true);
|
|
1649
|
+
}
|
|
1650
|
+
dispatch({ type: ActionTypes$1.SelectLocation, payload: city });
|
|
1651
|
+
if (locale !== 'ms-MY') {
|
|
1652
|
+
focusSearchInput();
|
|
1653
|
+
}
|
|
1654
|
+
if (onChangeLocation) {
|
|
1655
|
+
onChangeLocation(city);
|
|
1656
|
+
}
|
|
1657
|
+
}, [t, dispatch]);
|
|
1658
|
+
function handleCurrentLocationClick() {
|
|
1659
|
+
if (locale === 'ms-MY') {
|
|
1660
|
+
setIsNavResultPage(true);
|
|
1661
|
+
}
|
|
1662
|
+
if (isMobile && state.geoLocationPermission !== 'granted') {
|
|
1663
|
+
requestGeoLocation();
|
|
1664
|
+
}
|
|
1665
|
+
else {
|
|
1666
|
+
selectCurrentLocation();
|
|
1667
|
+
if (locale !== 'ms-MY') {
|
|
1668
|
+
focusSearchInput();
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
function handleMobileFakeInputClick() {
|
|
1673
|
+
var _a;
|
|
1674
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1675
|
+
if (hiddenInputRef.current) {
|
|
1676
|
+
hiddenInputRef.current.focus();
|
|
1677
|
+
}
|
|
1678
|
+
dispatch({ type: ActionTypes$1.OpenMobileModal });
|
|
1679
|
+
yield Promise.resolve();
|
|
1680
|
+
if (wrapperRef.current) {
|
|
1681
|
+
(_a = wrapperRef.current
|
|
1682
|
+
.querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
function focusLocationInput() {
|
|
1687
|
+
var _a;
|
|
1688
|
+
if (wrapperRef.current) {
|
|
1689
|
+
(_a = wrapperRef.current
|
|
1690
|
+
.querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
function focusSearchInput() {
|
|
1694
|
+
var _a;
|
|
1695
|
+
if (wrapperRef.current) {
|
|
1696
|
+
(_a = wrapperRef.current
|
|
1697
|
+
.querySelector('input[name="search-results"]')) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
function handleMobileTopBarClose() {
|
|
1701
|
+
dispatch({ type: ActionTypes$1.CloseMobileModal });
|
|
1702
|
+
}
|
|
1703
|
+
function renderLocationResults() {
|
|
1704
|
+
if (focused !== 'location') {
|
|
1705
|
+
return null;
|
|
1706
|
+
}
|
|
1707
|
+
return (React__default.createElement(LocationResults, { isLoading: isLoadingCities, cities: cities, onLocationClick: handleLocationClick, onCurrentLocationClick: handleCurrentLocationClick, isLocationLoading: isLoadingCities, geoLocationPermission: geoLocationPermission, selectedLocation: selectedLocation, isOptionAllLocation: isOptionAllLocation }));
|
|
1708
|
+
}
|
|
1709
|
+
function renderSearchResults() {
|
|
1710
|
+
if (focused !== 'search') {
|
|
1711
|
+
return null;
|
|
1712
|
+
}
|
|
1713
|
+
if (state.autoCompleteDisabled) {
|
|
1714
|
+
if (!isMobile) {
|
|
1715
|
+
return null;
|
|
1716
|
+
}
|
|
1717
|
+
return (React__default.createElement(SearchButton, { onClick: () => {
|
|
1718
|
+
onSearch({
|
|
1719
|
+
cityId: state.selectedLocation.id,
|
|
1720
|
+
keyword: searchKeywords,
|
|
1721
|
+
});
|
|
1722
|
+
handleMobileTopBarClose();
|
|
1723
|
+
} }));
|
|
1724
|
+
}
|
|
1725
|
+
return (React__default.createElement(SearchResults, { data: searchResults, state: state, dispatch: dispatch, isMobile: false, keyword: searchKeywords, isLoading: isLoadingSearchResults, hideResults: hideResults, isNavResultItem: isNavResultItem }));
|
|
1726
|
+
}
|
|
1727
|
+
function renderSearchInputs() {
|
|
1728
|
+
return (React__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 }));
|
|
1729
|
+
}
|
|
1730
|
+
useEffect(() => {
|
|
1731
|
+
if (window.visualViewport) {
|
|
1732
|
+
const resizeHandler = (evt) => {
|
|
1733
|
+
const viewport = evt.target;
|
|
1734
|
+
setViewportHeight(viewport === null || viewport === void 0 ? void 0 : viewport.height);
|
|
1735
|
+
};
|
|
1736
|
+
window.visualViewport.addEventListener('resize', resizeHandler, {
|
|
1737
|
+
passive: true,
|
|
1738
|
+
});
|
|
1739
|
+
return () => {
|
|
1740
|
+
window.visualViewport.removeEventListener('resize', resizeHandler);
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
}, [setViewportHeight]);
|
|
1744
|
+
useEffect(() => {
|
|
1745
|
+
// Apply for ms-MY. Navigation to result page after selected location
|
|
1746
|
+
if (selectedLocation && isNavResultPage && locale === 'ms-MY') {
|
|
1747
|
+
const url = `/${selectedLocation.slug}/hospital`;
|
|
1748
|
+
dispatch({ type: ActionTypes$1.NavigateTo, payload: url });
|
|
1749
|
+
setIsNavResultPage(false);
|
|
1750
|
+
}
|
|
1751
|
+
}, [isNavResultPage, locale, selectedLocation]);
|
|
1752
|
+
if (isMobile) {
|
|
1753
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
1754
|
+
React__default.createElement(CareSearchGlobalStyles, null),
|
|
1755
|
+
React__default.createElement(StyledHiddenInputMobile, { ref: hiddenInputRef }),
|
|
1756
|
+
React__default.createElement(StyledSearchBarMobileWrapper, { id: "booking-search-bar", ref: wrapperRef, "data-is-modal": isMobile && isMobileModalOpened, style: {
|
|
1757
|
+
'--mobile-care-searchbar-height': isMobileModalOpened && viewportHeight
|
|
1758
|
+
? `${viewportHeight}px`
|
|
1759
|
+
: '100%',
|
|
1760
|
+
} }, !isMobileModalOpened ? (React__default.createElement(MobileFakeInput, { onClick: handleMobileFakeInputClick, focused: focused, value: searchKeywords, trackingAttributes: gaTrackingSearchBar, inputSearchPlaceholder: inputSearchPlaceholder })) : (React__default.createElement(React__default.Fragment, null,
|
|
1761
|
+
React__default.createElement(StyledSearchBarMobileModalHeader, null,
|
|
1762
|
+
React__default.createElement(MobileTopBar, { headingText: t('booking.searchBar.searchButton'), onLeftClick: handleMobileTopBarClose }),
|
|
1763
|
+
renderSearchInputs()),
|
|
1764
|
+
renderLocationResults(),
|
|
1765
|
+
renderSearchResults())))));
|
|
1766
|
+
}
|
|
1767
|
+
return (React__default.createElement(StyledSearchBarWrapper$1, { id: "booking-search-bar", ref: wrapperRef }, renderSearchInputs()));
|
|
1768
|
+
};
|
|
1769
|
+
|
|
1770
|
+
const StyledSearchBarWrapper = styled.div ``;
|
|
1771
|
+
const StyleWrapperContainer = styled.div `
|
|
1772
|
+
background-color: ${theme.colors.neutral50};
|
|
1773
|
+
padding-bottom: 1px;
|
|
1774
|
+
${MediaQueries.mbDown} {
|
|
1775
|
+
padding: 0 16px 10px;
|
|
1776
|
+
}
|
|
1777
|
+
`;
|
|
1778
|
+
const StyleSearchInputContainer = styled(Container) `
|
|
1779
|
+
padding: 0 16px;
|
|
1780
|
+
|
|
1781
|
+
${MediaQueries.mbDown} {
|
|
1782
|
+
padding: 0;
|
|
1783
|
+
}
|
|
1784
|
+
`;
|
|
1785
|
+
const StyleSearchContent = styled.div `
|
|
1786
|
+
padding: 24px 56px;
|
|
1787
|
+
border-radius: 0px 0px 16px 16px;
|
|
1788
|
+
background-color: ${theme.colors.white};
|
|
1789
|
+
box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.04),
|
|
1790
|
+
0px 0px 2px 0px rgba(0, 0, 0, 0.06), 0px 4px 8px 0px rgba(0, 0, 0, 0.04);
|
|
1791
|
+
|
|
1792
|
+
${MediaQueries.mbDown} {
|
|
1793
|
+
padding: 16px 16px;
|
|
1794
|
+
border-radius: 0px 0px 12px 12px;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
.flex-search-input {
|
|
1798
|
+
flex-direction: row;
|
|
1799
|
+
${MediaQueries.mbDown} {
|
|
1800
|
+
flex-direction: column;
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
`;
|
|
1804
|
+
|
|
1805
|
+
const SEARCH_KEYWORD_MIN_LENGTH = {
|
|
1806
|
+
'en-PH': 3,
|
|
1807
|
+
'tl-PH': 2,
|
|
1808
|
+
'id-ID': 3,
|
|
1809
|
+
'vi-VN': 2,
|
|
1810
|
+
'zh-TW': 0,
|
|
1811
|
+
'ms-MY': 2,
|
|
1812
|
+
};
|
|
1813
|
+
|
|
1814
|
+
const initialState = {
|
|
1815
|
+
isMobile: false,
|
|
1816
|
+
isDebug: false,
|
|
1817
|
+
navigateTo: null,
|
|
1818
|
+
geoLocationPermission: 'unset',
|
|
1819
|
+
geoLocationCoordinates: null,
|
|
1820
|
+
focused: 'none',
|
|
1821
|
+
focusedSpecialty: 'none',
|
|
1822
|
+
searchLocationKeywords: '',
|
|
1823
|
+
searchSpecialtyKeywords: '',
|
|
1824
|
+
searchKeywords: '',
|
|
1825
|
+
selectedLocation: null,
|
|
1826
|
+
selectedSpecialty: null,
|
|
1827
|
+
defaultCity: null,
|
|
1828
|
+
initialCities: [],
|
|
1829
|
+
cities: [],
|
|
1830
|
+
searchResults: {},
|
|
1831
|
+
initialSearchResults: {},
|
|
1832
|
+
isLoadingCities: false,
|
|
1833
|
+
isLoadingSearchResults: false,
|
|
1834
|
+
isMobileModalOpened: false,
|
|
1835
|
+
initialSelectedCity: null,
|
|
1836
|
+
autoCompleteDisabled: false,
|
|
1837
|
+
inputSearchPlaceholder: '',
|
|
1838
|
+
locale: 'vi-VN',
|
|
1839
|
+
allSpecialties: [],
|
|
1840
|
+
popularKeys: [],
|
|
1841
|
+
};
|
|
1842
|
+
var ActionTypes;
|
|
1843
|
+
(function (ActionTypes) {
|
|
1844
|
+
ActionTypes["NavigateTo"] = "navigate to url";
|
|
1845
|
+
ActionTypes["ClickOutsideInputLocation"] = "click outside input location";
|
|
1846
|
+
ActionTypes["ClickOutsideInputSearch"] = "click outside input search";
|
|
1847
|
+
ActionTypes["ClickOutsideInputSearchSpecialty"] = "click outside input search specialty";
|
|
1848
|
+
ActionTypes["ClickOutsideInputSpecialty"] = "click outside input specialty";
|
|
1849
|
+
ActionTypes["SelectCurrentLocation"] = "select current location";
|
|
1850
|
+
ActionTypes["FocusInputLocation"] = "focus input location";
|
|
1851
|
+
ActionTypes["FocusInputSearch"] = "focus input search";
|
|
1852
|
+
ActionTypes["FocusInputSearchSpecialty"] = "focus input search specialty";
|
|
1853
|
+
ActionTypes["ChangeInputLocation"] = "change input location";
|
|
1854
|
+
ActionTypes["ChangeInputSearch"] = "change input search";
|
|
1855
|
+
ActionTypes["ClearInputLocation"] = "clear input location";
|
|
1856
|
+
ActionTypes["ClearInputSearch"] = "clear input search";
|
|
1857
|
+
ActionTypes["SelectLocation"] = "select location";
|
|
1858
|
+
ActionTypes["SelectSpecialty"] = "select specialty";
|
|
1859
|
+
ActionTypes["FetchCitiesStart"] = "fetch cities start";
|
|
1860
|
+
ActionTypes["FetchCitiesFinish"] = "fetch cities finish";
|
|
1861
|
+
ActionTypes["FetchSearchResultsStart"] = "fetch search results start";
|
|
1862
|
+
ActionTypes["FetchSearchResultsComplete"] = "fetch search results complete";
|
|
1863
|
+
ActionTypes["FetchSearchResultsFinish"] = "fetch search results finish";
|
|
1864
|
+
ActionTypes["FetchCitiesByGeoIpComplete"] = "fetch cities by geo IP finish";
|
|
1865
|
+
ActionTypes["FetchCitiesByKeywordComplete"] = "fetch cities by keyword finish";
|
|
1866
|
+
ActionTypes["DisplayInitialCities"] = "display initial cities";
|
|
1867
|
+
ActionTypes["DisplayInitialSearchResults"] = "display initial search results";
|
|
1868
|
+
ActionTypes["UpdateInitialSearchResults"] = "update initial search results";
|
|
1869
|
+
ActionTypes["GrantGeoLocationPermission"] = "grant geolocation permission";
|
|
1870
|
+
ActionTypes["DenyGeoLocationPermission"] = "deny geolocation permission";
|
|
1871
|
+
ActionTypes["OpenMobileModal"] = "open mobile modal";
|
|
1872
|
+
ActionTypes["CloseMobileModal"] = "close mobile modal";
|
|
1873
|
+
ActionTypes["UpdateInitialSearchValue"] = "update initial search value";
|
|
1874
|
+
ActionTypes["SelectSearchResult"] = "select search result";
|
|
1875
|
+
ActionTypes["SetInputSearchPlaceholder"] = "set input search placeholder";
|
|
1876
|
+
ActionTypes["FocusInputSpecialty"] = "focus input specialty";
|
|
1877
|
+
ActionTypes["FetchAllSpecialties"] = "fetch all specialty";
|
|
1878
|
+
ActionTypes["FetchPopularKeys"] = "fetch popular key by type";
|
|
1879
|
+
})(ActionTypes || (ActionTypes = {}));
|
|
1880
|
+
function resetSearchLocationKeywords(state) {
|
|
1881
|
+
const { selectedLocation, searchLocationKeywords } = state;
|
|
1882
|
+
if (selectedLocation && searchLocationKeywords !== selectedLocation.name) {
|
|
1883
|
+
return Object.assign(Object.assign({}, state), { searchLocationKeywords: selectedLocation.name });
|
|
1884
|
+
}
|
|
1885
|
+
return state;
|
|
1886
|
+
}
|
|
1887
|
+
function reducer(state, action) {
|
|
1888
|
+
var _a, _b;
|
|
1889
|
+
if (state.isDebug) {
|
|
1890
|
+
console.log('bookingSearchBar', { action, state });
|
|
1891
|
+
}
|
|
1892
|
+
switch (action.type) {
|
|
1893
|
+
case ActionTypes.NavigateTo:
|
|
1894
|
+
return Object.assign(Object.assign({}, state), { navigateTo: action.payload, focused: 'none', isMobileModalOpened: false });
|
|
1895
|
+
case ActionTypes.ClickOutsideInputLocation: {
|
|
1896
|
+
if (state.focused !== 'location') {
|
|
1897
|
+
return state;
|
|
1898
|
+
}
|
|
1899
|
+
return resetSearchLocationKeywords(Object.assign(Object.assign({}, state), { focused: 'none' }));
|
|
1900
|
+
}
|
|
1901
|
+
case ActionTypes.ClickOutsideInputSpecialty: {
|
|
1902
|
+
if (state.focused !== 'specialty') {
|
|
1903
|
+
return state;
|
|
1904
|
+
}
|
|
1905
|
+
return resetSearchLocationKeywords(Object.assign(Object.assign({}, state), { focused: 'none' }));
|
|
1906
|
+
}
|
|
1907
|
+
case ActionTypes.ClickOutsideInputSearch: {
|
|
1908
|
+
if (state.focused !== 'search') {
|
|
1909
|
+
return state;
|
|
1910
|
+
}
|
|
1911
|
+
return Object.assign(Object.assign({}, state), { focused: 'none' });
|
|
1912
|
+
}
|
|
1913
|
+
case ActionTypes.ClickOutsideInputSearchSpecialty: {
|
|
1914
|
+
if (state.focusedSpecialty !== 'search') {
|
|
1915
|
+
return state;
|
|
1916
|
+
}
|
|
1917
|
+
return Object.assign(Object.assign({}, state), { focusedSpecialty: 'none' });
|
|
1918
|
+
}
|
|
1919
|
+
case ActionTypes.FocusInputLocation: {
|
|
1920
|
+
const nextState = Object.assign(Object.assign({}, state), { focused: 'location' });
|
|
1921
|
+
if (((_a = state.selectedLocation) === null || _a === void 0 ? void 0 : _a.id) === ID_OPTION_CURRENT_LOCATION) {
|
|
1922
|
+
nextState.searchLocationKeywords = '';
|
|
1923
|
+
}
|
|
1924
|
+
return nextState;
|
|
1925
|
+
}
|
|
1926
|
+
case ActionTypes.FocusInputSpecialty: {
|
|
1927
|
+
const nextState = Object.assign(Object.assign({}, state), { focused: 'specialty' });
|
|
1928
|
+
if (((_b = state.selectedLocation) === null || _b === void 0 ? void 0 : _b.id) === ID_OPTION_CURRENT_LOCATION) {
|
|
1929
|
+
nextState.searchLocationKeywords = '';
|
|
1930
|
+
}
|
|
1931
|
+
return nextState;
|
|
1932
|
+
}
|
|
1933
|
+
case ActionTypes.FocusInputSearch:
|
|
1934
|
+
const nextState = Object.assign(Object.assign({}, state), { focused: 'search' });
|
|
1935
|
+
if (state.isMobile) {
|
|
1936
|
+
return resetSearchLocationKeywords(nextState);
|
|
1937
|
+
}
|
|
1938
|
+
return nextState;
|
|
1939
|
+
case ActionTypes.FocusInputSearchSpecialty: {
|
|
1940
|
+
const nextState = Object.assign(Object.assign({}, state), { focusedSpecialty: 'search' });
|
|
1941
|
+
return nextState;
|
|
1942
|
+
}
|
|
1943
|
+
case ActionTypes.ChangeInputLocation:
|
|
1944
|
+
return Object.assign(Object.assign({}, state), { searchLocationKeywords: action.payload });
|
|
1945
|
+
case ActionTypes.ChangeInputSearch: {
|
|
1946
|
+
const keyword = action.payload;
|
|
1947
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: keyword, isLoadingSearchResults: keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] });
|
|
1948
|
+
}
|
|
1949
|
+
case ActionTypes.SelectCurrentLocation:
|
|
1950
|
+
return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
|
|
1951
|
+
case ActionTypes.ClearInputLocation:
|
|
1952
|
+
return Object.assign(Object.assign({}, state), { focused: 'location', cities: state.initialCities, searchLocationKeywords: '' });
|
|
1953
|
+
case ActionTypes.ClearInputSearch:
|
|
1954
|
+
return Object.assign(Object.assign({}, state), { focused: 'search', searchKeywords: '' });
|
|
1955
|
+
case ActionTypes.SelectLocation:
|
|
1956
|
+
return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
|
|
1957
|
+
case ActionTypes.SelectSpecialty:
|
|
1958
|
+
return Object.assign(Object.assign({}, state), { focused: 'none', selectedSpecialty: action.payload });
|
|
1959
|
+
case ActionTypes.SelectSearchResult:
|
|
1960
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: action.payload.name, isMobileModalOpened: false, focused: 'none', navigateTo: action.payload.url });
|
|
1961
|
+
case ActionTypes.FetchCitiesStart:
|
|
1962
|
+
return Object.assign(Object.assign({}, state), { isLoadingCities: true });
|
|
1963
|
+
case ActionTypes.FetchCitiesFinish:
|
|
1964
|
+
return Object.assign(Object.assign({}, state), { isLoadingCities: false });
|
|
1965
|
+
case ActionTypes.FetchSearchResultsStart:
|
|
1966
|
+
return Object.assign(Object.assign({}, state), { isLoadingSearchResults: true });
|
|
1967
|
+
case ActionTypes.FetchSearchResultsFinish:
|
|
1968
|
+
return Object.assign(Object.assign({}, state), { isLoadingSearchResults: false });
|
|
1969
|
+
case ActionTypes.FetchSearchResultsComplete: {
|
|
1970
|
+
const nextState = Object.assign(Object.assign({}, state), { searchResults: Object.assign(Object.assign({}, state.searchResults), { [action.payload.key]: action.payload.searches }) });
|
|
1971
|
+
return nextState;
|
|
1972
|
+
}
|
|
1973
|
+
case ActionTypes.FetchCitiesByGeoIpComplete: {
|
|
1974
|
+
let { cities } = action.payload;
|
|
1975
|
+
const { default: defaultCity } = action.payload;
|
|
1976
|
+
cities = cities.filter((c) => c.id !== defaultCity.id);
|
|
1977
|
+
if (defaultCity) {
|
|
1978
|
+
cities.unshift(defaultCity);
|
|
1979
|
+
}
|
|
1980
|
+
if (state.initialSelectedCity &&
|
|
1981
|
+
!cities.find((c) => c.id === state.initialSelectedCity.id)) {
|
|
1982
|
+
cities.unshift(state.initialSelectedCity);
|
|
1983
|
+
}
|
|
1984
|
+
const nextState = Object.assign(Object.assign({}, state), { defaultCity, initialCities: cities, cities });
|
|
1985
|
+
if (state.geoLocationPermission === 'denied' &&
|
|
1986
|
+
!state.initialSelectedCity) {
|
|
1987
|
+
nextState.selectedLocation = defaultCity;
|
|
1988
|
+
nextState.searchLocationKeywords = defaultCity.name;
|
|
1989
|
+
}
|
|
1990
|
+
return nextState;
|
|
1991
|
+
}
|
|
1992
|
+
case ActionTypes.FetchCitiesByKeywordComplete:
|
|
1993
|
+
return Object.assign(Object.assign({}, state), { cities: action.payload });
|
|
1994
|
+
case ActionTypes.DisplayInitialCities:
|
|
1995
|
+
return Object.assign(Object.assign({}, state), { cities: state.initialCities });
|
|
1996
|
+
case ActionTypes.DisplayInitialSearchResults:
|
|
1997
|
+
return Object.assign(Object.assign({}, state), { searchResults: state.initialSearchResults, isLoadingSearchResults: false });
|
|
1998
|
+
case ActionTypes.UpdateInitialSearchResults:
|
|
1999
|
+
return Object.assign(Object.assign({}, state), { initialSearchResults: Object.assign(Object.assign({}, state.initialSearchResults), { [action.payload.key]: action.payload.searches }) });
|
|
2000
|
+
case ActionTypes.GrantGeoLocationPermission:
|
|
2001
|
+
return Object.assign(Object.assign({}, state), { geoLocationPermission: 'granted', geoLocationCoordinates: action.payload });
|
|
2002
|
+
case ActionTypes.DenyGeoLocationPermission:
|
|
2003
|
+
return Object.assign(Object.assign({}, state), { geoLocationPermission: 'denied', geoLocationCoordinates: null });
|
|
2004
|
+
case ActionTypes.OpenMobileModal:
|
|
2005
|
+
return Object.assign(Object.assign({}, state), { isMobileModalOpened: true });
|
|
2006
|
+
case ActionTypes.CloseMobileModal:
|
|
2007
|
+
return Object.assign(Object.assign({}, state), { isMobileModalOpened: false });
|
|
2008
|
+
case ActionTypes.UpdateInitialSearchValue:
|
|
2009
|
+
return Object.assign(Object.assign({}, state), { searchKeywords: action.payload });
|
|
2010
|
+
case ActionTypes.SetInputSearchPlaceholder:
|
|
2011
|
+
return Object.assign(Object.assign({}, state), { inputSearchPlaceholder: action.payload });
|
|
2012
|
+
case ActionTypes.FetchAllSpecialties:
|
|
2013
|
+
return Object.assign(Object.assign({}, state), { allSpecialties: action.payload });
|
|
2014
|
+
case ActionTypes.FetchPopularKeys:
|
|
2015
|
+
return Object.assign(Object.assign({}, state), { popularKeys: action.payload });
|
|
2016
|
+
default:
|
|
2017
|
+
return state;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
const StyleSearchInputsWrapper = styled.div `
|
|
2022
|
+
flex: 1;
|
|
2023
|
+
position: relative;
|
|
2024
|
+
|
|
2025
|
+
${MediaQueries.mbDown} {
|
|
2026
|
+
width: 100%;
|
|
2027
|
+
display: flex;
|
|
2028
|
+
flex-direction: column;
|
|
2029
|
+
gap: 12px;
|
|
2030
|
+
}
|
|
2031
|
+
`;
|
|
2032
|
+
const StyleResultWrapper$2 = styled.div `
|
|
2033
|
+
position: absolute;
|
|
2034
|
+
top: calc(100% + 2px);
|
|
2035
|
+
width: 100%;
|
|
2036
|
+
border-radius: 4px;
|
|
2037
|
+
background: ${theme.colors.white};
|
|
2038
|
+
box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
|
|
2039
|
+
z-index: 10;
|
|
2040
|
+
|
|
2041
|
+
${MediaQueries.mbDown} {
|
|
2042
|
+
width: calc(100% + 64px);
|
|
2043
|
+
left: -32px;
|
|
2044
|
+
}
|
|
2045
|
+
`;
|
|
2046
|
+
|
|
2047
|
+
const StyledSearchResultWrapper = styled.div ``;
|
|
2048
|
+
const StyleResultHeader = styled.div `
|
|
2049
|
+
display: flex;
|
|
2050
|
+
justify-content: space-between;
|
|
2051
|
+
align-item: center;
|
|
2052
|
+
padding: 9px 14px 9px 22px;
|
|
2053
|
+
background: #f7f9fc;
|
|
2054
|
+
|
|
2055
|
+
.title {
|
|
2056
|
+
color: ${theme.colors.gray800};
|
|
2057
|
+
font-size: 14px;
|
|
2058
|
+
font-weight: 600;
|
|
2059
|
+
line-height: 22px;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
.btn-see-all {
|
|
2063
|
+
color: ${theme.colors.blue600};
|
|
2064
|
+
font-size: 14px;
|
|
2065
|
+
line-height: 22px;
|
|
2066
|
+
cursor: pointer;
|
|
2067
|
+
}
|
|
2068
|
+
`;
|
|
2069
|
+
const StyleResultBody = styled.div `
|
|
2070
|
+
padding: 10px 16px;
|
|
2071
|
+
max-height: 400px;
|
|
2072
|
+
overflow: auto;
|
|
2073
|
+
`;
|
|
2074
|
+
const StyleResultItem = styled.div `
|
|
2075
|
+
display: flex;
|
|
2076
|
+
gap: 12px;
|
|
2077
|
+
align-items: center;
|
|
2078
|
+
cursor: pointer;
|
|
2079
|
+
|
|
2080
|
+
&:hover {
|
|
2081
|
+
background-color: ${theme.colors.blue50};
|
|
2082
|
+
}
|
|
2083
|
+
.image-item {
|
|
2084
|
+
flex: 0 0 48px;
|
|
2085
|
+
width: 48px;
|
|
2086
|
+
height: 48px;
|
|
2087
|
+
border-radius: 50%;
|
|
2088
|
+
|
|
2089
|
+
img {
|
|
2090
|
+
object-fit: contain;
|
|
2091
|
+
width: 100%;
|
|
2092
|
+
height: 100%;
|
|
2093
|
+
border-radius: 50%;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
.infor {
|
|
2097
|
+
overflow: hidden;
|
|
2098
|
+
padding: 12px 0;
|
|
2099
|
+
flex: 1;
|
|
2100
|
+
border-bottom: 1px solid ${theme.colors.neutral100};
|
|
2101
|
+
.title {
|
|
2102
|
+
color: ${theme.colors.gray800};
|
|
2103
|
+
font-size: 16px;
|
|
2104
|
+
font-weight: 600;
|
|
2105
|
+
line-height: 24px;
|
|
2106
|
+
}
|
|
2107
|
+
.description {
|
|
2108
|
+
overflow: hidden;
|
|
2109
|
+
color: ${theme.colors.gray600};
|
|
2110
|
+
text-overflow: ellipsis;
|
|
2111
|
+
white-space: nowrap;
|
|
2112
|
+
font-size: 12px;
|
|
2113
|
+
line-height: 18px;
|
|
2114
|
+
display: flex;
|
|
2115
|
+
gap: 8px;
|
|
2116
|
+
align-items: center;
|
|
2117
|
+
margin-top: 5px;
|
|
2118
|
+
|
|
2119
|
+
svg {
|
|
2120
|
+
flex: 0 0 16px;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
.sub-description {
|
|
2124
|
+
overflow: hidden;
|
|
2125
|
+
white-space: nowrap;
|
|
2126
|
+
text-overflow: ellipsis;
|
|
2127
|
+
flex: 1;
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
&.last-item {
|
|
2133
|
+
.infor {
|
|
2134
|
+
border-bottom: none;
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
`;
|
|
2138
|
+
styled.div `
|
|
2139
|
+
padding: 0 16px 16px;
|
|
2140
|
+
|
|
2141
|
+
.search-detail-btn {
|
|
2142
|
+
color: ${theme.colors.blue600};
|
|
2143
|
+
font-size: 14px;
|
|
2144
|
+
line-height: 22px;
|
|
2145
|
+
cursor: pointer;
|
|
2146
|
+
}
|
|
2147
|
+
`;
|
|
2148
|
+
|
|
2149
|
+
const SearchResult = ({ state, type, results, location, isLoading, typeInformation, clientSlug = '', dispatch, }) => {
|
|
2150
|
+
const { locale, t } = useTranslations();
|
|
2151
|
+
const { selectedLocation } = state;
|
|
2152
|
+
const typeSlug = useMemo(() => typeInformation[type].slug, [typeInformation, type]);
|
|
2153
|
+
const handleOnClick = (item) => {
|
|
2154
|
+
let url = '';
|
|
2155
|
+
switch (type) {
|
|
2156
|
+
case 'service':
|
|
2157
|
+
url = `/${selectedLocation.slug}/${typeSlug}/${item.slug}`;
|
|
2158
|
+
break;
|
|
2159
|
+
case 'doctor':
|
|
2160
|
+
case 'hospital':
|
|
2161
|
+
url = `/${typeSlug}/${item.slug}-${item.id}`;
|
|
2162
|
+
break;
|
|
2163
|
+
}
|
|
2164
|
+
if (url) {
|
|
2165
|
+
dispatch({
|
|
2166
|
+
type: ActionTypes.NavigateTo,
|
|
2167
|
+
payload: url,
|
|
2168
|
+
});
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2171
|
+
const handleSeeAll = () => {
|
|
2172
|
+
let url = `/${selectedLocation.slug}/${typeSlug}`;
|
|
2173
|
+
const slugClientUrl = MAPPING_CLIENT_WITH_SLUG[locale][clientSlug];
|
|
2174
|
+
if (slugClientUrl) {
|
|
2175
|
+
url += `/${slugClientUrl}`;
|
|
2176
|
+
}
|
|
2177
|
+
if ((type === 'doctor' || type === 'hospital') &&
|
|
2178
|
+
state.selectedSpecialty.id > 0) {
|
|
2179
|
+
url += `?specialtyId=${state.selectedSpecialty.id}`;
|
|
2180
|
+
}
|
|
2181
|
+
if (url) {
|
|
2182
|
+
dispatch({ type: ActionTypes.NavigateTo, payload: url });
|
|
2183
|
+
}
|
|
2184
|
+
};
|
|
2185
|
+
return (React__default.createElement(StyledSearchResultWrapper, null,
|
|
2186
|
+
React__default.createElement(StyleResultHeader, null,
|
|
2187
|
+
React__default.createElement("div", { className: "title" }, t('booking.searchResult.description', {
|
|
2188
|
+
search_type: typeInformation[type].name,
|
|
2189
|
+
search_location: location,
|
|
2190
|
+
})),
|
|
2191
|
+
results.length > 0 && (React__default.createElement("div", { className: "btn-see-all", onClick: handleSeeAll }, t('home.seeAll')))),
|
|
2192
|
+
React__default.createElement(StyleResultBody, null,
|
|
2193
|
+
isLoading &&
|
|
2194
|
+
Array(3)
|
|
2195
|
+
.fill(undefined)
|
|
2196
|
+
.map((_, i) => (React__default.createElement(StyleResultItem, { key: type + 'loading' + i, className: i === 2 ? 'last-item' : '' },
|
|
2197
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2198
|
+
React__default.createElement(Skeleton$1, { height: 48, circle: true, mb: "xl", animate: true })),
|
|
2199
|
+
React__default.createElement("div", { className: "infor" },
|
|
2200
|
+
React__default.createElement("div", { className: "title" },
|
|
2201
|
+
React__default.createElement(Skeleton$1, { height: 8, mt: 10, radius: "xl", animate: true })),
|
|
2202
|
+
React__default.createElement("div", { className: "description" },
|
|
2203
|
+
React__default.createElement("div", { className: "sub-description" },
|
|
2204
|
+
React__default.createElement(Skeleton$1, { height: 8, mt: 10, radius: "xl", width: "80%", animate: true }))))))),
|
|
2205
|
+
!isLoading && results && results.length > 0 && (React__default.createElement(React__default.Fragment, null, results.map((item, index) => {
|
|
2206
|
+
var _a, _b;
|
|
2207
|
+
const isLastItem = (results.length > 4 && index === 3) ||
|
|
2208
|
+
(results.length <= 4 && index === results.length - 1);
|
|
2209
|
+
let subDescription = '';
|
|
2210
|
+
if (type === 'hospital') {
|
|
2211
|
+
subDescription = (item === null || item === void 0 ? void 0 : item.address) || '';
|
|
2212
|
+
}
|
|
2213
|
+
if (type === 'doctor') {
|
|
2214
|
+
subDescription = ((_a = item === null || item === void 0 ? void 0 : item.specialties) === null || _a === void 0 ? void 0 : _a.join(', ')) || '';
|
|
2215
|
+
}
|
|
2216
|
+
if (type === 'service') {
|
|
2217
|
+
subDescription = ((_b = item === null || item === void 0 ? void 0 : item.hospital_branch) === null || _b === void 0 ? void 0 : _b.name) || '';
|
|
2218
|
+
}
|
|
2219
|
+
if (index >= 4) {
|
|
2220
|
+
return React__default.createElement(React__default.Fragment, null);
|
|
2221
|
+
}
|
|
2222
|
+
return (React__default.createElement(StyleResultItem, { key: item.id, className: isLastItem ? 'last-item' : '', onClick: () => handleOnClick(item) },
|
|
2223
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2224
|
+
React__default.createElement("img", { src: item.logo || item.avatar, alt: item.name })),
|
|
2225
|
+
React__default.createElement("div", { className: "infor" },
|
|
2226
|
+
React__default.createElement("div", { className: "title" }, item.name),
|
|
2227
|
+
React__default.createElement("div", { className: "description" },
|
|
2228
|
+
typeInformation[type].icon,
|
|
2229
|
+
React__default.createElement("div", { className: "sub-description" }, subDescription)))));
|
|
2230
|
+
}))),
|
|
2231
|
+
!isLoading && (results === null || results === void 0 ? void 0 : results.length) === 0 && (React__default.createElement(Text, { size: "sm", color: theme.colors.gray400 }, t('booking.searchBar.noResults'))))));
|
|
2232
|
+
};
|
|
2233
|
+
|
|
2234
|
+
const StyleSearchSpecialtyWrapper = styled.div `
|
|
2235
|
+
position: relative;
|
|
2236
|
+
|
|
2237
|
+
${MediaQueries.mbDown} {
|
|
2238
|
+
width: 100%;
|
|
2239
|
+
display: flex;
|
|
2240
|
+
flex-direction: column;
|
|
2241
|
+
gap: 12px;
|
|
2242
|
+
}
|
|
2243
|
+
`;
|
|
2244
|
+
const StyleResultWrapper$1 = styled.div `
|
|
2245
|
+
position: absolute;
|
|
2246
|
+
top: calc(100% + 2px);
|
|
2247
|
+
width: calc(100% + 100px);
|
|
2248
|
+
border-radius: 4px;
|
|
2249
|
+
background: ${theme.colors.white};
|
|
2250
|
+
box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
|
|
2251
|
+
z-index: 10;
|
|
2252
|
+
max-height: 300px;
|
|
2253
|
+
overflow: auto;
|
|
2254
|
+
|
|
2255
|
+
${MediaQueries.mbDown} {
|
|
2256
|
+
width: calc(100% + 64px);
|
|
2257
|
+
left: -32px;
|
|
2258
|
+
}
|
|
2259
|
+
`;
|
|
2260
|
+
const StyledSpecialtyItem = styled.li `
|
|
2261
|
+
position: relative;
|
|
2262
|
+
cursor: pointer;
|
|
2263
|
+
padding: 12px 18px;
|
|
2264
|
+
display: flex;
|
|
2265
|
+
align-items: center;
|
|
2266
|
+
gap: 14px;
|
|
2267
|
+
overflow: hidden;
|
|
2268
|
+
|
|
2269
|
+
.image-item {
|
|
2270
|
+
display: flex;
|
|
2271
|
+
align-items: center;
|
|
2272
|
+
width: 40px;
|
|
2273
|
+
height: 40px;
|
|
2274
|
+
|
|
2275
|
+
img {
|
|
2276
|
+
width: 100%;
|
|
2277
|
+
object-fit: cover;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
svg {
|
|
2281
|
+
width: 40px;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
${({ isSelected }) => isSelected &&
|
|
2286
|
+
`
|
|
2287
|
+
&::after {
|
|
2288
|
+
content: ${checkMarkIconUrl};
|
|
2289
|
+
top: 50%;
|
|
2290
|
+
right: 18px;
|
|
2291
|
+
position: absolute;
|
|
2292
|
+
transform: translateY(-50%);
|
|
2293
|
+
}
|
|
2294
|
+
`}
|
|
2295
|
+
|
|
2296
|
+
& + li::before {
|
|
2297
|
+
content: '';
|
|
2298
|
+
position: absolute;
|
|
2299
|
+
left: 18px;
|
|
2300
|
+
right: 18px;
|
|
2301
|
+
top: 0;
|
|
2302
|
+
height: 1px;
|
|
2303
|
+
background-color: ${theme.colors.neutral100};
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
&:not([data-is-denied='true']):hover {
|
|
2307
|
+
background-color: ${theme.colors.neutral50};
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
&:last-child:hover {
|
|
2311
|
+
border-bottom-right-radius: 6px;
|
|
2312
|
+
border-bottom-left-radius: 6px;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
&:first-child:hover {
|
|
2316
|
+
border-top-right-radius: 6px;
|
|
2317
|
+
border-top-left-radius: 6px;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
&[data-is-denied='true'] {
|
|
2321
|
+
cursor: not-allowed;
|
|
2322
|
+
}
|
|
2323
|
+
`;
|
|
2324
|
+
|
|
2325
|
+
const DoctorIcon = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
|
|
2326
|
+
React__default.createElement("path", { d: "M8.98307 14.3333C7.87196 14.3333 6.92752 13.9445 6.14974 13.1667C5.37196 12.3889 4.98307 11.4445 4.98307 10.3333V9.96668C4.08307 9.85557 3.33041 9.45557 2.72507 8.76668C2.1193 8.07779 1.81641 7.26668 1.81641 6.33334V3.10001C1.81641 2.93334 1.87463 2.79157 1.99107 2.67468C2.10796 2.55823 2.24974 2.50001 2.41641 2.50001H3.81641V2.33334C3.81641 2.1889 3.86374 2.06934 3.95841 1.97468C4.05263 1.88045 4.17196 1.83334 4.31641 1.83334C4.46085 1.83334 4.58041 1.88045 4.67507 1.97468C4.7693 2.06934 4.81641 2.1889 4.81641 2.33334V3.66668C4.81641 3.81112 4.7693 3.93045 4.67507 4.02468C4.58041 4.11934 4.46085 4.16668 4.31641 4.16668C4.17196 4.16668 4.05263 4.11934 3.95841 4.02468C3.86374 3.93045 3.81641 3.81112 3.81641 3.66668V3.50001H2.81641V6.33334C2.81641 7.06668 3.07752 7.69445 3.59974 8.21668C4.12196 8.7389 4.74974 9.00001 5.48307 9.00001C6.21641 9.00001 6.84418 8.7389 7.36641 8.21668C7.88863 7.69445 8.14974 7.06668 8.14974 6.33334V3.50001H7.14974V3.66668C7.14974 3.81112 7.10263 3.93045 7.00841 4.02468C6.91374 4.11934 6.79418 4.16668 6.64974 4.16668C6.5053 4.16668 6.38596 4.11934 6.29174 4.02468C6.19707 3.93045 6.14974 3.81112 6.14974 3.66668V2.33334C6.14974 2.1889 6.19707 2.06934 6.29174 1.97468C6.38596 1.88045 6.5053 1.83334 6.64974 1.83334C6.79418 1.83334 6.91374 1.88045 7.00841 1.97468C7.10263 2.06934 7.14974 2.1889 7.14974 2.33334V2.50001H8.54974C8.71641 2.50001 8.85818 2.55823 8.97507 2.67468C9.09152 2.79157 9.14974 2.93334 9.14974 3.10001V6.33334C9.14974 7.26668 8.84707 8.07779 8.24174 8.76668C7.63596 9.45557 6.88307 9.85557 5.98307 9.96668V10.3333C5.98307 11.1667 6.27485 11.8751 6.85841 12.4587C7.44152 13.0418 8.14974 13.3333 8.98307 13.3333C9.81641 13.3333 10.5249 13.0418 11.1084 12.4587C11.6915 11.8751 11.9831 11.1667 11.9831 10.3333V9.25001C11.6386 9.1389 11.3526 8.93601 11.1251 8.64134C10.8971 8.34712 10.7831 8.01112 10.7831 7.63334C10.7831 7.15557 10.9497 6.75001 11.2831 6.41668C11.6164 6.08334 12.0164 5.91668 12.4831 5.91668C12.9609 5.91668 13.3664 6.08334 13.6997 6.41668C14.0331 6.75001 14.1997 7.15557 14.1997 7.63334C14.1997 8.01112 14.086 8.34712 13.8584 8.64134C13.6304 8.93601 13.3386 9.1389 12.9831 9.25001V10.3333C12.9831 11.4445 12.5942 12.3889 11.8164 13.1667C11.0386 13.9445 10.0942 14.3333 8.98307 14.3333ZM12.4831 8.33334C12.6831 8.33334 12.8526 8.26401 12.9917 8.12534C13.1304 7.98623 13.1997 7.82223 13.1997 7.63334C13.1997 7.43334 13.1304 7.26401 12.9917 7.12534C12.8526 6.98623 12.6831 6.91668 12.4831 6.91668C12.2831 6.91668 12.1164 6.98623 11.9831 7.12534C11.8497 7.26401 11.7831 7.43334 11.7831 7.63334C11.7831 7.82223 11.8497 7.98623 11.9831 8.12534C12.1164 8.26401 12.2831 8.33334 12.4831 8.33334Z", fill: "#595959" })));
|
|
2327
|
+
const ServiceIcon = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
|
|
2328
|
+
React__default.createElement("path", { d: "M6.86836 9.26489V10.2386C6.86836 10.509 6.96294 10.7389 7.15209 10.9283C7.34124 11.1176 7.57093 11.2122 7.84114 11.2122C8.11135 11.2122 8.34133 11.1176 8.53106 10.9283C8.7208 10.7389 8.81567 10.509 8.81567 10.2386V9.26489H9.78936C10.0598 9.26489 10.2897 9.17031 10.479 8.98116C10.6684 8.79201 10.763 8.56233 10.763 8.29211C10.763 8.0219 10.6684 7.79192 10.479 7.60219C10.2897 7.41245 10.0598 7.31758 9.78936 7.31758H8.81567V6.34389C8.81567 6.07343 8.72109 5.84354 8.53194 5.65422C8.34279 5.4649 8.11311 5.37024 7.84289 5.37024C7.57268 5.37024 7.3427 5.4649 7.15297 5.65422C6.96323 5.84354 6.86836 6.07343 6.86836 6.34389V7.31758H5.89467C5.62421 7.31758 5.39432 7.41216 5.205 7.60131C5.01568 7.79046 4.92102 8.02014 4.92102 8.29036C4.92102 8.56057 5.01568 8.79055 5.205 8.98028C5.39432 9.17002 5.62421 9.26489 5.89467 9.26489H6.86836ZM3.40809 14.1333C3.02086 14.1333 2.68938 13.9954 2.41364 13.7196C2.13788 13.4439 2 13.1124 2 12.7252V6.07426C2 5.85132 2.04987 5.64011 2.14961 5.44063C2.24936 5.24116 2.38723 5.07689 2.56323 4.94782L6.99718 1.61486C7.24323 1.42712 7.52444 1.33325 7.84081 1.33325C8.15718 1.33325 8.43919 1.42712 8.68685 1.61486L13.1208 4.94782C13.2968 5.07689 13.4347 5.24116 13.5344 5.44063C13.6342 5.64011 13.684 5.85132 13.684 6.07426V12.7252C13.684 13.1124 13.5462 13.4439 13.2704 13.7196C12.9947 13.9954 12.6632 14.1333 12.2759 14.1333H3.40809ZM3.40809 12.9649H12.2759C12.3459 12.9649 12.4033 12.9424 12.4482 12.8974C12.4932 12.8525 12.5156 12.7951 12.5156 12.7252V6.07426C12.5156 6.03431 12.5069 5.99811 12.4894 5.96566C12.4719 5.9332 12.4482 5.90449 12.4183 5.87953L7.98433 2.55406C7.94438 2.51911 7.89694 2.50164 7.84202 2.50164C7.78709 2.50164 7.73965 2.51911 7.69971 2.55406L3.26576 5.87953C3.2358 5.90449 3.21209 5.9332 3.1946 5.96566C3.17712 5.99811 3.16839 6.03431 3.16839 6.07426V12.7252C3.16839 12.7951 3.19086 12.8525 3.2358 12.8974C3.28075 12.9424 3.33818 12.9649 3.40809 12.9649Z", fill: "#595959" })));
|
|
2329
|
+
const HospitalIcon = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" },
|
|
2330
|
+
React__default.createElement("path", { d: "M7.99984 8.00004C8.3665 8.00004 8.68039 7.86949 8.9415 7.60837C9.20261 7.34726 9.33317 7.03337 9.33317 6.66671C9.33317 6.30004 9.20261 5.98615 8.9415 5.72504C8.68039 5.46393 8.3665 5.33337 7.99984 5.33337C7.63317 5.33337 7.31928 5.46393 7.05817 5.72504C6.79706 5.98615 6.6665 6.30004 6.6665 6.66671C6.6665 7.03337 6.79706 7.34726 7.05817 7.60837C7.31928 7.86949 7.63317 8.00004 7.99984 8.00004ZM7.99984 12.9C9.35539 11.6556 10.3609 10.525 11.0165 9.50837C11.6721 8.49171 11.9998 7.58893 11.9998 6.80004C11.9998 5.58893 11.6137 4.59726 10.8415 3.82504C10.0693 3.05282 9.12206 2.66671 7.99984 2.66671C6.87761 2.66671 5.93039 3.05282 5.15817 3.82504C4.38595 4.59726 3.99984 5.58893 3.99984 6.80004C3.99984 7.58893 4.32761 8.49171 4.98317 9.50837C5.63873 10.525 6.64428 11.6556 7.99984 12.9ZM7.99984 14.4167C7.91095 14.4167 7.82206 14.4 7.73317 14.3667C7.64428 14.3334 7.5665 14.2889 7.49984 14.2334C5.87761 12.8 4.6665 11.4695 3.8665 10.2417C3.0665 9.01393 2.6665 7.86671 2.6665 6.80004C2.6665 5.13337 3.20261 3.8056 4.27484 2.81671C5.34706 1.82782 6.58873 1.33337 7.99984 1.33337C9.41095 1.33337 10.6526 1.82782 11.7248 2.81671C12.7971 3.8056 13.3332 5.13337 13.3332 6.80004C13.3332 7.86671 12.9332 9.01393 12.1332 10.2417C11.3332 11.4695 10.1221 12.8 8.49984 14.2334C8.43317 14.2889 8.35539 14.3334 8.2665 14.3667C8.17761 14.4 8.08873 14.4167 7.99984 14.4167Z", fill: "#8C8C8C" })));
|
|
2331
|
+
const SpecialtyIcon = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" },
|
|
2332
|
+
React__default.createElement("path", { d: "M3.83333 0.5C2.94928 0.5 2.10143 0.851189 1.47631 1.47631C0.851189 2.10143 0.5 2.94928 0.5 3.83333C0.5 4.71739 0.851189 5.56523 1.47631 6.19036C2.10143 6.81548 2.94928 7.16667 3.83333 7.16667C4.71739 7.16667 5.56523 6.81548 6.19036 6.19036C6.81548 5.56523 7.16667 4.71739 7.16667 3.83333C7.16667 2.94928 6.81548 2.10143 6.19036 1.47631C5.56523 0.851189 4.71739 0.5 3.83333 0.5V0.5ZM10.5 0.5C9.57917 0.5 8.83333 1.24583 8.83333 2.16667V5.5C8.83333 6.42083 9.57917 7.16667 10.5 7.16667H13.8333C14.7542 7.16667 15.5 6.42083 15.5 5.5V2.16667C15.5 1.24583 14.7542 0.5 13.8333 0.5H10.5ZM3.83333 8.83333C2.94928 8.83333 2.10143 9.18452 1.47631 9.80964C0.851189 10.4348 0.5 11.2826 0.5 12.1667C0.5 13.0507 0.851189 13.8986 1.47631 14.5237C2.10143 15.1488 2.94928 15.5 3.83333 15.5C4.71739 15.5 5.56523 15.1488 6.19036 14.5237C6.81548 13.8986 7.16667 13.0507 7.16667 12.1667C7.16667 11.2826 6.81548 10.4348 6.19036 9.80964C5.56523 9.18452 4.71739 8.83333 3.83333 8.83333V8.83333ZM12.1667 8.83333C11.2826 8.83333 10.4348 9.18452 9.80964 9.80964C9.18452 10.4348 8.83333 11.2826 8.83333 12.1667C8.83333 13.0507 9.18452 13.8986 9.80964 14.5237C10.4348 15.1488 11.2826 15.5 12.1667 15.5C13.0507 15.5 13.8986 15.1488 14.5237 14.5237C15.1488 13.8986 15.5 13.0507 15.5 12.1667C15.5 11.2826 15.1488 10.4348 14.5237 9.80964C13.8986 9.18452 13.0507 8.83333 12.1667 8.83333V8.83333Z", fill: "#9AA2AC" })));
|
|
2333
|
+
|
|
2334
|
+
const SearchSpecialty = ({ state, isMobile, debouncedFetchSearchResults, selectedLocation, onSpecialtyClick, dispatch, }) => {
|
|
2335
|
+
var _a;
|
|
2336
|
+
const { t, locale } = useTranslations();
|
|
2337
|
+
const inputSpecialtyWrapperRef = useRef(null);
|
|
2338
|
+
const slugs = useMemo(() => LOCALIZED_SLUGS[locale], [locale]);
|
|
2339
|
+
const styleSpecialties = useMemo(() => {
|
|
2340
|
+
return {
|
|
2341
|
+
wrapper: {
|
|
2342
|
+
'&:after': {
|
|
2343
|
+
content: '""',
|
|
2344
|
+
width: '1px',
|
|
2345
|
+
height: '20px',
|
|
2346
|
+
backgroundColor: '#E4E8EC',
|
|
2347
|
+
position: 'absolute',
|
|
2348
|
+
right: 0,
|
|
2349
|
+
top: '13px',
|
|
2350
|
+
},
|
|
2351
|
+
},
|
|
2352
|
+
input: {
|
|
2353
|
+
border: isMobile ? 'border: 1px solid #d9d9d9' : 'none',
|
|
2354
|
+
height: isMobile ? '40px' : '46px !important',
|
|
2355
|
+
paddingRight: '30px',
|
|
2356
|
+
'&:focus': {
|
|
2357
|
+
boxShadow: isMobile ? 'box-shadow: 0px 0px 0px 2px #91caff' : 'none',
|
|
2358
|
+
},
|
|
2359
|
+
},
|
|
2360
|
+
rightSection: {
|
|
2361
|
+
width: '30px',
|
|
2362
|
+
svg: {
|
|
2363
|
+
fontSize: '20px',
|
|
2364
|
+
},
|
|
2365
|
+
},
|
|
2366
|
+
};
|
|
2367
|
+
}, [isMobile]);
|
|
2368
|
+
const handleSearchSpecialtyInputChange = useCallback(function handleSearchSpecialtyInputChange(value) {
|
|
2369
|
+
// dispatch({ type: ActionTypes.ChangeInputLocation, payload: value })
|
|
2370
|
+
// if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale]) {
|
|
2371
|
+
// debouncedFetchSearchResults(value.trim())
|
|
2372
|
+
// } else {
|
|
2373
|
+
// debouncedFetchSearchResults.cancel()
|
|
2374
|
+
// dispatch({ type: ActionTypes.DisplayInitialCities })
|
|
2375
|
+
// }
|
|
2376
|
+
console.log(value);
|
|
2377
|
+
}, [debouncedFetchSearchResults, dispatch]);
|
|
2378
|
+
useOutsideClick(inputSpecialtyWrapperRef, () => {
|
|
2379
|
+
dispatch({ type: ActionTypes.ClickOutsideInputSpecialty });
|
|
2380
|
+
});
|
|
2381
|
+
return (React__default.createElement(StyleSearchSpecialtyWrapper, { ref: inputSpecialtyWrapperRef },
|
|
2382
|
+
React__default.createElement(Input$1.Wrapper, null,
|
|
2383
|
+
React__default.createElement(Input$1, { 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.createElement(ChevronDown, null), styles: styleSpecialties, onFocus: () => dispatch({ type: ActionTypes.FocusInputSpecialty }), onChange: (event) => {
|
|
2384
|
+
handleSearchSpecialtyInputChange(event.target.value);
|
|
2385
|
+
} })),
|
|
2386
|
+
state.focused === 'specialty' && (React__default.createElement(StyleResultWrapper$1, null,
|
|
2387
|
+
React__default.createElement(StyledSpecialtyItem, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
|
|
2388
|
+
if (onSpecialtyClick) {
|
|
2389
|
+
onSpecialtyClick({
|
|
2390
|
+
name: t('booking.searchBar.allSpecialties'),
|
|
2391
|
+
id: -1,
|
|
2392
|
+
thumbnail: '',
|
|
2393
|
+
total_doctor: 0,
|
|
2394
|
+
slug: slugs.SPECIALTIES,
|
|
2395
|
+
});
|
|
2396
|
+
}
|
|
2397
|
+
} },
|
|
2398
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2399
|
+
React__default.createElement(SpecialtyIcon, null)),
|
|
2400
|
+
React__default.createElement(Text, { size: "md" }, t('booking.searchBar.allSpecialties'))),
|
|
2401
|
+
state.allSpecialties.map((specialty) => (React__default.createElement(StyledSpecialtyItem, { key: specialty.id, onClick: (evt) => {
|
|
2402
|
+
evt.nativeEvent.stopImmediatePropagation();
|
|
2403
|
+
if (onSpecialtyClick) {
|
|
2404
|
+
onSpecialtyClick(Object.assign(Object.assign({}, specialty), { total_doctor: 0 }));
|
|
2405
|
+
}
|
|
2406
|
+
}, role: "button", tabIndex: 0, "aria-label": `Select ${specialty.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === specialty.id },
|
|
2407
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2408
|
+
React__default.createElement("img", { src: specialty.thumbnail, alt: specialty.name })),
|
|
2409
|
+
React__default.createElement(Text, { size: "md" }, specialty.name))))))));
|
|
2410
|
+
};
|
|
2411
|
+
|
|
2412
|
+
const SearchInputs = ({ state, type, isMobile, isLoading, initalSearchValue, typeInformation, debouncedFetchSearchResults, trackingAttributes, hideSpecialtySelection = false, clientSlug = '', focusSearchInput, onSearch, onEnterSearch, dispatch, }) => {
|
|
2413
|
+
var _a;
|
|
2414
|
+
const { t } = useTranslations();
|
|
2415
|
+
const inputSearchWrapperRef = useRef(null);
|
|
2416
|
+
const gaAttributes = useMemo(() => {
|
|
2417
|
+
if (trackingAttributes) {
|
|
2418
|
+
return {
|
|
2419
|
+
'data-event-category': trackingAttributes.dataEventCategory,
|
|
2420
|
+
'data-event-action': trackingAttributes.dataEventAction,
|
|
2421
|
+
'data-event-label': trackingAttributes.dataEventLabel,
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
else {
|
|
2425
|
+
return {};
|
|
2426
|
+
}
|
|
2427
|
+
}, [trackingAttributes]);
|
|
2428
|
+
const placeholderSearch = useMemo(() => {
|
|
2429
|
+
if (type === 'doctor') {
|
|
2430
|
+
return t('booking.searchBar.placeholder.doctor');
|
|
2431
|
+
}
|
|
2432
|
+
if (type === 'service') {
|
|
2433
|
+
return t('booking.searchBar.placeholder.service');
|
|
2434
|
+
}
|
|
2435
|
+
if (type === 'hospital') {
|
|
2436
|
+
return t('booking.searchBar.placeholder.hospital');
|
|
2437
|
+
}
|
|
2438
|
+
if (type === 'specialty') {
|
|
2439
|
+
return t('booking.searchBar.placeholder.specialty');
|
|
2440
|
+
}
|
|
2441
|
+
return '';
|
|
2442
|
+
}, [type]);
|
|
2443
|
+
const styleInputWrapper = useMemo(() => {
|
|
2444
|
+
return {
|
|
2445
|
+
root: {
|
|
2446
|
+
flex: 1,
|
|
2447
|
+
'&.hide-specialty-selection': {
|
|
2448
|
+
'.mantine-Input-rightSection': {
|
|
2449
|
+
display: 'none',
|
|
2450
|
+
},
|
|
2451
|
+
input: {
|
|
2452
|
+
paddingLeft: '48px',
|
|
2453
|
+
},
|
|
2454
|
+
'.mantine-Input-icon': {
|
|
2455
|
+
left: '0',
|
|
2456
|
+
},
|
|
2457
|
+
},
|
|
2458
|
+
},
|
|
2459
|
+
};
|
|
2460
|
+
}, []);
|
|
2461
|
+
const styleInput = useMemo(() => {
|
|
2462
|
+
return {
|
|
2463
|
+
icon: {
|
|
2464
|
+
left: '165px',
|
|
2465
|
+
},
|
|
2466
|
+
input: {
|
|
2467
|
+
color: '#262626',
|
|
2468
|
+
'&[data-with-icon="true"]': {
|
|
2469
|
+
paddingLeft: '205px',
|
|
2470
|
+
paddingRight: '16px',
|
|
2471
|
+
},
|
|
2472
|
+
},
|
|
2473
|
+
rightSection: {
|
|
2474
|
+
left: 0,
|
|
2475
|
+
width: '165px',
|
|
2476
|
+
padding: '1px',
|
|
2477
|
+
},
|
|
2478
|
+
};
|
|
2479
|
+
}, []);
|
|
2480
|
+
const styleInputSpecialties = useMemo(() => {
|
|
2481
|
+
return {
|
|
2482
|
+
input: {
|
|
2483
|
+
color: '#262626',
|
|
2484
|
+
},
|
|
2485
|
+
};
|
|
2486
|
+
}, []);
|
|
2487
|
+
useOutsideClick(inputSearchWrapperRef, () => {
|
|
2488
|
+
dispatch({ type: ActionTypes.ClickOutsideInputSearch });
|
|
2489
|
+
});
|
|
2490
|
+
const handleSearchInputChange = useCallback(function handleSearchInputChange(value) {
|
|
2491
|
+
dispatch({ type: ActionTypes.ChangeInputSearch, payload: value });
|
|
2492
|
+
if (typeof onSearch === 'function') {
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] ||
|
|
2496
|
+
initalSearchValue ||
|
|
2497
|
+
value.trim().length === 0) {
|
|
2498
|
+
debouncedFetchSearchResults(value.trim(), state, type, clientSlug);
|
|
2499
|
+
}
|
|
2500
|
+
else {
|
|
2501
|
+
debouncedFetchSearchResults.cancel();
|
|
2502
|
+
dispatch({ type: ActionTypes.DisplayInitialSearchResults });
|
|
2503
|
+
}
|
|
2504
|
+
}, [dispatch, state, type]);
|
|
2505
|
+
const handleSpecialtyClick = useCallback(function handleSpecialtyClick(specialty) {
|
|
2506
|
+
dispatch({ type: ActionTypes.SelectSpecialty, payload: specialty });
|
|
2507
|
+
focusSearchInput();
|
|
2508
|
+
}, [dispatch]);
|
|
2509
|
+
const inputOnKeyDown = useCallback((e) => {
|
|
2510
|
+
if (e.keyCode === 13) {
|
|
2511
|
+
e.stopPropagation();
|
|
2512
|
+
e.preventDefault();
|
|
2513
|
+
onEnterSearch && onEnterSearch();
|
|
2514
|
+
}
|
|
2515
|
+
}, [onEnterSearch]);
|
|
2516
|
+
return (React__default.createElement(StyleSearchInputsWrapper, { ref: inputSearchWrapperRef }, type === 'specialty' ? (React__default.createElement(Input$1.Wrapper, { styles: styleInputWrapper },
|
|
2517
|
+
React__default.createElement(Input$1, { icon: React__default.createElement(Search, null), size: isMobile ? 'md' : 'lg', placeholder: placeholderSearch, styles: styleInputSpecialties, value: state.searchKeywords, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearchSpecialty }), onChange: (event) => {
|
|
2518
|
+
handleSearchInputChange(event.target.value);
|
|
2519
|
+
}, onKeyDown: inputOnKeyDown }))) : (React__default.createElement(React__default.Fragment, null,
|
|
2520
|
+
type === 'service' ? (React__default.createElement(Input$1.Wrapper, { styles: styleInputWrapper },
|
|
2521
|
+
React__default.createElement(Input$1, { icon: React__default.createElement(Search, null), size: isMobile ? 'md' : 'lg', name: "search-results", placeholder: placeholderSearch, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), value: state.searchKeywords, onChange: (event) => {
|
|
2522
|
+
handleSearchInputChange(event.target.value);
|
|
2523
|
+
}, onKeyDown: inputOnKeyDown }))) : (React__default.createElement(React__default.Fragment, null, isMobile && !hideSpecialtySelection ? (React__default.createElement(React__default.Fragment, null,
|
|
2524
|
+
React__default.createElement(SearchSpecialty, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchSearchResults: debouncedFetchSearchResults, onSpecialtyClick: handleSpecialtyClick }),
|
|
2525
|
+
React__default.createElement(Input$1.Wrapper, { styles: styleInputWrapper },
|
|
2526
|
+
React__default.createElement(Input$1, { icon: React__default.createElement(Search, null), size: "md", placeholder: placeholderSearch, value: state.searchKeywords, name: "search-results", onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), onChange: (event) => {
|
|
2527
|
+
handleSearchInputChange(event.target.value);
|
|
2528
|
+
}, onKeyDown: inputOnKeyDown })))) : (React__default.createElement(Input$1.Wrapper, { styles: styleInputWrapper, className: hideSpecialtySelection ? 'hide-specialty-selection' : '' },
|
|
2529
|
+
React__default.createElement(Input$1, Object.assign({ icon: React__default.createElement(Search, null), size: "lg", placeholder: placeholderSearch, styles: styleInput, name: "search-results", autoComplete: "off", value: state.searchKeywords, onChange: (event) => {
|
|
2530
|
+
handleSearchInputChange(event.target.value);
|
|
2531
|
+
}, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), onKeyDown: inputOnKeyDown }, gaAttributes, { rightSection: hideSpecialtySelection ? (React__default.createElement(React__default.Fragment, null)) : (React__default.createElement(SearchSpecialty, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchSearchResults: debouncedFetchSearchResults, onSpecialtyClick: handleSpecialtyClick })) })))))),
|
|
2532
|
+
state.focused === 'search' && (React__default.createElement(StyleResultWrapper$2, null,
|
|
2533
|
+
React__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 })))))));
|
|
2534
|
+
};
|
|
2535
|
+
|
|
2536
|
+
const StyleSearchLocationWrapper = styled.div `
|
|
2537
|
+
position: relative;
|
|
2538
|
+
|
|
2539
|
+
${MediaQueries.mbDown} {
|
|
2540
|
+
width: 100%;
|
|
2541
|
+
display: flex;
|
|
2542
|
+
flex-direction: column;
|
|
2543
|
+
gap: 12px;
|
|
2544
|
+
}
|
|
2545
|
+
`;
|
|
2546
|
+
const StyleResultWrapper = styled.div `
|
|
2547
|
+
position: absolute;
|
|
2548
|
+
top: calc(100% + 2px);
|
|
2549
|
+
width: 100%;
|
|
2550
|
+
border-radius: 4px;
|
|
2551
|
+
background: ${theme.colors.white};
|
|
2552
|
+
box-shadow: 0px 8px 40px 0px rgba(0, 0, 0, 0.1);
|
|
2553
|
+
z-index: 10;
|
|
2554
|
+
|
|
2555
|
+
${MediaQueries.mbDown} {
|
|
2556
|
+
width: calc(100% + 64px);
|
|
2557
|
+
left: -32px;
|
|
2558
|
+
}
|
|
2559
|
+
`;
|
|
2560
|
+
const StyledLocationItem = styled.li `
|
|
2561
|
+
position: relative;
|
|
2562
|
+
cursor: pointer;
|
|
2563
|
+
padding: 12px 18px;
|
|
2564
|
+
display: flex;
|
|
2565
|
+
align-items: center;
|
|
2566
|
+
gap: 14px;
|
|
2567
|
+
overflow: hidden;
|
|
2568
|
+
|
|
2569
|
+
${({ isSelected }) => isSelected &&
|
|
2570
|
+
`
|
|
2571
|
+
&::after {
|
|
2572
|
+
content: ${checkMarkIconUrl};
|
|
2573
|
+
top: 50%;
|
|
2574
|
+
right: 18px;
|
|
2575
|
+
position: absolute;
|
|
2576
|
+
transform: translateY(-50%);
|
|
2577
|
+
}
|
|
2578
|
+
`}
|
|
2579
|
+
|
|
2580
|
+
& + li::before {
|
|
2581
|
+
content: '';
|
|
2582
|
+
position: absolute;
|
|
2583
|
+
left: 18px;
|
|
2584
|
+
right: 18px;
|
|
2585
|
+
top: 0;
|
|
2586
|
+
height: 1px;
|
|
2587
|
+
background-color: ${theme.colors.neutral100};
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
&:not([data-is-denied='true']):hover {
|
|
2591
|
+
background-color: ${theme.colors.neutral50};
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
&:last-child:hover {
|
|
2595
|
+
border-bottom-right-radius: 6px;
|
|
2596
|
+
border-bottom-left-radius: 6px;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
&:first-child:hover {
|
|
2600
|
+
border-top-right-radius: 6px;
|
|
2601
|
+
border-top-left-radius: 6px;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
&[data-is-denied='true'] {
|
|
2605
|
+
cursor: not-allowed;
|
|
2606
|
+
}
|
|
2607
|
+
`;
|
|
2608
|
+
const StyledPinIcon = styled(PinIcon) `
|
|
2609
|
+
width: 12px;
|
|
2610
|
+
height: 18px;
|
|
2611
|
+
flex: 0 0 12px;
|
|
2612
|
+
`;
|
|
2613
|
+
|
|
2614
|
+
const SearchLocation = ({ state, isMobile, debouncedFetchCitiesByKeyword, selectedLocation, trackingAttributes, onLocationClick, dispatch, }) => {
|
|
2615
|
+
const { t, locale } = useTranslations();
|
|
2616
|
+
const inputLocationWrapperRef = useRef(null);
|
|
2617
|
+
const gaAttributes = useMemo(() => {
|
|
2618
|
+
if (trackingAttributes) {
|
|
2619
|
+
return {
|
|
2620
|
+
'data-event-category': trackingAttributes.dataEventCategory,
|
|
2621
|
+
'data-event-action': trackingAttributes.dataEventAction,
|
|
2622
|
+
'data-event-label': trackingAttributes.dataEventLabel,
|
|
2623
|
+
};
|
|
2624
|
+
}
|
|
2625
|
+
else {
|
|
2626
|
+
return {};
|
|
2627
|
+
}
|
|
2628
|
+
}, [trackingAttributes]);
|
|
2629
|
+
const handleSearchLocationInputChange = useCallback(function handleSearchLocationInputChange(value) {
|
|
2630
|
+
dispatch({ type: ActionTypes.ChangeInputLocation, payload: value });
|
|
2631
|
+
if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale]) {
|
|
2632
|
+
debouncedFetchCitiesByKeyword(value.trim());
|
|
2633
|
+
}
|
|
2634
|
+
else {
|
|
2635
|
+
debouncedFetchCitiesByKeyword.cancel();
|
|
2636
|
+
dispatch({ type: ActionTypes.DisplayInitialCities });
|
|
2637
|
+
}
|
|
2638
|
+
}, [debouncedFetchCitiesByKeyword, dispatch]);
|
|
2639
|
+
useOutsideClick(inputLocationWrapperRef, () => {
|
|
2640
|
+
dispatch({ type: ActionTypes.ClickOutsideInputLocation });
|
|
2641
|
+
});
|
|
2642
|
+
return (React__default.createElement(StyleSearchLocationWrapper, { ref: inputLocationWrapperRef },
|
|
2643
|
+
React__default.createElement(Input$1.Wrapper, null,
|
|
2644
|
+
React__default.createElement(Input$1, Object.assign({ size: isMobile ? 'md' : 'lg', placeholder: "Search location", value: state.searchLocationKeywords, onFocus: () => dispatch({ type: ActionTypes.FocusInputLocation }), onChange: (event) => {
|
|
2645
|
+
handleSearchLocationInputChange(event.target.value);
|
|
2646
|
+
} }, gaAttributes))),
|
|
2647
|
+
state.focused === 'location' && (React__default.createElement(StyleResultWrapper, null,
|
|
2648
|
+
React__default.createElement(StyledLocationItem, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
|
|
2649
|
+
var _a;
|
|
2650
|
+
if (onLocationClick) {
|
|
2651
|
+
onLocationClick({
|
|
2652
|
+
name: t('booking.searchBar.allLocations'),
|
|
2653
|
+
id: ID_OPTION_ALL_LOCATION,
|
|
2654
|
+
slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
|
|
2655
|
+
});
|
|
2656
|
+
}
|
|
2657
|
+
} },
|
|
2658
|
+
React__default.createElement(StyledPinIcon, { color: theme.colors.neutral400 }),
|
|
2659
|
+
React__default.createElement(Text, { size: "md" }, t('booking.searchBar.allLocations'))),
|
|
2660
|
+
state.cities.map((city) => (React__default.createElement(StyledLocationItem, { key: city.id, onClick: (evt) => {
|
|
2661
|
+
evt.nativeEvent.stopImmediatePropagation();
|
|
2662
|
+
if (onLocationClick) {
|
|
2663
|
+
onLocationClick(city);
|
|
2664
|
+
}
|
|
2665
|
+
}, role: "button", tabIndex: 0, "aria-label": `Select ${city.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === city.id },
|
|
2666
|
+
React__default.createElement(StyledPinIcon, { color: theme.colors.neutral400 }),
|
|
2667
|
+
React__default.createElement(Text, { size: "md" }, city.name))))))));
|
|
2668
|
+
};
|
|
2669
|
+
|
|
2670
|
+
const StyleSpecialtiesWrapper = styled.div `
|
|
2671
|
+
display: flex;
|
|
2672
|
+
flex-wrap: wrap;
|
|
2673
|
+
row-gap: 8px;
|
|
2674
|
+
column-gap: 20px;
|
|
2675
|
+
${MediaQueries.mbDown} {
|
|
2676
|
+
margin-top: 12px;
|
|
2677
|
+
}
|
|
2678
|
+
`;
|
|
2679
|
+
const StyleSpecialtyItem = styled.div `
|
|
2680
|
+
display: flex;
|
|
2681
|
+
align-items: center;
|
|
2682
|
+
border-radius: 8px;
|
|
2683
|
+
border: 1px solid ${theme.colors.neutral100};
|
|
2684
|
+
background: ${theme.colors.white};
|
|
2685
|
+
padding: 8px 12px 8px 8px;
|
|
2686
|
+
flex: 0 0 calc(33.3% - 13px);
|
|
2687
|
+
gap: 12px;
|
|
2688
|
+
cursor: pointer;
|
|
2689
|
+
|
|
2690
|
+
&:hover {
|
|
2691
|
+
background: ${theme.colors.blue50};
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2694
|
+
${MediaQueries.tdDown} {
|
|
2695
|
+
flex: 0 0 calc(50% - 10px);
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
${MediaQueries.mbDown} {
|
|
2699
|
+
flex: 0 0 100%;
|
|
2700
|
+
border: none;
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
.image-item {
|
|
2704
|
+
display: flex;
|
|
2705
|
+
align-items: center;
|
|
2706
|
+
width: 40px;
|
|
2707
|
+
height: 40px;
|
|
2708
|
+
|
|
2709
|
+
img {
|
|
2710
|
+
width: 100%;
|
|
2711
|
+
object-fit: cover;
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
.infor {
|
|
2716
|
+
flex: 1;
|
|
2717
|
+
.title {
|
|
2718
|
+
color: ${theme.colors.gray800};
|
|
2719
|
+
font-size: 14px;
|
|
2720
|
+
font-style: normal;
|
|
2721
|
+
font-weight: 400;
|
|
2722
|
+
line-height: 22px;
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
.description {
|
|
2726
|
+
color: ${theme.colors.gray600};
|
|
2727
|
+
font-size: 12px;
|
|
2728
|
+
font-weight: 400;
|
|
2729
|
+
line-height: 18px;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
`;
|
|
2733
|
+
const StyleDivider = styled(Divider) `
|
|
2734
|
+
margin: 24px 0 !important;
|
|
2735
|
+
`;
|
|
2736
|
+
const StyleShowMore = styled.div `
|
|
2737
|
+
display: flex;
|
|
2738
|
+
justify-content: center;
|
|
2739
|
+
margin-top: 24px;
|
|
2740
|
+
.show-more {
|
|
2741
|
+
border-radius: 4px;
|
|
2742
|
+
border: 1px solid ${theme.colors.neutral200};
|
|
2743
|
+
padding: 12px 16px;
|
|
2744
|
+
cursor: pointer;
|
|
2745
|
+
display: inline-block;
|
|
2746
|
+
color: ${theme.colors.gray800};
|
|
2747
|
+
font-size: 16px;
|
|
2748
|
+
font-weight: 600;
|
|
2749
|
+
line-height: 24px;
|
|
2750
|
+
|
|
2751
|
+
${MediaQueries.mbDown} {
|
|
2752
|
+
width: 100%;
|
|
2753
|
+
text-align: center;
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
`;
|
|
2757
|
+
|
|
2758
|
+
const SearchResultSpecialties = ({ state, isMobile, specialties, isLoading, dispatch, }) => {
|
|
2759
|
+
const { t, locale } = useTranslations();
|
|
2760
|
+
const { selectedLocation } = state;
|
|
2761
|
+
const slugs = useMemo(() => LOCALIZED_SLUGS[locale], [locale]);
|
|
2762
|
+
const handleOnClick = (specialtySlug) => {
|
|
2763
|
+
let url = '';
|
|
2764
|
+
if (specialtySlug === SLUG_VACIN_ID) {
|
|
2765
|
+
url = `/${selectedLocation.slug}/${slugs.HOSPITAL}/${CLIENT_KEY.GSK}/`;
|
|
2766
|
+
dispatch({ type: ActionTypes.ClickOutsideInputSearchSpecialty });
|
|
2767
|
+
}
|
|
2768
|
+
else {
|
|
2769
|
+
url = `/${selectedLocation.slug}/${slugs.DOCTOR}/${specialtySlug}`;
|
|
2770
|
+
}
|
|
2771
|
+
dispatch({ type: ActionTypes.NavigateTo, payload: url });
|
|
2772
|
+
};
|
|
2773
|
+
const handleShowMore = () => {
|
|
2774
|
+
const url = `/${slugs.SPECIALTIES}`;
|
|
2775
|
+
dispatch({ type: ActionTypes.NavigateTo, payload: url });
|
|
2776
|
+
};
|
|
2777
|
+
const showSeeMore = useMemo(() => {
|
|
2778
|
+
return (specialties.length >= 9 ||
|
|
2779
|
+
state.searchKeywords.trim().length <=
|
|
2780
|
+
SEARCH_KEYWORD_MIN_LENGTH[state.locale]);
|
|
2781
|
+
}, [state.searchKeywords, specialties]);
|
|
2782
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
2783
|
+
!isMobile && React__default.createElement(StyleDivider, { color: "#E4E8EC" }),
|
|
2784
|
+
React__default.createElement(StyleSpecialtiesWrapper, null,
|
|
2785
|
+
specialties.length > 0 && !isLoading && (React__default.createElement(React__default.Fragment, null, specialties.map((specialty, index) => {
|
|
2786
|
+
if (index >= 9) {
|
|
2787
|
+
return React__default.createElement(React__default.Fragment, null);
|
|
2788
|
+
}
|
|
2789
|
+
return (React__default.createElement(StyleSpecialtyItem, { key: specialty.id, onClick: () => handleOnClick(specialty.slug) },
|
|
2790
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2791
|
+
React__default.createElement("img", { src: specialty.thumbnail, alt: specialty.name })),
|
|
2792
|
+
React__default.createElement("div", { className: "infor" },
|
|
2793
|
+
React__default.createElement("div", { className: "title" }, specialty.name))));
|
|
2794
|
+
}))),
|
|
2795
|
+
specialties.length === 0 && !isLoading && (React__default.createElement(Text, { size: "sm", color: theme.colors.gray400 }, t('booking.searchBar.noResults'))),
|
|
2796
|
+
isLoading &&
|
|
2797
|
+
Array(6)
|
|
2798
|
+
.fill(undefined)
|
|
2799
|
+
.map((_, i) => (React__default.createElement(StyleSpecialtyItem, { key: 'loading' + i },
|
|
2800
|
+
React__default.createElement("div", { className: "image-item" },
|
|
2801
|
+
React__default.createElement(Skeleton$1, { height: 40, animate: true })),
|
|
2802
|
+
React__default.createElement("div", { className: "infor" },
|
|
2803
|
+
React__default.createElement("div", { className: "title" },
|
|
2804
|
+
React__default.createElement(Skeleton$1, { height: 20, radius: "sm", animate: true }))))))),
|
|
2805
|
+
showSeeMore && (React__default.createElement(StyleShowMore, null,
|
|
2806
|
+
React__default.createElement("div", { className: "show-more", onClick: handleShowMore }, t('home.seeAll'))))));
|
|
2807
|
+
};
|
|
2808
|
+
|
|
2809
|
+
const StyleSearchTagWrapper = styled.div `
|
|
2810
|
+
display: flex;
|
|
2811
|
+
gap: 5px;
|
|
2812
|
+
margin-top: 16px;
|
|
2813
|
+
flex-wrap: wrap;
|
|
2814
|
+
`;
|
|
2815
|
+
const StyleTagItem = styled.div `
|
|
2816
|
+
color: ${theme.colors.gray600};
|
|
2817
|
+
font-size: 14px;
|
|
2818
|
+
font-weight: 600;
|
|
2819
|
+
line-height: 22px;
|
|
2820
|
+
padding: 4px 12px;
|
|
2821
|
+
background: ${theme.colors.white};
|
|
2822
|
+
border-radius: 32px;
|
|
2823
|
+
cursor: pointer;
|
|
2824
|
+
border: 1px solid ${theme.colors.white};
|
|
2825
|
+
margin-bottom: 5px;
|
|
2826
|
+
border-color: ${theme.colors.neutral100};
|
|
2827
|
+
background: #f7f9fc;
|
|
2828
|
+
|
|
2829
|
+
&.view-all {
|
|
2830
|
+
border-radius: 32px;
|
|
2831
|
+
border-color: ${theme.colors.blue50};
|
|
2832
|
+
background: ${theme.colors.blue50};
|
|
2833
|
+
color: ${theme.colors.blue600};
|
|
2834
|
+
|
|
2835
|
+
&:hover {
|
|
2836
|
+
border-color: ${theme.colors.blue50};
|
|
2837
|
+
background: ${theme.colors.blue50};
|
|
2838
|
+
color: ${theme.colors.blue600};
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
&:hover {
|
|
2843
|
+
border-color: ${theme.colors.neutral100};
|
|
2844
|
+
background: #f7f9fc;
|
|
2845
|
+
}
|
|
2846
|
+
`;
|
|
2847
|
+
const StyleTagLabel = styled.div `
|
|
2848
|
+
color: ${theme.colors.gray600};
|
|
2849
|
+
font-size: 14px;
|
|
2850
|
+
font-weight: 600;
|
|
2851
|
+
line-height: 22px;
|
|
2852
|
+
padding: 4px 0;
|
|
2853
|
+
background: ${theme.colors.white};
|
|
2854
|
+
border-radius: 32px;
|
|
2855
|
+
border: 1px solid ${theme.colors.white};
|
|
2856
|
+
margin-bottom: 5px;
|
|
2857
|
+
margin-right: 7px;
|
|
2858
|
+
`;
|
|
2859
|
+
|
|
2860
|
+
const SearchTag = ({ state, type, typeInformation, dispatch }) => {
|
|
2861
|
+
const { t } = useTranslations();
|
|
2862
|
+
const { selectedLocation } = state;
|
|
2863
|
+
const typeSlug = useMemo(() => typeInformation[type].slug, [typeInformation, type]);
|
|
2864
|
+
const handleViewAll = () => {
|
|
2865
|
+
const url = `/${selectedLocation.slug}/${typeSlug}`;
|
|
2866
|
+
if (url) {
|
|
2867
|
+
dispatch({ type: ActionTypes.NavigateTo, payload: url });
|
|
2868
|
+
}
|
|
2869
|
+
};
|
|
2870
|
+
const handleClickKeyword = (keyword) => {
|
|
2871
|
+
if (keyword.url) {
|
|
2872
|
+
window.location.href = keyword.url;
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
return (React__default.createElement(StyleSearchTagWrapper, null,
|
|
2876
|
+
React__default.createElement(StyleTagLabel, null, t('booking.searchBar.popularKey')),
|
|
2877
|
+
state.popularKeys.map((item) => {
|
|
2878
|
+
return (React__default.createElement(StyleTagItem, { key: item.id, onClick: () => handleClickKeyword(item) }, item.keyword));
|
|
2879
|
+
}),
|
|
2880
|
+
React__default.createElement(StyleTagItem, { className: "view-all", onClick: handleViewAll }, t('booking.searchBar.viewAll'))));
|
|
2881
|
+
};
|
|
2882
|
+
|
|
2883
|
+
const StyledTabWrapper = styled.div `
|
|
2884
|
+
background: rgba(255, 255, 255, 0.64);
|
|
2885
|
+
backdrop-filter: blur(12px);
|
|
2886
|
+
border-bottom: 1px solid ${theme.colors.neutral100};
|
|
2887
|
+
`;
|
|
2888
|
+
const StyleTabContainer = styled(Container) `
|
|
2889
|
+
padding: 0 16px;
|
|
2890
|
+
`;
|
|
2891
|
+
|
|
2892
|
+
const itemTabs = () => {
|
|
2893
|
+
const { t } = useTranslations();
|
|
2894
|
+
return [
|
|
2895
|
+
{
|
|
2896
|
+
value: 'hospital',
|
|
2897
|
+
label: t('booking.searchPopup.hospitals'),
|
|
2898
|
+
},
|
|
2899
|
+
{
|
|
2900
|
+
value: 'doctor',
|
|
2901
|
+
label: t('booking.searchPopup.doctors'),
|
|
2902
|
+
},
|
|
2903
|
+
{
|
|
2904
|
+
value: 'service',
|
|
2905
|
+
label: t('booking.searchPopup.services'),
|
|
2906
|
+
},
|
|
2907
|
+
{
|
|
2908
|
+
value: 'specialty',
|
|
2909
|
+
label: t('booking.searchPopup.specialties'),
|
|
2910
|
+
},
|
|
2911
|
+
];
|
|
2912
|
+
};
|
|
2913
|
+
const TabSearch = ({ currentTab, hideTabBookingSearch = [], isMobile, setCurrentTab, }) => {
|
|
2914
|
+
const stylesTabs = useMemo(() => {
|
|
2915
|
+
return {
|
|
2916
|
+
root: {
|
|
2917
|
+
overflowY: isMobile ? 'hidden' : 'initial',
|
|
2918
|
+
overflowX: isMobile ? 'auto' : 'initial',
|
|
2919
|
+
},
|
|
2920
|
+
tabsList: {
|
|
2921
|
+
background: 'rgba(255, 255, 255, 0)',
|
|
2922
|
+
borderBottom: 'none',
|
|
2923
|
+
flexWrap: 'nowrap',
|
|
2924
|
+
'.mantine-Tabs-tab': {
|
|
2925
|
+
'&:last-child': {
|
|
2926
|
+
'&:after': {
|
|
2927
|
+
display: 'none',
|
|
2928
|
+
},
|
|
2929
|
+
},
|
|
2930
|
+
},
|
|
2931
|
+
},
|
|
2932
|
+
tab: {
|
|
2933
|
+
padding: isMobile ? '12px 16px 12px 16px' : '15px 40px 15px 40px',
|
|
2934
|
+
borderTop: '2px solid transparent',
|
|
2935
|
+
borderBottom: 'none',
|
|
2936
|
+
margin: 0,
|
|
2937
|
+
borderRadius: 0,
|
|
2938
|
+
position: 'relative',
|
|
2939
|
+
width: 'auto',
|
|
2940
|
+
'&[data-active="true"]': {
|
|
2941
|
+
borderColor: '#2d87f3',
|
|
2942
|
+
backgroundColor: '#ffffff',
|
|
2943
|
+
'&:after': {
|
|
2944
|
+
display: 'none',
|
|
2945
|
+
},
|
|
2946
|
+
'&:before': {
|
|
2947
|
+
content: '""',
|
|
2948
|
+
width: '100%',
|
|
2949
|
+
height: '1px',
|
|
2950
|
+
position: 'absolute',
|
|
2951
|
+
backgroundColor: '#ffffff',
|
|
2952
|
+
bottom: '-1px',
|
|
2953
|
+
},
|
|
2954
|
+
},
|
|
2955
|
+
'&:hover': {
|
|
2956
|
+
borderColor: '#2d87f3',
|
|
2957
|
+
backgroundColor: '#ffffff',
|
|
2958
|
+
'&:before': {
|
|
2959
|
+
content: '""',
|
|
2960
|
+
width: '100%',
|
|
2961
|
+
height: '1px',
|
|
2962
|
+
position: 'absolute',
|
|
2963
|
+
backgroundColor: '#ffffff',
|
|
2964
|
+
bottom: '-1px',
|
|
2965
|
+
},
|
|
2966
|
+
},
|
|
2967
|
+
'&:after': {
|
|
2968
|
+
content: '""',
|
|
2969
|
+
width: '1px',
|
|
2970
|
+
height: '24px',
|
|
2971
|
+
backgroundColor: '#E4E8EC',
|
|
2972
|
+
position: 'absolute',
|
|
2973
|
+
right: '-1px',
|
|
2974
|
+
},
|
|
2975
|
+
},
|
|
2976
|
+
tabLabel: {
|
|
2977
|
+
color: '#595959',
|
|
2978
|
+
fontSize: isMobile ? '14px' : '16px',
|
|
2979
|
+
fontWeight: 600,
|
|
2980
|
+
lineHeight: isMobile ? '22px' : '24px',
|
|
2981
|
+
},
|
|
2982
|
+
};
|
|
2983
|
+
}, [isMobile]);
|
|
2984
|
+
const tabConfig = itemTabs();
|
|
2985
|
+
const activeTabs = useMemo(() => {
|
|
2986
|
+
return (tabConfig.filter((item) => !hideTabBookingSearch.includes(item.value)) ||
|
|
2987
|
+
[]);
|
|
2988
|
+
}, [hideTabBookingSearch, tabConfig]);
|
|
2989
|
+
return (React__default.createElement(StyledTabWrapper, { className: "booking-search-tab" },
|
|
2990
|
+
React__default.createElement(StyleTabContainer, null,
|
|
2991
|
+
React__default.createElement(Tabs, { value: currentTab, onTabChange: (tab) => {
|
|
2992
|
+
setCurrentTab(tab);
|
|
2993
|
+
}, styles: stylesTabs },
|
|
2994
|
+
React__default.createElement(Tabs.List, null, activeTabs.map((tab) => {
|
|
2995
|
+
return (React__default.createElement(Tabs.Tab, { value: tab.value, key: tab.value }, tab.label));
|
|
2996
|
+
}))))));
|
|
2997
|
+
};
|
|
2998
|
+
|
|
2999
|
+
var TypePopularKeySearch;
|
|
3000
|
+
(function (TypePopularKeySearch) {
|
|
3001
|
+
TypePopularKeySearch["doctor"] = "doctor";
|
|
3002
|
+
TypePopularKeySearch["service"] = "hospital_service";
|
|
3003
|
+
TypePopularKeySearch["hospital"] = "hospital_branch";
|
|
3004
|
+
})(TypePopularKeySearch || (TypePopularKeySearch = {}));
|
|
3005
|
+
|
|
3006
|
+
function useSearchBarApi({ dispatch, careApiDomain, locale = 'vi-VN', client = '', }) {
|
|
3007
|
+
const fetchCitiesApi = useCallback(function fetchCitiesApi(path, params = {}) {
|
|
3008
|
+
const url = `${careApiDomain}${path}`;
|
|
3009
|
+
dispatch({ type: ActionTypes.FetchCitiesStart });
|
|
3010
|
+
return fetch(getApiPath(url, params, locale), { method: 'GET' })
|
|
3011
|
+
.then((res) => res.json())
|
|
3012
|
+
.then((data) => {
|
|
3013
|
+
if (data._status !== 1 || !data._data) {
|
|
3014
|
+
console.log('error loading cities', data);
|
|
3015
|
+
return Promise.reject(data);
|
|
3016
|
+
}
|
|
3017
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
3018
|
+
})
|
|
3019
|
+
.finally(() => dispatch({ type: ActionTypes.FetchCitiesFinish }));
|
|
3020
|
+
}, [locale]);
|
|
3021
|
+
const fetchCitiesByLocation = useCallback(function fetchCitiesByLocation({ coordinates }) {
|
|
3022
|
+
let params = {};
|
|
3023
|
+
const moreParams = {};
|
|
3024
|
+
if (coordinates) {
|
|
3025
|
+
params = {
|
|
3026
|
+
lat: coordinates.lat,
|
|
3027
|
+
lng: coordinates.lng,
|
|
3028
|
+
};
|
|
3029
|
+
}
|
|
3030
|
+
if (locale === 'ms-MY') {
|
|
3031
|
+
moreParams.noPaging = 1;
|
|
3032
|
+
}
|
|
3033
|
+
const requests = [
|
|
3034
|
+
fetchCitiesApi(PATHS.GET_CITY_BY_IP, Object.assign(Object.assign(Object.assign({}, params), moreParams), { client: CLIENT_KEY.MSD === client ? '' : client })),
|
|
3035
|
+
];
|
|
3036
|
+
if (locale === 'zh-TW') {
|
|
3037
|
+
requests.push(fetchCitiesApi(PATHS.GET_CITIES_LIST, {
|
|
3038
|
+
noPaging: 1,
|
|
3039
|
+
client: CLIENT_KEY.MSD === client ? '' : client,
|
|
3040
|
+
}));
|
|
3041
|
+
}
|
|
3042
|
+
return Promise.all(requests)
|
|
3043
|
+
.then(([data1, data2]) => {
|
|
3044
|
+
const data = Object.assign({}, data1);
|
|
3045
|
+
if (data2) {
|
|
3046
|
+
const citiesIds = data.cities.map((c) => c.id);
|
|
3047
|
+
data.cities = data.cities.concat(data2.cities.filter((c) => !citiesIds.includes(c.id)));
|
|
3048
|
+
}
|
|
3049
|
+
dispatch({
|
|
3050
|
+
type: ActionTypes.FetchCitiesByGeoIpComplete,
|
|
3051
|
+
payload: data,
|
|
3052
|
+
});
|
|
3053
|
+
})
|
|
3054
|
+
.catch((err) => console.error('error loading cities by location', err));
|
|
3055
|
+
}, [locale, careApiDomain, dispatch]);
|
|
3056
|
+
const fetchCitiesByKeyword = useCallback(function fetchCitiesByKeyword(keyword) {
|
|
3057
|
+
return fetchCitiesApi(PATHS.GET_CITIES_LIST, {
|
|
3058
|
+
keyword,
|
|
3059
|
+
client,
|
|
3060
|
+
})
|
|
3061
|
+
.then((data) => {
|
|
3062
|
+
dispatch({
|
|
3063
|
+
type: ActionTypes.FetchCitiesByKeywordComplete,
|
|
3064
|
+
payload: data.cities,
|
|
3065
|
+
});
|
|
3066
|
+
})
|
|
3067
|
+
.catch((err) => console.error('error loading cities by keyword', err));
|
|
3068
|
+
}, [locale, careApiDomain, dispatch]);
|
|
3069
|
+
const fetchSearchResults = useCallback(function fetchSearchResults(searchKeywords, state, searchType, clientSlug, cacheResult) {
|
|
3070
|
+
const url = searchType === 'specialty'
|
|
3071
|
+
? `${careApiDomain}${PATHS.GET_SEARCH_SPECIALTY}`
|
|
3072
|
+
: `${careApiDomain}${PATHS.GET_SEARCH_V2}`;
|
|
3073
|
+
dispatch({ type: ActionTypes.FetchSearchResultsStart });
|
|
3074
|
+
const { selectedLocation, geoLocationCoordinates, selectedSpecialty } = state;
|
|
3075
|
+
let cityId = '';
|
|
3076
|
+
if (!selectedLocation) {
|
|
3077
|
+
dispatch({ type: ActionTypes.FetchSearchResultsFinish });
|
|
3078
|
+
return;
|
|
3079
|
+
}
|
|
3080
|
+
if (selectedLocation.id === ID_OPTION_ALL_LOCATION) {
|
|
3081
|
+
cityId = '';
|
|
3082
|
+
}
|
|
3083
|
+
else {
|
|
3084
|
+
cityId = selectedLocation.id;
|
|
3085
|
+
}
|
|
3086
|
+
const lat = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lat) || '';
|
|
3087
|
+
const lng = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lng) || '';
|
|
3088
|
+
const specialty_id = (selectedSpecialty === null || selectedSpecialty === void 0 ? void 0 : selectedSpecialty.id) > 0 ? selectedSpecialty === null || selectedSpecialty === void 0 ? void 0 : selectedSpecialty.id : '';
|
|
3089
|
+
const keyword = searchKeywords.trim().length > SEARCH_KEYWORD_MIN_LENGTH[locale]
|
|
3090
|
+
? searchKeywords.trim()
|
|
3091
|
+
: '';
|
|
3092
|
+
return fetch(getApiPath(url, {
|
|
3093
|
+
domain: careApiDomain,
|
|
3094
|
+
searchType: searchType || 'global',
|
|
3095
|
+
keyword: keyword,
|
|
3096
|
+
city: cityId === ID_OPTION_CURRENT_LOCATION ? '' : cityId,
|
|
3097
|
+
lat,
|
|
3098
|
+
lng,
|
|
3099
|
+
specialty_id,
|
|
3100
|
+
client_slug: CLIENT_KEY.MSD === clientSlug ? '' : clientSlug,
|
|
3101
|
+
msd: CLIENT_KEY.MSD === client ? 1 : '',
|
|
3102
|
+
}, locale), {
|
|
3103
|
+
method: 'GET',
|
|
3104
|
+
headers: {
|
|
3105
|
+
accept: 'version=2.0.0.0',
|
|
3106
|
+
},
|
|
3107
|
+
})
|
|
3108
|
+
.then((res) => res.json())
|
|
3109
|
+
.then((data) => {
|
|
3110
|
+
if (data._status !== 1 || !data._data) {
|
|
3111
|
+
return Promise.reject(data);
|
|
3112
|
+
}
|
|
3113
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
3114
|
+
})
|
|
3115
|
+
.then((results) => {
|
|
3116
|
+
let searchesResult = [];
|
|
3117
|
+
if (searchType !== 'specialty') {
|
|
3118
|
+
searchesResult = results.searches;
|
|
3119
|
+
}
|
|
3120
|
+
if (searchType === 'specialty') {
|
|
3121
|
+
if (keyword) {
|
|
3122
|
+
searchesResult = results.specialties;
|
|
3123
|
+
}
|
|
3124
|
+
else {
|
|
3125
|
+
searchesResult = results.default;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
dispatch({
|
|
3129
|
+
type: ActionTypes.FetchSearchResultsComplete,
|
|
3130
|
+
payload: {
|
|
3131
|
+
key: searchType,
|
|
3132
|
+
searches: searchesResult || [],
|
|
3133
|
+
},
|
|
3134
|
+
});
|
|
3135
|
+
if (cacheResult) {
|
|
3136
|
+
dispatch({
|
|
3137
|
+
type: ActionTypes.UpdateInitialSearchResults,
|
|
3138
|
+
payload: {
|
|
3139
|
+
key: searchType,
|
|
3140
|
+
searches: searchesResult || [],
|
|
3141
|
+
},
|
|
3142
|
+
});
|
|
3143
|
+
}
|
|
3144
|
+
})
|
|
3145
|
+
.catch((error) => {
|
|
3146
|
+
console.log('error loading search results', { url, error });
|
|
3147
|
+
})
|
|
3148
|
+
.finally(() => dispatch({ type: ActionTypes.FetchSearchResultsFinish }));
|
|
3149
|
+
}, [locale, careApiDomain, dispatch]);
|
|
3150
|
+
const fetchAllSpecialties = useCallback(function fetchSearchSpecialties() {
|
|
3151
|
+
const url = `${careApiDomain}${PATHS.GET_SEARCH_SPECIALTY}`;
|
|
3152
|
+
return fetch(getApiPath(url, {
|
|
3153
|
+
domain: careApiDomain,
|
|
3154
|
+
searchType: '',
|
|
3155
|
+
msd: CLIENT_KEY.MSD === client ? 1 : '',
|
|
3156
|
+
}, locale), {
|
|
3157
|
+
method: 'GET',
|
|
3158
|
+
headers: {
|
|
3159
|
+
accept: 'version=2.0.0.0',
|
|
3160
|
+
},
|
|
3161
|
+
})
|
|
3162
|
+
.then((res) => res.json())
|
|
3163
|
+
.then((data) => {
|
|
3164
|
+
if (data._status !== 1 || !data._data) {
|
|
3165
|
+
return Promise.reject(data);
|
|
3166
|
+
}
|
|
3167
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
3168
|
+
})
|
|
3169
|
+
.then((results) => {
|
|
3170
|
+
dispatch({
|
|
3171
|
+
type: ActionTypes.FetchAllSpecialties,
|
|
3172
|
+
payload: results.specialties || [],
|
|
3173
|
+
});
|
|
3174
|
+
})
|
|
3175
|
+
.catch((error) => {
|
|
3176
|
+
console.log('error loading search results', { url, error });
|
|
3177
|
+
});
|
|
3178
|
+
}, [locale, careApiDomain, dispatch]);
|
|
3179
|
+
const fetchPopularKeys = useCallback(function fetchPopularKeys(searchType) {
|
|
3180
|
+
const url = `${careApiDomain}${PATHS.GET_SEARCH_POPULAR_KEY}`;
|
|
3181
|
+
return fetch(getApiPath(url, {
|
|
3182
|
+
domain: careApiDomain,
|
|
3183
|
+
searchType: TypePopularKeySearch[searchType],
|
|
3184
|
+
sort_by: 'display_order',
|
|
3185
|
+
sort_order: 'asc',
|
|
3186
|
+
}, locale))
|
|
3187
|
+
.then((res) => res.json())
|
|
3188
|
+
.then((data) => {
|
|
3189
|
+
if (data._status !== 1 || !data._data) {
|
|
3190
|
+
return Promise.reject(data);
|
|
3191
|
+
}
|
|
3192
|
+
return data === null || data === void 0 ? void 0 : data._data;
|
|
3193
|
+
})
|
|
3194
|
+
.then((results) => {
|
|
3195
|
+
dispatch({
|
|
3196
|
+
type: ActionTypes.FetchPopularKeys,
|
|
3197
|
+
payload: results.popular_searches || [],
|
|
3198
|
+
});
|
|
3199
|
+
})
|
|
3200
|
+
.catch((error) => {
|
|
3201
|
+
console.log('error loading search results', { url, error });
|
|
3202
|
+
});
|
|
3203
|
+
}, [locale, careApiDomain, dispatch]);
|
|
3204
|
+
return {
|
|
3205
|
+
fetchCitiesByLocation,
|
|
3206
|
+
fetchCitiesByKeyword,
|
|
3207
|
+
fetchSearchResults,
|
|
3208
|
+
fetchAllSpecialties,
|
|
3209
|
+
fetchPopularKeys,
|
|
3210
|
+
};
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
const BookingSearchBarV2 = ({ isMobile, careApiDomain, geoLocationPermission: geoLocationPermissionFromProps, geoLocationCoordinates: geoLocationCoordinatesFromProps, initialSelectedCity: initialSelectedCityFromProps, initialSearchValue = '', initTypeSearch = 'hospital', initSpecialty, careFrontDomain = '/care', isDebug = false,
|
|
3214
|
+
// askForGeolocationPermission = false,
|
|
3215
|
+
gaTrackingSearchBar, gaTrackingLocationSearch, autoCompleteDisabled = false, inputSearchPlaceholder = '', hideTabBookingSearch = [], hideSpecialtySelection = false, hidePopularSearchKeys = false, clientSlug = '',
|
|
3216
|
+
// isOptionAllLocation = false,
|
|
3217
|
+
// hideResults = [],
|
|
3218
|
+
// isNavResultItem = true,
|
|
3219
|
+
routerPush, onGeoLocationPermissionChange,
|
|
3220
|
+
// onSearch,
|
|
3221
|
+
onChangeLocation, }) => {
|
|
3222
|
+
const { locale, t } = useTranslations();
|
|
3223
|
+
const wrapperRef = useRef(null);
|
|
3224
|
+
const inputSearchSpecialtyWrapperRef = useRef(null);
|
|
3225
|
+
const [currentTab, setCurrentTab] = useState(initTypeSearch);
|
|
3226
|
+
const { geoLocationPermission: geoLocationPermissionFromHook, geoLocationCoordinates: geoLocationCoordinatesFromHook, } = useGeolocation();
|
|
3227
|
+
const [state, dispatch] = useReducer(reducer, initialState, (s) => (Object.assign(Object.assign({}, s), { isDebug,
|
|
3228
|
+
isMobile, geoLocationPermission: geoLocationPermissionFromProps ||
|
|
3229
|
+
geoLocationPermissionFromHook ||
|
|
3230
|
+
'unset', geoLocationCoordinates: geoLocationCoordinatesFromProps ||
|
|
3231
|
+
geoLocationCoordinatesFromHook ||
|
|
3232
|
+
null, searchKeywords: initialSearchValue, initialSelectedCity: initialSelectedCityFromProps || null, selectedLocation: initialSelectedCityFromProps || s.selectedLocation || null, searchLocationKeywords: (initialSelectedCityFromProps === null || initialSelectedCityFromProps === void 0 ? void 0 : initialSelectedCityFromProps.name) || s.searchLocationKeywords, autoCompleteDisabled,
|
|
3233
|
+
inputSearchPlaceholder,
|
|
3234
|
+
locale })));
|
|
3235
|
+
const { navigateTo, focusedSpecialty,
|
|
3236
|
+
// isLoadingCities,
|
|
3237
|
+
// cities,
|
|
3238
|
+
searchKeywords, geoLocationPermission, selectedLocation, selectedSpecialty, initialSelectedCity,
|
|
3239
|
+
// defaultCity,
|
|
3240
|
+
searchResults, isLoadingSearchResults,
|
|
3241
|
+
// isMobileModalOpened,
|
|
3242
|
+
// inputSearchPlaceholder,
|
|
3243
|
+
// allSpecialties,
|
|
3244
|
+
} = state;
|
|
3245
|
+
const { fetchCitiesByLocation, fetchCitiesByKeyword, fetchSearchResults, fetchAllSpecialties, fetchPopularKeys, } = useSearchBarApi({
|
|
3246
|
+
dispatch,
|
|
3247
|
+
locale,
|
|
3248
|
+
careApiDomain,
|
|
3249
|
+
client: clientSlug,
|
|
3250
|
+
});
|
|
3251
|
+
const slugs = useMemo(() => LOCALIZED_SLUGS[locale], [locale]);
|
|
3252
|
+
const typeInformation = useMemo(() => {
|
|
3253
|
+
return {
|
|
3254
|
+
doctor: {
|
|
3255
|
+
name: t('booking.searchPopup.doctors'),
|
|
3256
|
+
icon: React__default.createElement(DoctorIcon, null),
|
|
3257
|
+
slug: slugs.DOCTOR,
|
|
3258
|
+
},
|
|
3259
|
+
service: {
|
|
3260
|
+
name: t('booking.searchPopup.services'),
|
|
3261
|
+
icon: React__default.createElement(ServiceIcon, null),
|
|
3262
|
+
slug: slugs.SERVICE,
|
|
3263
|
+
},
|
|
3264
|
+
hospital: {
|
|
3265
|
+
name: t('booking.searchPopup.hospitals'),
|
|
3266
|
+
icon: React__default.createElement(HospitalIcon, null),
|
|
3267
|
+
slug: slugs.HOSPITAL,
|
|
3268
|
+
},
|
|
3269
|
+
specialty: {
|
|
3270
|
+
name: t('booking.searchPopup.specialties'),
|
|
3271
|
+
icon: React__default.createElement(SpecialtyIcon, null),
|
|
3272
|
+
slug: slugs.SPECIALTIES,
|
|
3273
|
+
},
|
|
3274
|
+
};
|
|
3275
|
+
}, [currentTab]);
|
|
3276
|
+
const debouncedFetchCitiesByKeyword = useMemo(() => debounce(fetchCitiesByKeyword, 400), [fetchCitiesByKeyword]);
|
|
3277
|
+
const debouncedFetchSearchResults = useMemo(() => debounce(fetchSearchResults, 400), [fetchSearchResults]);
|
|
3278
|
+
const handleLocationClick = useCallback(function handleLocationClick(city) {
|
|
3279
|
+
dispatch({ type: ActionTypes.SelectLocation, payload: city });
|
|
3280
|
+
focusSearchInput();
|
|
3281
|
+
if (onChangeLocation) {
|
|
3282
|
+
onChangeLocation(city);
|
|
3283
|
+
}
|
|
3284
|
+
}, [t, dispatch]);
|
|
3285
|
+
function focusSearchInput() {
|
|
3286
|
+
var _a;
|
|
3287
|
+
if (wrapperRef.current) {
|
|
3288
|
+
(_a = wrapperRef.current
|
|
3289
|
+
.querySelector('input[name="search-results"]')) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
function onClickSearchByKeyword() {
|
|
3293
|
+
let url = '';
|
|
3294
|
+
const { slug: typeSlug } = typeInformation[currentTab];
|
|
3295
|
+
let moreParams = '';
|
|
3296
|
+
const slugClientUrl = MAPPING_CLIENT_WITH_SLUG[locale][clientSlug];
|
|
3297
|
+
if ((currentTab === 'doctor' || currentTab === 'hospital') &&
|
|
3298
|
+
state.selectedSpecialty.id > 0) {
|
|
3299
|
+
moreParams = `&specialtyId=${state.selectedSpecialty.id}`;
|
|
3300
|
+
}
|
|
3301
|
+
if (currentTab === 'specialty') {
|
|
3302
|
+
url = `/${typeSlug}`;
|
|
3303
|
+
}
|
|
3304
|
+
else {
|
|
3305
|
+
url = `/${selectedLocation.slug}/${typeSlug}`;
|
|
3306
|
+
}
|
|
3307
|
+
if (slugClientUrl) {
|
|
3308
|
+
url += `/${slugClientUrl}`;
|
|
3309
|
+
}
|
|
3310
|
+
url += `?q=${searchKeywords}${moreParams}`;
|
|
3311
|
+
if (url) {
|
|
3312
|
+
dispatch({ type: ActionTypes.NavigateTo, payload: url });
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
useOutsideClick(inputSearchSpecialtyWrapperRef, () => {
|
|
3316
|
+
dispatch({ type: ActionTypes.ClickOutsideInputSearchSpecialty });
|
|
3317
|
+
});
|
|
3318
|
+
useEffect(() => {
|
|
3319
|
+
var _a;
|
|
3320
|
+
if (geoLocationPermission !== 'denied' && !initialSelectedCity) {
|
|
3321
|
+
dispatch({
|
|
3322
|
+
type: ActionTypes.SelectLocation,
|
|
3323
|
+
payload: {
|
|
3324
|
+
name: t('booking.searchBar.allLocations'),
|
|
3325
|
+
id: ID_OPTION_ALL_LOCATION,
|
|
3326
|
+
slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
|
|
3327
|
+
},
|
|
3328
|
+
});
|
|
3329
|
+
}
|
|
3330
|
+
if (onGeoLocationPermissionChange) {
|
|
3331
|
+
onGeoLocationPermissionChange(geoLocationPermission, state.geoLocationCoordinates);
|
|
3332
|
+
}
|
|
3333
|
+
if (isMobile && geoLocationPermission === 'granted' && selectedLocation) {
|
|
3334
|
+
dispatch({ type: ActionTypes.FocusInputSearch });
|
|
3335
|
+
}
|
|
3336
|
+
fetchCitiesByLocation({ coordinates: state.geoLocationCoordinates });
|
|
3337
|
+
}, [geoLocationPermission]);
|
|
3338
|
+
useEffect(() => {
|
|
3339
|
+
const defaultSpecialty = initSpecialty
|
|
3340
|
+
? initSpecialty
|
|
3341
|
+
: {
|
|
3342
|
+
name: t('booking.searchBar.allSpecialties'),
|
|
3343
|
+
id: -1,
|
|
3344
|
+
thumbnail: '',
|
|
3345
|
+
total_doctor: 0,
|
|
3346
|
+
slug: slugs.SPECIALTIES,
|
|
3347
|
+
};
|
|
3348
|
+
if (!state.selectedSpecialty) {
|
|
3349
|
+
dispatch({
|
|
3350
|
+
type: ActionTypes.SelectSpecialty,
|
|
3351
|
+
payload: defaultSpecialty,
|
|
3352
|
+
});
|
|
3353
|
+
}
|
|
3354
|
+
}, [initSpecialty, state.selectedSpecialty]);
|
|
3355
|
+
useEffect(() => {
|
|
3356
|
+
fetchAllSpecialties();
|
|
3357
|
+
}, []);
|
|
3358
|
+
useEffect(() => {
|
|
3359
|
+
fetchPopularKeys(currentTab);
|
|
3360
|
+
}, [currentTab]);
|
|
3361
|
+
useEffect(() => {
|
|
3362
|
+
if (navigateTo) {
|
|
3363
|
+
if (routerPush) {
|
|
3364
|
+
routerPush(navigateTo);
|
|
3365
|
+
}
|
|
3366
|
+
else {
|
|
3367
|
+
window.location.href = `${careFrontDomain}${navigateTo}`;
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
}, [navigateTo]);
|
|
3371
|
+
useEffect(() => {
|
|
3372
|
+
fetchSearchResults(state.searchKeywords, state, currentTab, clientSlug, true);
|
|
3373
|
+
}, [selectedLocation, selectedSpecialty, currentTab]);
|
|
3374
|
+
return (React__default.createElement(StyledSearchBarWrapper, { ref: wrapperRef },
|
|
3375
|
+
React__default.createElement(TabSearch, { currentTab: currentTab, setCurrentTab: setCurrentTab, isMobile: isMobile, hideTabBookingSearch: hideTabBookingSearch }),
|
|
3376
|
+
React__default.createElement(StyleWrapperContainer, { className: "booking-search-container" },
|
|
3377
|
+
React__default.createElement(StyleSearchInputContainer, null,
|
|
3378
|
+
React__default.createElement(StyleSearchContent, null,
|
|
3379
|
+
React__default.createElement("div", { ref: inputSearchSpecialtyWrapperRef },
|
|
3380
|
+
React__default.createElement(Flex, { gap: "12px", justify: "space-between", align: "center", direction: isMobile ? 'column' : 'row', className: "flex-search-input" },
|
|
3381
|
+
currentTab !== 'specialty' && (React__default.createElement(SearchLocation, { state: state, isMobile: isMobile, dispatch: dispatch, debouncedFetchCitiesByKeyword: debouncedFetchCitiesByKeyword, selectedLocation: selectedLocation, onLocationClick: handleLocationClick, trackingAttributes: gaTrackingLocationSearch })),
|
|
3382
|
+
React__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 }),
|
|
3383
|
+
React__default.createElement(Button, { size: isMobile ? 'md' : 'lg', color: "#2D87F3", fullWidth: isMobile, variant: "filled", onClick: onClickSearchByKeyword, styles: {
|
|
3384
|
+
root: {
|
|
3385
|
+
height: isMobile ? '40px' : '48px',
|
|
3386
|
+
},
|
|
3387
|
+
} }, t('booking.searchBar.searchButton'))),
|
|
3388
|
+
!hidePopularSearchKeys &&
|
|
3389
|
+
currentTab !== 'specialty' &&
|
|
3390
|
+
state.popularKeys.length > 0 && (React__default.createElement(SearchTag, { type: currentTab, state: state, typeInformation: typeInformation, dispatch: dispatch })),
|
|
3391
|
+
currentTab === 'specialty' && focusedSpecialty === 'search' && (React__default.createElement(SearchResultSpecialties, { state: state, isMobile: isMobile, dispatch: dispatch, specialties: (searchResults === null || searchResults === void 0 ? void 0 : searchResults.specialty) || [], isLoading: isLoadingSearchResults }))))))));
|
|
3392
|
+
};
|
|
3393
|
+
|
|
3394
|
+
const StyledTextDivider = styled.div `
|
|
3395
|
+
background-color: var(--neutral50);
|
|
3396
|
+
padding: 12px 0;
|
|
3397
|
+
box-shadow: inset 0px 1px 0px #e4e8ec;
|
|
3398
|
+
|
|
3399
|
+
> * {
|
|
3400
|
+
display: grid;
|
|
3401
|
+
grid-template-columns: 32px 1fr;
|
|
3402
|
+
align-content: center;
|
|
3403
|
+
|
|
3404
|
+
p {
|
|
3405
|
+
font-weight: 600;
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
.icon-wrapper {
|
|
3410
|
+
display: flex;
|
|
3411
|
+
align-items: center;
|
|
3412
|
+
}
|
|
3413
|
+
`;
|
|
3414
|
+
const TextDivider = ({ children, icon, className, style }) => (React__default.createElement(StyledTextDivider, { style: style, className: className },
|
|
3415
|
+
React__default.createElement(Container, null,
|
|
3416
|
+
React__default.createElement("div", { className: "icon-wrapper" }, icon),
|
|
3417
|
+
React__default.createElement(Text, { size: "c1", color: "var(--neutral800)" }, children))));
|
|
3418
|
+
|
|
3419
|
+
var RedirectType;
|
|
3420
|
+
(function (RedirectType) {
|
|
3421
|
+
RedirectType[RedirectType["SPECIALTY"] = 1] = "SPECIALTY";
|
|
3422
|
+
RedirectType[RedirectType["DOCTOR"] = 2] = "DOCTOR";
|
|
3423
|
+
RedirectType[RedirectType["CLINIC"] = 3] = "CLINIC";
|
|
3424
|
+
RedirectType[RedirectType["SERVICE"] = 4] = "SERVICE";
|
|
3425
|
+
})(RedirectType || (RedirectType = {}));
|
|
3426
|
+
|
|
3427
|
+
var types = /*#__PURE__*/Object.freeze({
|
|
3428
|
+
__proto__: null,
|
|
3429
|
+
get RedirectType () { return RedirectType; }
|
|
3430
|
+
});
|
|
3431
|
+
|
|
3432
|
+
export { BookingSearchBar as B, TextDivider as T, BookingSearchBarV2 as a, types as t };
|