@sonordev/site-kit 5.3.2 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +16 -6
- package/README.md +26 -7
- package/agent-manifest.json +11 -10
- package/dist/AnalyticsProvider-KFXAH4GR.mjs +11 -0
- package/dist/{AnalyticsProvider-2XK54UZW.mjs.map → AnalyticsProvider-KFXAH4GR.mjs.map} +1 -1
- package/dist/AnalyticsProvider-WDDW3IJW.js +32 -0
- package/dist/{AnalyticsProvider-PM7SOGOS.js.map → AnalyticsProvider-WDDW3IJW.js.map} +1 -1
- package/dist/{BlogViewTracker-3BIUF5TI.js → BlogViewTracker-D4DIEP4Q.js} +6 -6
- package/dist/{BlogViewTracker-3BIUF5TI.js.map → BlogViewTracker-D4DIEP4Q.js.map} +1 -1
- package/dist/{BlogViewTracker-KFUDRDQK.mjs → BlogViewTracker-ZVEGGH3Y.mjs} +5 -5
- package/dist/{BlogViewTracker-KFUDRDQK.mjs.map → BlogViewTracker-ZVEGGH3Y.mjs.map} +1 -1
- package/dist/ChatWidget-2ZYPYIMQ.js +22 -0
- package/dist/{ChatWidget-7BYSGNO2.js.map → ChatWidget-2ZYPYIMQ.js.map} +1 -1
- package/dist/ChatWidget-FYCCLMQE.mjs +13 -0
- package/dist/{ChatWidget-4PHZHGG5.mjs.map → ChatWidget-FYCCLMQE.mjs.map} +1 -1
- package/dist/EngageWidget-6HUZYOY7.mjs +11 -0
- package/dist/{EngageWidget-D6M6QWEC.mjs.map → EngageWidget-6HUZYOY7.mjs.map} +1 -1
- package/dist/EngageWidget-MYQTBBW6.js +20 -0
- package/dist/{EngageWidget-Q4ITKTMJ.js.map → EngageWidget-MYQTBBW6.js.map} +1 -1
- package/dist/{FileField-YBBIJOCK.js → FileField-JK2S24XU.js} +6 -6
- package/dist/{FileField-YBBIJOCK.js.map → FileField-JK2S24XU.js.map} +1 -1
- package/dist/{FileField-PQQDX4IR.mjs → FileField-OZZHWGPA.mjs} +5 -5
- package/dist/{FileField-PQQDX4IR.mjs.map → FileField-OZZHWGPA.mjs.map} +1 -1
- package/dist/{FormSpotlight-WUN24F3P.js → FormSpotlight-5AXFQU5M.js} +15 -15
- package/dist/{FormSpotlight-WUN24F3P.js.map → FormSpotlight-5AXFQU5M.js.map} +1 -1
- package/dist/{FormSpotlight-7TIIWFTP.mjs → FormSpotlight-XV42L72H.mjs} +3 -3
- package/dist/{FormSpotlight-7TIIWFTP.mjs.map → FormSpotlight-XV42L72H.mjs.map} +1 -1
- package/dist/{FormStage-CM7OVLUT.js → FormStage-HATUHNRV.js} +13 -13
- package/dist/{FormStage-CM7OVLUT.js.map → FormStage-HATUHNRV.js.map} +1 -1
- package/dist/{FormStage-TFN2GIBO.mjs → FormStage-RUK675HV.mjs} +3 -3
- package/dist/{FormStage-TFN2GIBO.mjs.map → FormStage-RUK675HV.mjs.map} +1 -1
- package/dist/ManagedForm-JWEXJEXK.js +23 -0
- package/dist/{ManagedForm-N63YGVNY.js.map → ManagedForm-JWEXJEXK.js.map} +1 -1
- package/dist/ManagedForm-OA3MNGXT.mjs +14 -0
- package/dist/{ManagedForm-ZUXLHEQU.mjs.map → ManagedForm-OA3MNGXT.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-PIVJTU5L.js → ManagedNewsletterForm-AAHH63KT.js} +8 -8
- package/dist/{ManagedNewsletterForm-PIVJTU5L.js.map → ManagedNewsletterForm-AAHH63KT.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs → ManagedNewsletterForm-HZKTNWLW.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs.map → ManagedNewsletterForm-HZKTNWLW.mjs.map} +1 -1
- package/dist/{SignalCore-LT4NCPOR.mjs → SignalCore-X3GDGBZD.mjs} +5 -5
- package/dist/{SignalCore-LT4NCPOR.mjs.map → SignalCore-X3GDGBZD.mjs.map} +1 -1
- package/dist/{SignalCore-2M5TISM7.js → SignalCore-YSNZYBKJ.js} +11 -11
- package/dist/{SignalCore-2M5TISM7.js.map → SignalCore-YSNZYBKJ.js.map} +1 -1
- package/dist/SitemapSync-2PTDBH5E.mjs +9 -0
- package/dist/{SitemapSync-G3OLECFI.mjs.map → SitemapSync-2PTDBH5E.mjs.map} +1 -1
- package/dist/SitemapSync-3SFAI546.js +18 -0
- package/dist/{SitemapSync-7OBOJG2L.js.map → SitemapSync-3SFAI546.js.map} +1 -1
- package/dist/analytics/dispatch.d.ts +4 -4
- package/dist/analytics/index.js +15 -15
- package/dist/analytics/index.mjs +6 -6
- package/dist/{api-NTHZ6PAW.mjs → api-D745LGGU.mjs} +3 -3
- package/dist/api-D745LGGU.mjs.map +1 -0
- package/dist/{api-N5OLQXYN.js → api-XR5APCH3.js} +3 -3
- package/dist/api-XR5APCH3.js.map +1 -0
- package/dist/blog/AuthorPage.d.ts +1 -1
- package/dist/blog/AuthorPage.d.ts.map +1 -1
- package/dist/blog/BlogLayout.d.ts +3 -1
- package/dist/blog/BlogLayout.d.ts.map +1 -1
- package/dist/blog/BlogList.d.ts +3 -1
- package/dist/blog/BlogList.d.ts.map +1 -1
- package/dist/blog/BlogPost.d.ts +3 -1
- package/dist/blog/BlogPost.d.ts.map +1 -1
- package/dist/blog/BlogSidebar.d.ts +3 -1
- package/dist/blog/BlogSidebar.d.ts.map +1 -1
- package/dist/blog/ClusterLandingPage.d.ts +3 -1
- package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
- package/dist/blog/ClusterNavigation.d.ts +3 -1
- package/dist/blog/ClusterNavigation.d.ts.map +1 -1
- package/dist/blog/RelatedPosts.d.ts +4 -1
- package/dist/blog/RelatedPosts.d.ts.map +1 -1
- package/dist/blog/artwork-components.test.d.ts +2 -0
- package/dist/blog/artwork-components.test.d.ts.map +1 -0
- package/dist/blog/artwork.d.ts +14 -0
- package/dist/blog/artwork.d.ts.map +1 -0
- package/dist/blog/artwork.test.d.ts +2 -0
- package/dist/blog/artwork.test.d.ts.map +1 -0
- package/dist/blog/blog-styles.d.ts.map +1 -1
- package/dist/blog/blog-tables.d.ts +13 -0
- package/dist/blog/blog-tables.d.ts.map +1 -0
- package/dist/blog/blog-tables.test.d.ts +2 -0
- package/dist/blog/blog-tables.test.d.ts.map +1 -0
- package/dist/blog/index.d.ts +3 -0
- package/dist/blog/index.d.ts.map +1 -1
- package/dist/blog/index.js +52 -30
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +15 -12
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/publication-render.test.d.ts +2 -0
- package/dist/blog/publication-render.test.d.ts.map +1 -0
- package/dist/blog/publication-routes.test.d.ts +2 -0
- package/dist/blog/publication-routes.test.d.ts.map +1 -0
- package/dist/blog/routes.d.ts +40 -0
- package/dist/blog/routes.d.ts.map +1 -0
- package/dist/blog/server-core.d.ts +28 -21
- package/dist/blog/server-core.d.ts.map +1 -1
- package/dist/blog/server-ui.d.ts +4 -0
- package/dist/blog/server-ui.d.ts.map +1 -1
- package/dist/blog/server-ui.js +49 -28
- package/dist/blog/server-ui.js.map +1 -1
- package/dist/blog/server-ui.mjs +9 -15
- package/dist/blog/server-ui.mjs.map +1 -1
- package/dist/blog/server.d.ts +28 -21
- package/dist/blog/server.d.ts.map +1 -1
- package/dist/blog/server.js +71 -42
- package/dist/blog/server.mjs +3 -2
- package/dist/blog/types.d.ts +8 -1
- package/dist/blog/types.d.ts.map +1 -1
- package/dist/blog-styles-6EY3BS5Y.js +595 -0
- package/dist/blog-styles-6EY3BS5Y.js.map +1 -0
- package/dist/blog-styles-7AKRUMV7.mjs +592 -0
- package/dist/blog-styles-7AKRUMV7.mjs.map +1 -0
- package/dist/blog-tables-DWDEWA3S.js +17 -0
- package/dist/blog-tables-DWDEWA3S.js.map +1 -0
- package/dist/blog-tables-QGIHOESZ.mjs +4 -0
- package/dist/blog-tables-QGIHOESZ.mjs.map +1 -0
- package/dist/{chunk-OIJ435IZ.js → chunk-2CMSWJWC.js} +18 -18
- package/dist/{chunk-OIJ435IZ.js.map → chunk-2CMSWJWC.js.map} +1 -1
- package/dist/{chunk-K37JPEQW.js → chunk-2OU4KBUN.js} +26 -23
- package/dist/chunk-2OU4KBUN.js.map +1 -0
- package/dist/{chunk-JSLYNYTB.mjs → chunk-3B6CXGAK.mjs} +3 -3
- package/dist/{chunk-JSLYNYTB.mjs.map → chunk-3B6CXGAK.mjs.map} +1 -1
- package/dist/{chunk-HMFFAUCD.js → chunk-3DWIYCQX.js} +2 -2
- package/dist/chunk-3DWIYCQX.js.map +1 -0
- package/dist/{chunk-3EPMDPWI.js → chunk-3SDMJMN2.js} +5 -5
- package/dist/{chunk-3EPMDPWI.js.map → chunk-3SDMJMN2.js.map} +1 -1
- package/dist/chunk-4B4S56WJ.mjs +110 -0
- package/dist/chunk-4B4S56WJ.mjs.map +1 -0
- package/dist/chunk-4U5NCKQY.mjs +39 -0
- package/dist/chunk-4U5NCKQY.mjs.map +1 -0
- package/dist/{chunk-CQUA2AUA.mjs → chunk-4XGACM7D.mjs} +3 -3
- package/dist/{chunk-CQUA2AUA.mjs.map → chunk-4XGACM7D.mjs.map} +1 -1
- package/dist/{chunk-AVM4OZHR.mjs → chunk-5TGAUWNO.mjs} +3 -3
- package/dist/{chunk-AVM4OZHR.mjs.map → chunk-5TGAUWNO.mjs.map} +1 -1
- package/dist/{chunk-RO55G3OA.mjs → chunk-64BOVMXG.mjs} +3 -3
- package/dist/{chunk-RO55G3OA.mjs.map → chunk-64BOVMXG.mjs.map} +1 -1
- package/dist/{chunk-JBGRXICL.js → chunk-746RKQHA.js} +75 -70
- package/dist/chunk-746RKQHA.js.map +1 -0
- package/dist/{chunk-N3C323NY.mjs → chunk-7PPNXORV.mjs} +3 -3
- package/dist/{chunk-N3C323NY.mjs.map → chunk-7PPNXORV.mjs.map} +1 -1
- package/dist/{chunk-DYKFC7WY.js → chunk-A3F5GRNJ.js} +8 -8
- package/dist/{chunk-DYKFC7WY.js.map → chunk-A3F5GRNJ.js.map} +1 -1
- package/dist/{chunk-4TU246Q4.mjs → chunk-AEARU24Q.mjs} +40 -26
- package/dist/chunk-AEARU24Q.mjs.map +1 -0
- package/dist/{chunk-5BZDHZCN.js → chunk-BNOQXDPJ.js} +4 -4
- package/dist/{chunk-5BZDHZCN.js.map → chunk-BNOQXDPJ.js.map} +1 -1
- package/dist/{chunk-XQZTOWS3.js → chunk-CT5REGAK.js} +15 -15
- package/dist/{chunk-XQZTOWS3.js.map → chunk-CT5REGAK.js.map} +1 -1
- package/dist/{chunk-KOP3DPIR.mjs → chunk-DRLHQQBH.mjs} +4 -4
- package/dist/{chunk-KOP3DPIR.mjs.map → chunk-DRLHQQBH.mjs.map} +1 -1
- package/dist/{chunk-Y7SRO7MJ.mjs → chunk-DYULWKDC.mjs} +4 -4
- package/dist/{chunk-Y7SRO7MJ.mjs.map → chunk-DYULWKDC.mjs.map} +1 -1
- package/dist/{chunk-DHXQBTXE.mjs → chunk-EEQYKMGH.mjs} +75 -70
- package/dist/chunk-EEQYKMGH.mjs.map +1 -0
- package/dist/chunk-ESP5RMB7.js +42 -0
- package/dist/chunk-ESP5RMB7.js.map +1 -0
- package/dist/{chunk-4DE2KJ7R.js → chunk-FF5N5D3D.js} +8 -8
- package/dist/{chunk-4DE2KJ7R.js.map → chunk-FF5N5D3D.js.map} +1 -1
- package/dist/{chunk-757HXAYX.js → chunk-FYVLQ3OU.js} +3 -3
- package/dist/{chunk-757HXAYX.js.map → chunk-FYVLQ3OU.js.map} +1 -1
- package/dist/{chunk-OC6PU7U2.mjs → chunk-G5HUI4BO.mjs} +3 -3
- package/dist/{chunk-OC6PU7U2.mjs.map → chunk-G5HUI4BO.mjs.map} +1 -1
- package/dist/chunk-G6WF4G3E.js +43 -0
- package/dist/chunk-G6WF4G3E.js.map +1 -0
- package/dist/chunk-GHECYDSZ.mjs +134 -0
- package/dist/chunk-GHECYDSZ.mjs.map +1 -0
- package/dist/{chunk-JTO3K5B7.mjs → chunk-HBI67P7Y.mjs} +4 -4
- package/dist/{chunk-JTO3K5B7.mjs.map → chunk-HBI67P7Y.mjs.map} +1 -1
- package/dist/{chunk-FFJVQWKO.js → chunk-HFJQMIFM.js} +4 -4
- package/dist/{chunk-FFJVQWKO.js.map → chunk-HFJQMIFM.js.map} +1 -1
- package/dist/{chunk-A3NNUKFA.js → chunk-HX3BRMOX.js} +96 -644
- package/dist/chunk-HX3BRMOX.js.map +1 -0
- package/dist/{chunk-3TXX5KIN.js → chunk-JNRHTZL4.js} +2 -2
- package/dist/{chunk-3TXX5KIN.js.map → chunk-JNRHTZL4.js.map} +1 -1
- package/dist/{chunk-R3LYTIVN.js → chunk-KAUUGRYB.js} +5 -5
- package/dist/{chunk-R3LYTIVN.js.map → chunk-KAUUGRYB.js.map} +1 -1
- package/dist/{chunk-L2LJQIM3.js → chunk-KPKQKFT4.js} +11 -11
- package/dist/chunk-KPKQKFT4.js.map +1 -0
- package/dist/chunk-LC7AM4J5.js +118 -0
- package/dist/chunk-LC7AM4J5.js.map +1 -0
- package/dist/{chunk-GFNXWS3I.js → chunk-MCJF2KJ6.js} +5 -5
- package/dist/{chunk-GFNXWS3I.js.map → chunk-MCJF2KJ6.js.map} +1 -1
- package/dist/{chunk-Z7K5AMCE.js → chunk-MNYM2XU4.js} +4 -4
- package/dist/{chunk-Z7K5AMCE.js.map → chunk-MNYM2XU4.js.map} +1 -1
- package/dist/{chunk-6QABCGM6.mjs → chunk-MU7IEPDG.mjs} +4 -4
- package/dist/chunk-MU7IEPDG.mjs.map +1 -0
- package/dist/chunk-NSWO43XW.mjs +39 -0
- package/dist/chunk-NSWO43XW.mjs.map +1 -0
- package/dist/{chunk-Z33JXJTJ.js → chunk-NZSFOZJV.js} +40 -26
- package/dist/chunk-NZSFOZJV.js.map +1 -0
- package/dist/{chunk-ZKR5AJV5.mjs → chunk-OFSA7LUH.mjs} +4 -4
- package/dist/{chunk-ZKR5AJV5.mjs.map → chunk-OFSA7LUH.mjs.map} +1 -1
- package/dist/{chunk-M7FWXEXC.js → chunk-PIPLBBDH.js} +8 -8
- package/dist/{chunk-M7FWXEXC.js.map → chunk-PIPLBBDH.js.map} +1 -1
- package/dist/{chunk-FDVE56JS.js → chunk-Q26VZNM2.js} +3 -3
- package/dist/{chunk-FDVE56JS.js.map → chunk-Q26VZNM2.js.map} +1 -1
- package/dist/{chunk-6AZTRTCG.js → chunk-QEGUI2Q2.js} +15 -15
- package/dist/{chunk-6AZTRTCG.js.map → chunk-QEGUI2Q2.js.map} +1 -1
- package/dist/{chunk-GPNBBUEN.js → chunk-QFNSM77X.js} +3 -3
- package/dist/{chunk-GPNBBUEN.js.map → chunk-QFNSM77X.js.map} +1 -1
- package/dist/{chunk-QZ54OCWD.mjs → chunk-R4MX6EOM.mjs} +7 -7
- package/dist/{chunk-QZ54OCWD.mjs.map → chunk-R4MX6EOM.mjs.map} +1 -1
- package/dist/{chunk-67CHHDBL.mjs → chunk-RMMHWSPP.mjs} +96 -644
- package/dist/chunk-RMMHWSPP.mjs.map +1 -0
- package/dist/{chunk-B4BFQSSS.mjs → chunk-RU54J2PY.mjs} +4 -4
- package/dist/chunk-RU54J2PY.mjs.map +1 -0
- package/dist/{chunk-AXAIUCSF.mjs → chunk-RZUZMUTN.mjs} +9 -8
- package/dist/chunk-RZUZMUTN.mjs.map +1 -0
- package/dist/{chunk-NSLYY62T.mjs → chunk-S6FEC6UT.mjs} +9 -5
- package/dist/chunk-S6FEC6UT.mjs.map +1 -0
- package/dist/{chunk-3DPXOZAU.mjs → chunk-SHLWA6JY.mjs} +2 -2
- package/dist/chunk-SHLWA6JY.mjs.map +1 -0
- package/dist/{chunk-E33HJMRP.js → chunk-SQVYLIIN.js} +11 -7
- package/dist/chunk-SQVYLIIN.js.map +1 -0
- package/dist/chunk-SUZ3ZLB2.js +8 -0
- package/dist/{chunk-D37M7MIH.js.map → chunk-SUZ3ZLB2.js.map} +1 -1
- package/dist/{chunk-DZDWBQKA.mjs → chunk-TALEV3IH.mjs} +3 -3
- package/dist/{chunk-DZDWBQKA.mjs.map → chunk-TALEV3IH.mjs.map} +1 -1
- package/dist/{chunk-UOTXSWKZ.mjs → chunk-TP7H6BSK.mjs} +2 -2
- package/dist/{chunk-UOTXSWKZ.mjs.map → chunk-TP7H6BSK.mjs.map} +1 -1
- package/dist/{chunk-XW5KNCWJ.mjs → chunk-TX2QQ7IX.mjs} +3 -3
- package/dist/{chunk-XW5KNCWJ.mjs.map → chunk-TX2QQ7IX.mjs.map} +1 -1
- package/dist/{chunk-PEEQMI7U.js → chunk-UNPEMSLK.js} +12 -11
- package/dist/chunk-UNPEMSLK.js.map +1 -0
- package/dist/{chunk-42F5EK24.mjs → chunk-UZL2QU2V.mjs} +16 -13
- package/dist/chunk-UZL2QU2V.mjs.map +1 -0
- package/dist/{chunk-6VG65AIA.mjs → chunk-V6NOM7PJ.mjs} +3 -3
- package/dist/{chunk-6VG65AIA.mjs.map → chunk-V6NOM7PJ.mjs.map} +1 -1
- package/dist/{chunk-W23TMUKB.js → chunk-VAS3LH5W.js} +418 -98
- package/dist/chunk-VAS3LH5W.js.map +1 -0
- package/dist/{chunk-TS3N3LGZ.mjs → chunk-VYHRAICF.mjs} +4 -4
- package/dist/{chunk-TS3N3LGZ.mjs.map → chunk-VYHRAICF.mjs.map} +1 -1
- package/dist/{chunk-G3YUSRCL.js → chunk-W5NVW23S.js} +4 -4
- package/dist/{chunk-G3YUSRCL.js.map → chunk-W5NVW23S.js.map} +1 -1
- package/dist/chunk-WDBCXRTT.mjs +6 -0
- package/dist/{chunk-OUERH2T4.mjs.map → chunk-WDBCXRTT.mjs.map} +1 -1
- package/dist/{chunk-ZOJ3TLO5.mjs → chunk-WIZRCI6J.mjs} +3 -3
- package/dist/{chunk-ZOJ3TLO5.mjs.map → chunk-WIZRCI6J.mjs.map} +1 -1
- package/dist/{chunk-HDQTZAGE.mjs → chunk-X2XFLYZ3.mjs} +3 -3
- package/dist/{chunk-HDQTZAGE.mjs.map → chunk-X2XFLYZ3.mjs.map} +1 -1
- package/dist/{chunk-HVFXFPUJ.mjs → chunk-XQYC4KMH.mjs} +413 -94
- package/dist/chunk-XQYC4KMH.mjs.map +1 -0
- package/dist/{chunk-KPFPSOYS.js → chunk-YNC5D3FT.js} +12 -12
- package/dist/{chunk-KPFPSOYS.js.map → chunk-YNC5D3FT.js.map} +1 -1
- package/dist/chunk-YQTE32QK.js +137 -0
- package/dist/chunk-YQTE32QK.js.map +1 -0
- package/dist/{chunk-PZXKFHPO.js → chunk-YYAFHIY7.js} +15 -15
- package/dist/chunk-YYAFHIY7.js.map +1 -0
- package/dist/{chunk-MANX6422.js → chunk-Z6S4MWSR.js} +7 -7
- package/dist/{chunk-MANX6422.js.map → chunk-Z6S4MWSR.js.map} +1 -1
- package/dist/{chunk-DVH3JHZ3.mjs → chunk-ZRQFG3L6.mjs} +5 -5
- package/dist/{chunk-DVH3JHZ3.mjs.map → chunk-ZRQFG3L6.mjs.map} +1 -1
- package/dist/cli/agent/checks.d.ts.map +1 -1
- package/dist/cli/agent/ssr-bailout.d.ts +27 -0
- package/dist/cli/agent/ssr-bailout.d.ts.map +1 -0
- package/dist/cli/agent/ssr-bailout.test.d.ts +2 -0
- package/dist/cli/agent/ssr-bailout.test.d.ts.map +1 -0
- package/dist/cli/codemod/transforms.d.ts.map +1 -1
- package/dist/cli/index.js +38 -51
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +36 -49
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/migrator/index.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +20 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +5 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/cms/index.js.map +1 -1
- package/dist/cms/index.mjs.map +1 -1
- package/dist/cms/sanity-image.d.ts +1 -1
- package/dist/commerce/index.js +58 -58
- package/dist/commerce/index.mjs +7 -7
- package/dist/engage/ChatWidget.d.ts.map +1 -1
- package/dist/engage/EngageWidget.d.ts +3 -4
- package/dist/engage/EngageWidget.d.ts.map +1 -1
- package/dist/engage/chat-launcher.test.d.ts +2 -0
- package/dist/engage/chat-launcher.test.d.ts.map +1 -0
- package/dist/engage/index.js +12 -10
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +9 -7
- package/dist/engage/index.mjs.map +1 -1
- package/dist/engage/launcher-placement.d.ts +56 -0
- package/dist/engage/launcher-placement.d.ts.map +1 -0
- package/dist/engage/launcher-placement.test.d.ts +2 -0
- package/dist/engage/launcher-placement.test.d.ts.map +1 -0
- package/dist/engage/types.d.ts +41 -7
- package/dist/engage/types.d.ts.map +1 -1
- package/dist/fleet/index.js +8 -8
- package/dist/fleet/index.mjs +4 -4
- package/dist/forms/index.js +16 -16
- package/dist/forms/index.mjs +9 -9
- package/dist/forms/server.js +10 -10
- package/dist/forms/server.mjs +8 -8
- package/dist/forms/static.js +7 -7
- package/dist/forms/static.mjs +6 -6
- package/dist/images/ManagedImage.d.ts.map +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +65 -65
- package/dist/index.mjs +11 -11
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +8 -8
- package/dist/layout/client.mjs +7 -7
- package/dist/layout/index.js +10 -10
- package/dist/layout/index.mjs +8 -8
- package/dist/layout/types.d.ts +7 -3
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.mjs +2 -2
- package/dist/llms/types.d.ts +7 -1
- package/dist/llms/types.d.ts.map +1 -1
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/mcp/WebMcpTools.d.ts +5 -2
- package/dist/mcp/WebMcpTools.d.ts.map +1 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/client.mjs.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/LocationPageContent.d.ts +6 -5
- package/dist/seo/LocationPageContent.d.ts.map +1 -1
- package/dist/seo/api.d.ts +4 -5
- package/dist/seo/api.d.ts.map +1 -1
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +42 -42
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +8 -8
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/routing.d.ts +9 -23
- package/dist/seo/routing.d.ts.map +1 -1
- package/dist/seo/server-api.d.ts +11 -5
- package/dist/seo/server-api.d.ts.map +1 -1
- package/dist/seo/server.js +18 -18
- package/dist/seo/server.mjs +2 -2
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/{server-api-HW4PL2L2.mjs → server-api-RG3ZL3DV.mjs} +3 -3
- package/dist/{server-api-HW4PL2L2.mjs.map → server-api-RG3ZL3DV.mjs.map} +1 -1
- package/dist/{server-api-DB2SIUP4.js → server-api-RYJQAUGO.js} +21 -21
- package/dist/{server-api-DB2SIUP4.js.map → server-api-RYJQAUGO.js.map} +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +52 -0
- package/dist/shared/visual-viewport-gap.d.ts.map +1 -0
- package/dist/shared/visual-viewport-gap.test.d.ts +2 -0
- package/dist/shared/visual-viewport-gap.test.d.ts.map +1 -0
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/index.mjs +1 -1
- package/dist/sync/BookingWidget.d.ts +0 -23
- package/dist/sync/BookingWidget.d.ts.map +1 -1
- package/dist/sync/MeetingFormatStep.d.ts +13 -0
- package/dist/sync/MeetingFormatStep.d.ts.map +1 -0
- package/dist/sync/api.d.ts +9 -10
- package/dist/sync/api.d.ts.map +1 -1
- package/dist/sync/booking-flow.d.ts +7 -0
- package/dist/sync/booking-flow.d.ts.map +1 -0
- package/dist/sync/booking-flow.test.d.ts +2 -0
- package/dist/sync/booking-flow.test.d.ts.map +1 -0
- package/dist/sync/index.d.ts +2 -2
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +20 -16
- package/dist/sync/index.mjs +4 -4
- package/dist/sync/types.d.ts +34 -0
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/site-kit/SKILL.md +8 -3
- package/dist/AnalyticsProvider-2XK54UZW.mjs +0 -11
- package/dist/AnalyticsProvider-PM7SOGOS.js +0 -32
- package/dist/ChatWidget-4PHZHGG5.mjs +0 -11
- package/dist/ChatWidget-7BYSGNO2.js +0 -20
- package/dist/EngageWidget-D6M6QWEC.mjs +0 -9
- package/dist/EngageWidget-Q4ITKTMJ.js +0 -18
- package/dist/ManagedForm-N63YGVNY.js +0 -23
- package/dist/ManagedForm-ZUXLHEQU.mjs +0 -14
- package/dist/SitemapSync-7OBOJG2L.js +0 -18
- package/dist/SitemapSync-G3OLECFI.mjs +0 -9
- package/dist/api-N5OLQXYN.js.map +0 -1
- package/dist/api-NTHZ6PAW.mjs.map +0 -1
- package/dist/chunk-3DPXOZAU.mjs.map +0 -1
- package/dist/chunk-42F5EK24.mjs.map +0 -1
- package/dist/chunk-4TU246Q4.mjs.map +0 -1
- package/dist/chunk-67CHHDBL.mjs.map +0 -1
- package/dist/chunk-6QABCGM6.mjs.map +0 -1
- package/dist/chunk-A3NNUKFA.js.map +0 -1
- package/dist/chunk-AXAIUCSF.mjs.map +0 -1
- package/dist/chunk-B4BFQSSS.mjs.map +0 -1
- package/dist/chunk-CGCYZJYX.mjs +0 -41
- package/dist/chunk-CGCYZJYX.mjs.map +0 -1
- package/dist/chunk-D37M7MIH.js +0 -8
- package/dist/chunk-DHXQBTXE.mjs.map +0 -1
- package/dist/chunk-E33HJMRP.js.map +0 -1
- package/dist/chunk-HMFFAUCD.js.map +0 -1
- package/dist/chunk-HVFXFPUJ.mjs.map +0 -1
- package/dist/chunk-JBGRXICL.js.map +0 -1
- package/dist/chunk-K37JPEQW.js.map +0 -1
- package/dist/chunk-L2LJQIM3.js.map +0 -1
- package/dist/chunk-NSLYY62T.mjs.map +0 -1
- package/dist/chunk-OUERH2T4.mjs +0 -6
- package/dist/chunk-PEEQMI7U.js.map +0 -1
- package/dist/chunk-PZXKFHPO.js.map +0 -1
- package/dist/chunk-TPL2IHFI.js +0 -43
- package/dist/chunk-TPL2IHFI.js.map +0 -1
- package/dist/chunk-W23TMUKB.js.map +0 -1
- package/dist/chunk-Z33JXJTJ.js.map +0 -1
|
@@ -1,8 +1,83 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { sonorFetch } from './chunk-
|
|
3
|
-
import { useState, useRef, useMemo, useEffect,
|
|
2
|
+
import { sonorFetch } from './chunk-OFSA7LUH.mjs';
|
|
3
|
+
import { useState, useRef, useMemo, useCallback, useEffect, useId } from 'react';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
+
function MeetingFormatStep({ options, busy, format, address, onFormatChange, onAddressChange, onContinue, onBack }) {
|
|
7
|
+
const id = useId();
|
|
8
|
+
const choices = [
|
|
9
|
+
{ value: "virtual", label: "Virtual", description: "Meet online with a Google Meet link." },
|
|
10
|
+
{ value: "office", label: "Come to us", description: "Meet in person at our office." },
|
|
11
|
+
{ value: "client_location", label: "We come to you", description: `We can meet at your location within about ${options.travel_radius_miles} miles of our office.` }
|
|
12
|
+
];
|
|
13
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: (e) => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
if (format) onContinue(format, format === "client_location" ? address : void 0);
|
|
16
|
+
}, className: "bw-step sk-meeting-step", children: [
|
|
17
|
+
onBack && /* @__PURE__ */ jsx("button", { type: "button", className: "bw-back sk-meeting-change", onClick: onBack, disabled: busy, children: "\u2190 Change service" }),
|
|
18
|
+
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: "How would you like to meet?" }),
|
|
19
|
+
/* @__PURE__ */ jsxs("fieldset", { disabled: busy, className: "sk-meeting-choices", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("legend", { className: "sk-meeting-legend", children: "Meeting format" }),
|
|
21
|
+
choices.map((choice) => /* @__PURE__ */ jsxs("label", { className: `sk-meeting-choice ${format === choice.value ? "sk-meeting-selected" : ""}`, children: [
|
|
22
|
+
/* @__PURE__ */ jsx("input", { type: "radio", name: `${id}-format`, value: choice.value, checked: format === choice.value, onChange: () => onFormatChange(choice.value), required: true }),
|
|
23
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
24
|
+
/* @__PURE__ */ jsx("strong", { children: choice.label }),
|
|
25
|
+
/* @__PURE__ */ jsx("span", { children: choice.description })
|
|
26
|
+
] })
|
|
27
|
+
] }, choice.value))
|
|
28
|
+
] }),
|
|
29
|
+
format === "office" && /* @__PURE__ */ jsxs("div", { className: "sk-meeting-address", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("p", { children: options.office_address }),
|
|
31
|
+
/* @__PURE__ */ jsx("p", { children: options.office_instructions }),
|
|
32
|
+
/* @__PURE__ */ jsx("a", { href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(options.office_address)}`, target: "_blank", rel: "noopener noreferrer", children: "Get directions" })
|
|
33
|
+
] }),
|
|
34
|
+
format === "client_location" && /* @__PURE__ */ jsxs("fieldset", { disabled: busy, className: "bw-form sk-meeting-fields", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("legend", { children: "Your meeting address" }),
|
|
36
|
+
[
|
|
37
|
+
["street", "Street address", "street-address"],
|
|
38
|
+
["unit", "Suite or unit (optional)", "address-line2"],
|
|
39
|
+
["city", "City", "address-level2"],
|
|
40
|
+
["region", "State or region", "address-level1"],
|
|
41
|
+
["postalCode", "Postal code", "postal-code"],
|
|
42
|
+
["country", "Country", "country-name"]
|
|
43
|
+
].map(([key, label, autocomplete]) => /* @__PURE__ */ jsxs("div", { className: "bw-field", children: [
|
|
44
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${id}-${key}`, children: label }),
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
"input",
|
|
47
|
+
{
|
|
48
|
+
id: `${id}-${key}`,
|
|
49
|
+
value: address[key],
|
|
50
|
+
required: key !== "unit",
|
|
51
|
+
maxLength: 200,
|
|
52
|
+
autoComplete: autocomplete,
|
|
53
|
+
onChange: (e) => onAddressChange({ ...address, [key]: e.target.value })
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
] }, key)),
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "bw-field", children: [
|
|
58
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${id}-notes`, children: "Parking or access notes (optional)" }),
|
|
59
|
+
/* @__PURE__ */ jsx("textarea", { id: `${id}-notes`, value: address.notes, maxLength: 2e3, onChange: (e) => onAddressChange({ ...address, notes: e.target.value }) })
|
|
60
|
+
] }),
|
|
61
|
+
options.travel_review_required && /* @__PURE__ */ jsx("p", { children: "We\u2019ll reserve your requested time and confirm after checking travel arrangements." })
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ jsx("button", { className: "bw-submit", type: "submit", disabled: !format || busy, children: busy ? "Checking meeting details\u2026" : "Choose a time" }),
|
|
64
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
65
|
+
.sk-meeting-choices { border: 0; padding: 0; margin: 20px 0; display: grid; gap: 10px; }
|
|
66
|
+
.sk-meeting-legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
|
|
67
|
+
.sk-meeting-choice { display: flex; align-items: flex-start; gap: 12px; padding: 16px; border: 1px solid var(--sk-border); border-radius: var(--sk-radius); cursor: pointer; background: var(--sk-surface); }
|
|
68
|
+
.sk-meeting-choice input { margin-top: 4px; accent-color: var(--sk-primary); }
|
|
69
|
+
.sk-meeting-choice strong { display: block; color: var(--sk-text-primary); }
|
|
70
|
+
.sk-meeting-choice span span { display: block; margin-top: 4px; font-size: 14px; color: var(--sk-text-secondary); }
|
|
71
|
+
.sk-meeting-selected { border-color: var(--sk-primary); background: var(--sk-primary-light); }
|
|
72
|
+
.sk-meeting-address { padding: 16px; background: var(--sk-surface); border-radius: var(--sk-radius); margin-bottom: 16px; white-space: pre-wrap; }
|
|
73
|
+
.sk-meeting-address a { display: inline-block; margin-top: 8px; color: var(--sk-primary); }
|
|
74
|
+
.sk-meeting-fields { border: 0; padding: 0; margin-bottom: 20px; }
|
|
75
|
+
.sk-meeting-fields legend { margin-bottom: 12px; font-weight: 600; }
|
|
76
|
+
.sk-meeting-step .bw-submit { width: 100%; }
|
|
77
|
+
` })
|
|
78
|
+
] });
|
|
79
|
+
}
|
|
80
|
+
|
|
6
81
|
// src/sync/api.ts
|
|
7
82
|
var DEFAULT_API_URL = "https://api.sonor.io";
|
|
8
83
|
function getApiConfig() {
|
|
@@ -42,13 +117,14 @@ async function fetchBookingTypeDetails(typeSlug, orgSlug, apiUrl, apiKey) {
|
|
|
42
117
|
}
|
|
43
118
|
return response.json();
|
|
44
119
|
}
|
|
45
|
-
async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezone, hostId) {
|
|
120
|
+
async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezone, hostId, meetingToken) {
|
|
46
121
|
const cfg = getApiConfig();
|
|
47
122
|
const url = apiUrl || cfg.apiUrl;
|
|
48
123
|
const key = apiKey || cfg.apiKey;
|
|
49
124
|
const params = new URLSearchParams({ date });
|
|
50
125
|
if (timezone) params.append("timezone", timezone);
|
|
51
126
|
if (hostId) params.append("hostId", hostId);
|
|
127
|
+
if (meetingToken) params.append("meetingToken", meetingToken);
|
|
52
128
|
const endpoint = key ? `${url}/sync/widget/availability/${typeSlug}?${params}` : `${url}/sync/public/${orgSlug}/availability/${typeSlug}?${params}`;
|
|
53
129
|
const response = await sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
54
130
|
if (!response.ok) {
|
|
@@ -68,6 +144,11 @@ async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezo
|
|
|
68
144
|
available: slot.available !== false
|
|
69
145
|
}));
|
|
70
146
|
}
|
|
147
|
+
async function bookingRequestError(response, fallback) {
|
|
148
|
+
const body = await response.json().catch(() => ({}));
|
|
149
|
+
const message = Array.isArray(body.message) ? body.message.join(". ") : body.message;
|
|
150
|
+
return new Error(typeof message === "string" && message.trim() ? message : fallback);
|
|
151
|
+
}
|
|
71
152
|
async function createSlotHold(holdData, apiUrl, apiKey) {
|
|
72
153
|
const cfg = getApiConfig();
|
|
73
154
|
const url = apiUrl || cfg.apiUrl;
|
|
@@ -79,7 +160,7 @@ async function createSlotHold(holdData, apiUrl, apiKey) {
|
|
|
79
160
|
body: JSON.stringify(holdData)
|
|
80
161
|
}, { apiKey: key, retries: 0 });
|
|
81
162
|
if (!response.ok) {
|
|
82
|
-
throw
|
|
163
|
+
throw await bookingRequestError(response, "We couldn\u2019t reserve that time. Please choose another time.");
|
|
83
164
|
}
|
|
84
165
|
return response.json();
|
|
85
166
|
}
|
|
@@ -104,12 +185,11 @@ async function createBooking(bookingData, apiUrl, apiKey) {
|
|
|
104
185
|
body: JSON.stringify(bookingData)
|
|
105
186
|
}, { apiKey: key, retries: 0 });
|
|
106
187
|
if (!response.ok) {
|
|
107
|
-
|
|
108
|
-
throw new Error(errorData.message || `Failed to create booking: ${response.statusText}`);
|
|
188
|
+
throw await bookingRequestError(response, "We couldn\u2019t complete your booking. Please try again.");
|
|
109
189
|
}
|
|
110
190
|
return response.json();
|
|
111
191
|
}
|
|
112
|
-
async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl, apiKey, timezone) {
|
|
192
|
+
async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl, apiKey, timezone, meetingToken) {
|
|
113
193
|
const availableDates = [];
|
|
114
194
|
const start = new Date(startDate);
|
|
115
195
|
const end = new Date(endDate);
|
|
@@ -117,7 +197,7 @@ async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl
|
|
|
117
197
|
while (current <= end) {
|
|
118
198
|
const dateStr = current.toISOString().split("T")[0];
|
|
119
199
|
try {
|
|
120
|
-
const slots = await fetchAvailability(typeSlug, dateStr, orgSlug, apiUrl, apiKey, timezone);
|
|
200
|
+
const slots = await fetchAvailability(typeSlug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meetingToken);
|
|
121
201
|
if (slots.some((s) => s.available)) {
|
|
122
202
|
availableDates.push(dateStr);
|
|
123
203
|
}
|
|
@@ -164,6 +244,33 @@ function formatDuration(minutes) {
|
|
|
164
244
|
}
|
|
165
245
|
return `${hours}h ${mins}m`;
|
|
166
246
|
}
|
|
247
|
+
async function prepareMeeting(bookingType, format, address, orgSlug, apiUrl, apiKey) {
|
|
248
|
+
const cfg = getApiConfig();
|
|
249
|
+
const url = apiUrl || cfg.apiUrl;
|
|
250
|
+
const key = apiKey || cfg.apiKey;
|
|
251
|
+
const endpoint = key ? `${url}/sync/widget/meeting` : `${url}/sync/public/${orgSlug}/meeting`;
|
|
252
|
+
const response = await sonorFetch(endpoint, {
|
|
253
|
+
method: "POST",
|
|
254
|
+
headers: buildHeaders(true),
|
|
255
|
+
body: JSON.stringify({ bookingType, format, address })
|
|
256
|
+
}, { apiKey: key, retries: 0 });
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
throw await bookingRequestError(response, "We couldn\u2019t check your meeting details. Please try again.");
|
|
259
|
+
}
|
|
260
|
+
return response.json();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/sync/booking-flow.ts
|
|
264
|
+
function expiredBookingContext(meeting, hold, now = Date.now()) {
|
|
265
|
+
if (hold) return Date.parse(hold.expiresAt) <= now ? "hold" : null;
|
|
266
|
+
return meeting && Date.parse(meeting.expiresAt) <= now ? "meeting" : null;
|
|
267
|
+
}
|
|
268
|
+
function bookingRecoveryFromError(error) {
|
|
269
|
+
const message = error instanceof Error ? error.message : "";
|
|
270
|
+
if (/meeting details expired|choose how you.d like to meet first/i.test(message)) return "meeting";
|
|
271
|
+
if (/time reservation expired|invalid slot hold|meeting details changed/i.test(message)) return "hold";
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
167
274
|
var DEFAULT_API_URL2 = "https://api.sonor.io";
|
|
168
275
|
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
169
276
|
var MONTHS = [
|
|
@@ -275,6 +382,17 @@ function BookingWidget({
|
|
|
275
382
|
const [guestInfo, setGuestInfo] = useState({ name: "", email: "" });
|
|
276
383
|
const [bookingResult, setBookingResult] = useState(null);
|
|
277
384
|
const [submitting, setSubmitting] = useState(false);
|
|
385
|
+
const [meeting, setMeeting] = useState(null);
|
|
386
|
+
const [meetingFormat, setMeetingFormat] = useState(null);
|
|
387
|
+
const [meetingAddress, setMeetingAddress] = useState({ street: "", city: "", region: "", postalCode: "", country: "United States", unit: "", notes: "" });
|
|
388
|
+
const [recovery, setRecovery] = useState(null);
|
|
389
|
+
const [sessionId] = useState(() => `bw-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
390
|
+
const requestRef = useRef(0);
|
|
391
|
+
const busyRef = useRef(false);
|
|
392
|
+
const bookingInFlightRef = useRef(false);
|
|
393
|
+
const holdRef = useRef(null);
|
|
394
|
+
const onErrorRef = useRef(onError);
|
|
395
|
+
onErrorRef.current = onError;
|
|
278
396
|
const [autoProbing, setAutoProbing] = useState(false);
|
|
279
397
|
const probeRef = useRef(0);
|
|
280
398
|
const prefetchedRef = useRef(null);
|
|
@@ -299,26 +417,79 @@ function BookingWidget({
|
|
|
299
417
|
d.setDate(d.getDate() + daysToShow);
|
|
300
418
|
return d;
|
|
301
419
|
}, [today, daysToShow]);
|
|
420
|
+
const setActiveHold = useCallback((value) => {
|
|
421
|
+
holdRef.current = value;
|
|
422
|
+
setHold(value);
|
|
423
|
+
}, []);
|
|
424
|
+
const resetScheduling = useCallback((nextStep, clearMeeting = false) => {
|
|
425
|
+
++requestRef.current;
|
|
426
|
+
const previous = holdRef.current;
|
|
427
|
+
setActiveHold(null);
|
|
428
|
+
if (previous) releaseSlotHold(previous.holdId, apiUrl, apiKey).catch(() => {
|
|
429
|
+
});
|
|
430
|
+
setSelectedDate(null);
|
|
431
|
+
setSelectedSlot(null);
|
|
432
|
+
setConfirmedSlot(false);
|
|
433
|
+
setSlots([]);
|
|
434
|
+
setSlotsLoading(false);
|
|
435
|
+
prefetchedRef.current = null;
|
|
436
|
+
if (clearMeeting) setMeeting(null);
|
|
437
|
+
setRecovery(null);
|
|
438
|
+
setError(null);
|
|
439
|
+
setStep(nextStep);
|
|
440
|
+
}, [apiUrl, apiKey, setActiveHold]);
|
|
441
|
+
const reportRequestError = useCallback((err) => {
|
|
442
|
+
setRecovery(bookingRecoveryFromError(err));
|
|
443
|
+
setError(err.message);
|
|
444
|
+
onErrorRef.current?.(err);
|
|
445
|
+
}, []);
|
|
446
|
+
useEffect(() => () => {
|
|
447
|
+
++requestRef.current;
|
|
448
|
+
if (holdRef.current && !bookingInFlightRef.current) {
|
|
449
|
+
releaseSlotHold(holdRef.current.holdId, apiUrl, apiKey).catch(() => {
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
holdRef.current = null;
|
|
453
|
+
}, [apiUrl, apiKey]);
|
|
302
454
|
useEffect(() => {
|
|
455
|
+
let cancelled = false;
|
|
456
|
+
++requestRef.current;
|
|
457
|
+
busyRef.current = false;
|
|
458
|
+
bookingInFlightRef.current = false;
|
|
459
|
+
resetScheduling(bookingTypeSlug ? "datetime" : "type", true);
|
|
460
|
+
setSelectedType(null);
|
|
461
|
+
setMeetingFormat(null);
|
|
462
|
+
setBookingResult(null);
|
|
463
|
+
setSubmitting(false);
|
|
303
464
|
if (bookingTypeSlug) {
|
|
304
465
|
setLoading(true);
|
|
305
466
|
fetchBookingTypeDetails(bookingTypeSlug, orgSlug, apiUrl, apiKey).then((type) => {
|
|
306
|
-
|
|
307
|
-
|
|
467
|
+
if (!cancelled) {
|
|
468
|
+
setSelectedType(type);
|
|
469
|
+
setStep(type.meeting_options ? "format" : "datetime");
|
|
470
|
+
}
|
|
308
471
|
}).catch((err) => {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
472
|
+
if (!cancelled) reportRequestError(err);
|
|
473
|
+
}).finally(() => {
|
|
474
|
+
if (!cancelled) setLoading(false);
|
|
475
|
+
});
|
|
312
476
|
} else {
|
|
313
477
|
setLoading(true);
|
|
314
|
-
fetchBookingTypes(orgSlug, apiUrl, apiKey).then((types) =>
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
478
|
+
fetchBookingTypes(orgSlug, apiUrl, apiKey).then((types) => {
|
|
479
|
+
if (!cancelled) setBookingTypes(types.filter((t) => t.is_active));
|
|
480
|
+
}).catch((err) => {
|
|
481
|
+
if (!cancelled) reportRequestError(err);
|
|
482
|
+
}).finally(() => {
|
|
483
|
+
if (!cancelled) setLoading(false);
|
|
484
|
+
});
|
|
318
485
|
}
|
|
319
|
-
|
|
486
|
+
return () => {
|
|
487
|
+
cancelled = true;
|
|
488
|
+
++requestRef.current;
|
|
489
|
+
};
|
|
490
|
+
}, [orgSlug, apiKey, bookingTypeSlug, apiUrl, resetScheduling, reportRequestError]);
|
|
320
491
|
useEffect(() => {
|
|
321
|
-
if (!selectedDate || !selectedType) return;
|
|
492
|
+
if (!selectedDate || !selectedType || selectedType.meeting_options && !meeting) return;
|
|
322
493
|
const dateStr = toLocalDateStr(selectedDate);
|
|
323
494
|
setSelectedSlot(null);
|
|
324
495
|
setConfirmedSlot(false);
|
|
@@ -329,15 +500,22 @@ function BookingWidget({
|
|
|
329
500
|
setSlotsLoading(false);
|
|
330
501
|
return;
|
|
331
502
|
}
|
|
503
|
+
let cancelled = false;
|
|
332
504
|
setSlotsLoading(true);
|
|
333
505
|
setSlots([]);
|
|
334
|
-
fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
506
|
+
fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meeting?.meetingToken).then((s) => {
|
|
507
|
+
if (!cancelled) setSlots(s.filter((slot) => slot.available));
|
|
508
|
+
}).catch((err) => {
|
|
509
|
+
if (!cancelled) reportRequestError(err);
|
|
510
|
+
}).finally(() => {
|
|
511
|
+
if (!cancelled) setSlotsLoading(false);
|
|
512
|
+
});
|
|
513
|
+
return () => {
|
|
514
|
+
cancelled = true;
|
|
515
|
+
};
|
|
516
|
+
}, [selectedDate, selectedType, orgSlug, apiKey, apiUrl, timezone, reportRequestError, meeting]);
|
|
339
517
|
useEffect(() => {
|
|
340
|
-
if (!autoSelectFirstDay || !selectedType || selectedDate) return;
|
|
518
|
+
if (!autoSelectFirstDay || !selectedType || selectedDate || step !== "datetime" || recovery || selectedType.meeting_options && !meeting) return;
|
|
341
519
|
const probeId = ++probeRef.current;
|
|
342
520
|
let cancelled = false;
|
|
343
521
|
const PROBE_DAYS = 14;
|
|
@@ -350,7 +528,7 @@ function BookingWidget({
|
|
|
350
528
|
d.setDate(d.getDate() + i);
|
|
351
529
|
if (d > maxDate) break;
|
|
352
530
|
const dateStr = toLocalDateStr(d);
|
|
353
|
-
const s = await fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone);
|
|
531
|
+
const s = await fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meeting?.meetingToken);
|
|
354
532
|
if (cancelled || probeRef.current !== probeId) return;
|
|
355
533
|
const open = s.filter((slot) => slot.available);
|
|
356
534
|
if (open.length > 0) {
|
|
@@ -360,7 +538,8 @@ function BookingWidget({
|
|
|
360
538
|
return;
|
|
361
539
|
}
|
|
362
540
|
}
|
|
363
|
-
} catch {
|
|
541
|
+
} catch (err) {
|
|
542
|
+
if (!cancelled && bookingRecoveryFromError(err)) reportRequestError(err);
|
|
364
543
|
} finally {
|
|
365
544
|
if (!cancelled && probeRef.current === probeId) setAutoProbing(false);
|
|
366
545
|
}
|
|
@@ -369,46 +548,92 @@ function BookingWidget({
|
|
|
369
548
|
cancelled = true;
|
|
370
549
|
setAutoProbing(false);
|
|
371
550
|
};
|
|
372
|
-
}, [autoSelectFirstDay, selectedType, selectedDate, orgSlug, apiKey, apiUrl, timezone, today, maxDate]);
|
|
551
|
+
}, [autoSelectFirstDay, selectedType, selectedDate, orgSlug, apiKey, apiUrl, timezone, today, maxDate, step, meeting, recovery, reportRequestError]);
|
|
552
|
+
useEffect(() => {
|
|
553
|
+
if (step !== "datetime" && step !== "form" || loading || submitting) return;
|
|
554
|
+
const expiry = hold?.expiresAt || meeting?.expiresAt;
|
|
555
|
+
if (!expiry || !Number.isFinite(Date.parse(expiry))) return;
|
|
556
|
+
const checkExpiry = () => {
|
|
557
|
+
const expired = expiredBookingContext(meeting, hold);
|
|
558
|
+
if (!busyRef.current && expired) setRecovery(expired);
|
|
559
|
+
};
|
|
560
|
+
const timer = setTimeout(checkExpiry, Math.max(0, Date.parse(expiry) - Date.now()));
|
|
561
|
+
window.addEventListener("focus", checkExpiry);
|
|
562
|
+
return () => {
|
|
563
|
+
clearTimeout(timer);
|
|
564
|
+
window.removeEventListener("focus", checkExpiry);
|
|
565
|
+
};
|
|
566
|
+
}, [meeting, hold, step, loading, submitting]);
|
|
373
567
|
const handleSlotSelect = useCallback((slot) => {
|
|
568
|
+
if (busyRef.current) return;
|
|
374
569
|
setSelectedSlot(slot);
|
|
375
570
|
setConfirmedSlot(false);
|
|
376
571
|
}, []);
|
|
377
572
|
const handleSlotConfirm = useCallback(async () => {
|
|
378
|
-
if (!selectedType || !selectedSlot) return;
|
|
379
|
-
|
|
380
|
-
|
|
573
|
+
if (!selectedType || !selectedSlot || busyRef.current || recovery) return;
|
|
574
|
+
const expired = expiredBookingContext(meeting, null);
|
|
575
|
+
if (expired) {
|
|
576
|
+
setRecovery(expired);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
const requestId = ++requestRef.current;
|
|
580
|
+
busyRef.current = true;
|
|
381
581
|
setLoading(true);
|
|
582
|
+
setError(null);
|
|
382
583
|
try {
|
|
584
|
+
const previous = holdRef.current;
|
|
585
|
+
setActiveHold(null);
|
|
586
|
+
if (previous) await releaseSlotHold(previous.holdId, apiUrl, apiKey).catch(() => {
|
|
587
|
+
});
|
|
588
|
+
if (requestId !== requestRef.current) return;
|
|
383
589
|
const newHold = await createSlotHold(
|
|
384
590
|
{
|
|
591
|
+
meetingToken: meeting?.meetingToken,
|
|
592
|
+
org: apiKey ? void 0 : orgSlug,
|
|
385
593
|
bookingType: selectedType.slug,
|
|
386
594
|
slotStart: selectedSlot.start,
|
|
387
595
|
slotEnd: selectedSlot.end,
|
|
388
596
|
hostId: selectedSlot.hostId || "",
|
|
389
|
-
sessionId
|
|
597
|
+
sessionId
|
|
390
598
|
},
|
|
391
599
|
apiUrl,
|
|
392
600
|
apiKey
|
|
393
601
|
);
|
|
394
|
-
|
|
602
|
+
if (requestId !== requestRef.current) {
|
|
603
|
+
await releaseSlotHold(newHold.holdId, apiUrl, apiKey).catch(() => {
|
|
604
|
+
});
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
setActiveHold(newHold);
|
|
395
608
|
setConfirmedSlot(true);
|
|
396
609
|
setStep("form");
|
|
397
610
|
} catch (err) {
|
|
398
|
-
|
|
399
|
-
onError?.(err);
|
|
611
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
400
612
|
} finally {
|
|
401
|
-
|
|
613
|
+
if (requestId === requestRef.current) {
|
|
614
|
+
busyRef.current = false;
|
|
615
|
+
setLoading(false);
|
|
616
|
+
}
|
|
402
617
|
}
|
|
403
|
-
}, [selectedType, selectedSlot,
|
|
618
|
+
}, [selectedType, selectedSlot, apiUrl, apiKey, meeting, sessionId, orgSlug, recovery, setActiveHold, reportRequestError]);
|
|
404
619
|
const handleBookingSubmit = useCallback(async (e) => {
|
|
405
620
|
e.preventDefault();
|
|
406
|
-
if (!selectedType || !selectedSlot) return;
|
|
621
|
+
if (!selectedType || !selectedSlot || busyRef.current || recovery) return;
|
|
622
|
+
const expired = expiredBookingContext(meeting, hold);
|
|
623
|
+
if (expired) {
|
|
624
|
+
setRecovery(expired);
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
const requestId = ++requestRef.current;
|
|
628
|
+
busyRef.current = true;
|
|
629
|
+
bookingInFlightRef.current = true;
|
|
407
630
|
setSubmitting(true);
|
|
408
631
|
setError(null);
|
|
409
632
|
try {
|
|
410
633
|
const result = await createBooking(
|
|
411
634
|
{
|
|
635
|
+
meetingToken: meeting?.meetingToken,
|
|
636
|
+
org: apiKey ? void 0 : orgSlug,
|
|
412
637
|
bookingType: selectedType.slug,
|
|
413
638
|
scheduledAt: selectedSlot.start,
|
|
414
639
|
hostId: selectedSlot.hostId || "",
|
|
@@ -419,31 +644,82 @@ function BookingWidget({
|
|
|
419
644
|
source: "main-site",
|
|
420
645
|
timezone,
|
|
421
646
|
holdId: hold?.holdId,
|
|
422
|
-
sessionId
|
|
647
|
+
sessionId,
|
|
423
648
|
sourceUrl: typeof window !== "undefined" ? window.location.href : void 0
|
|
424
649
|
},
|
|
425
650
|
apiUrl,
|
|
426
651
|
apiKey
|
|
427
652
|
);
|
|
653
|
+
if (requestId !== requestRef.current) return;
|
|
654
|
+
setActiveHold(null);
|
|
428
655
|
setBookingResult(result);
|
|
429
656
|
setStep("success");
|
|
430
657
|
onBookingComplete?.(result);
|
|
431
658
|
} catch (err) {
|
|
432
|
-
|
|
433
|
-
|
|
659
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
660
|
+
else if (hold) releaseSlotHold(hold.holdId, apiUrl, apiKey).catch(() => {
|
|
661
|
+
});
|
|
434
662
|
} finally {
|
|
435
|
-
|
|
663
|
+
if (requestId === requestRef.current) {
|
|
664
|
+
busyRef.current = false;
|
|
665
|
+
bookingInFlightRef.current = false;
|
|
666
|
+
setSubmitting(false);
|
|
667
|
+
}
|
|
436
668
|
}
|
|
437
|
-
}, [selectedType, selectedSlot, guestInfo, timezone, hold, apiUrl, apiKey, onBookingComplete,
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
669
|
+
}, [selectedType, selectedSlot, guestInfo, timezone, hold, apiUrl, apiKey, onBookingComplete, meeting, sessionId, orgSlug, recovery, setActiveHold, reportRequestError]);
|
|
670
|
+
const chooseFormat = async (format, address) => {
|
|
671
|
+
if (!selectedType || busyRef.current) return;
|
|
672
|
+
const requestId = ++requestRef.current;
|
|
673
|
+
busyRef.current = true;
|
|
674
|
+
setLoading(true);
|
|
675
|
+
setError(null);
|
|
676
|
+
try {
|
|
677
|
+
const prepared = await prepareMeeting(selectedType.slug, format, address, orgSlug, apiUrl, apiKey);
|
|
678
|
+
if (requestId !== requestRef.current) return;
|
|
679
|
+
setMeeting(prepared);
|
|
680
|
+
setRecovery(null);
|
|
681
|
+
setSelectedDate(null);
|
|
682
|
+
setSelectedSlot(null);
|
|
683
|
+
prefetchedRef.current = null;
|
|
684
|
+
setStep("datetime");
|
|
685
|
+
} catch (err) {
|
|
686
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
687
|
+
} finally {
|
|
688
|
+
if (requestId === requestRef.current) {
|
|
689
|
+
busyRef.current = false;
|
|
690
|
+
setLoading(false);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
const changeFormat = () => {
|
|
695
|
+
if (!busyRef.current) resetScheduling("format", true);
|
|
696
|
+
};
|
|
697
|
+
const changeService = () => {
|
|
698
|
+
if (busyRef.current) return;
|
|
699
|
+
resetScheduling("type", true);
|
|
700
|
+
setSelectedType(null);
|
|
701
|
+
setMeetingFormat(null);
|
|
702
|
+
};
|
|
703
|
+
const recoverReservation = () => {
|
|
704
|
+
if (busyRef.current) return;
|
|
705
|
+
const needsMeeting = recovery === "meeting" || expiredBookingContext(meeting, null) === "meeting";
|
|
706
|
+
resetScheduling(needsMeeting ? "format" : "datetime", needsMeeting);
|
|
707
|
+
};
|
|
708
|
+
const displayType = selectedType ? {
|
|
709
|
+
...selectedType,
|
|
710
|
+
...meeting ? { location_type: meeting.location_type, location_details: meeting.location_details, location_instructions: meeting.location_instructions } : {},
|
|
711
|
+
...bookingResult ? {
|
|
712
|
+
location_type: bookingResult.booking.location_type || selectedType.location_type,
|
|
713
|
+
location_details: bookingResult.booking.location_details,
|
|
714
|
+
location_instructions: bookingResult.booking.location_instructions,
|
|
715
|
+
video_link: bookingResult.booking.video_link
|
|
716
|
+
} : {}
|
|
717
|
+
} : null;
|
|
718
|
+
const isPending = bookingResult?.booking.status === "pending";
|
|
444
719
|
const canGoPrev = viewMonth.getFullYear() > today.getFullYear() || viewMonth.getMonth() > today.getMonth();
|
|
445
720
|
const canGoNext = viewMonth < maxDate;
|
|
446
721
|
const goMonth = (dir) => {
|
|
722
|
+
if (busyRef.current) return;
|
|
447
723
|
setViewMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + dir, 1));
|
|
448
724
|
};
|
|
449
725
|
const groupedSlots = useMemo(() => {
|
|
@@ -478,10 +754,17 @@ function BookingWidget({
|
|
|
478
754
|
"--sk-input-focus-ring": styles.primaryColor ? `color-mix(in srgb, ${styles.primaryColor} 12%, ${styles.backgroundColor || "white"})` : "#e8f1ff"
|
|
479
755
|
};
|
|
480
756
|
return /* @__PURE__ */ jsxs("div", { className: `bw-root ${className}`, style: cssVars, children: [
|
|
481
|
-
error && /* @__PURE__ */ jsxs("div", { className: "bw-error", role: "alert", children: [
|
|
757
|
+
error && !recovery && /* @__PURE__ */ jsxs("div", { className: "bw-error", role: "alert", children: [
|
|
482
758
|
/* @__PURE__ */ jsx("span", { children: error }),
|
|
483
759
|
/* @__PURE__ */ jsx("button", { onClick: () => setError(null), "aria-label": "Dismiss error", children: "\xD7" })
|
|
484
760
|
] }),
|
|
761
|
+
recovery && /* @__PURE__ */ jsxs("div", { className: "sk-booking-recovery", role: "alert", children: [
|
|
762
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
763
|
+
recovery === "meeting" ? "Your meeting details need to be checked again." : "Your time reservation expired. Choose a time to continue.",
|
|
764
|
+
" Your entered details are saved."
|
|
765
|
+
] }),
|
|
766
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "bw-submit", onClick: recoverReservation, disabled: loading || submitting, children: recovery === "meeting" ? "Review meeting details" : "Choose another time" })
|
|
767
|
+
] }),
|
|
485
768
|
step === "type" && !hideTypeSelector && /* @__PURE__ */ jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
486
769
|
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: "Select a Service" }),
|
|
487
770
|
loading ? /* @__PURE__ */ jsxs("div", { className: "bw-loading", children: [
|
|
@@ -492,8 +775,10 @@ function BookingWidget({
|
|
|
492
775
|
{
|
|
493
776
|
className: "bw-type-card",
|
|
494
777
|
onClick: () => {
|
|
495
|
-
|
|
496
|
-
|
|
778
|
+
if (!busyRef.current) {
|
|
779
|
+
resetScheduling(type.meeting_options ? "format" : "datetime", true);
|
|
780
|
+
setSelectedType(type);
|
|
781
|
+
}
|
|
497
782
|
},
|
|
498
783
|
children: [
|
|
499
784
|
/* @__PURE__ */ jsx("span", { className: "bw-type-name", children: type.name }),
|
|
@@ -510,12 +795,23 @@ function BookingWidget({
|
|
|
510
795
|
type.id
|
|
511
796
|
)) })
|
|
512
797
|
] }),
|
|
798
|
+
step === "format" && selectedType?.meeting_options && /* @__PURE__ */ jsx(
|
|
799
|
+
MeetingFormatStep,
|
|
800
|
+
{
|
|
801
|
+
options: selectedType.meeting_options,
|
|
802
|
+
busy: loading,
|
|
803
|
+
format: meetingFormat,
|
|
804
|
+
address: meetingAddress,
|
|
805
|
+
onFormatChange: setMeetingFormat,
|
|
806
|
+
onAddressChange: setMeetingAddress,
|
|
807
|
+
onContinue: chooseFormat,
|
|
808
|
+
onBack: !bookingTypeSlug && !hideTypeSelector ? changeService : void 0
|
|
809
|
+
}
|
|
810
|
+
),
|
|
811
|
+
selectedType?.meeting_options && (step === "datetime" || step === "form") && /* @__PURE__ */ jsx("button", { type: "button", className: "bw-back sk-meeting-change", onClick: changeFormat, disabled: loading || submitting, children: "\u2190 Change meeting format" }),
|
|
513
812
|
step === "datetime" && selectedType && /* @__PURE__ */ jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
514
813
|
/* @__PURE__ */ jsxs("div", { className: "bw-info-header", children: [
|
|
515
|
-
!bookingTypeSlug && /* @__PURE__ */ jsx("button", { className: "bw-back", onClick: ()
|
|
516
|
-
setSelectedType(null);
|
|
517
|
-
setStep("type");
|
|
518
|
-
}, children: /* @__PURE__ */ jsx(ArrowLeftIcon, {}) }),
|
|
814
|
+
!bookingTypeSlug && !hideTypeSelector && /* @__PURE__ */ jsx("button", { className: "bw-back", onClick: changeService, disabled: loading, "aria-label": "Change service", children: /* @__PURE__ */ jsx(ArrowLeftIcon, {}) }),
|
|
519
815
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
520
816
|
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: selectedType.name }),
|
|
521
817
|
/* @__PURE__ */ jsxs("div", { className: "bw-meta-row", children: [
|
|
@@ -529,34 +825,36 @@ function BookingWidget({
|
|
|
529
825
|
" ",
|
|
530
826
|
shortTz
|
|
531
827
|
] }),
|
|
532
|
-
/* @__PURE__ */ jsx(LocationBadge, { type:
|
|
828
|
+
/* @__PURE__ */ jsx(LocationBadge, { type: displayType })
|
|
533
829
|
] })
|
|
534
830
|
] })
|
|
535
831
|
] }),
|
|
536
832
|
/* @__PURE__ */ jsxs("div", { className: "bw-datetime-layout", children: [
|
|
537
833
|
/* @__PURE__ */ jsxs("div", { className: "bw-calendar", children: [
|
|
538
834
|
/* @__PURE__ */ jsxs("div", { className: "bw-cal-header", children: [
|
|
539
|
-
/* @__PURE__ */ jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(-1), disabled: !canGoPrev, "aria-label": "Previous month", children: /* @__PURE__ */ jsx(ChevronLeft, {}) }),
|
|
835
|
+
/* @__PURE__ */ jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(-1), disabled: !canGoPrev || loading || !!recovery, "aria-label": "Previous month", children: /* @__PURE__ */ jsx(ChevronLeft, {}) }),
|
|
540
836
|
/* @__PURE__ */ jsxs("span", { className: "bw-cal-title", children: [
|
|
541
837
|
MONTHS[viewMonth.getMonth()],
|
|
542
838
|
" ",
|
|
543
839
|
viewMonth.getFullYear()
|
|
544
840
|
] }),
|
|
545
|
-
/* @__PURE__ */ jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(1), disabled: !canGoNext, "aria-label": "Next month", children: /* @__PURE__ */ jsx(ChevronRight, {}) })
|
|
841
|
+
/* @__PURE__ */ jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(1), disabled: !canGoNext || loading || !!recovery, "aria-label": "Next month", children: /* @__PURE__ */ jsx(ChevronRight, {}) })
|
|
546
842
|
] }),
|
|
547
843
|
/* @__PURE__ */ jsx("div", { className: "bw-cal-weekdays", children: DAYS.map((d) => /* @__PURE__ */ jsx("span", { className: "bw-cal-wd", children: d }, d)) }),
|
|
548
844
|
/* @__PURE__ */ jsx("div", { className: "bw-cal-grid", children: days.map((date, i) => {
|
|
549
845
|
if (!date) return /* @__PURE__ */ jsx("span", { className: "bw-cal-empty" }, `e-${i}`);
|
|
550
846
|
const past = isBeforeDay(date, today);
|
|
551
847
|
const future = date > maxDate;
|
|
552
|
-
const disabled = past || future;
|
|
848
|
+
const disabled = past || future || loading || !!recovery;
|
|
553
849
|
const sel = selectedDate && isSameDay(date, selectedDate);
|
|
554
850
|
const isToday = isSameDay(date, today);
|
|
555
851
|
return /* @__PURE__ */ jsx(
|
|
556
852
|
"button",
|
|
557
853
|
{
|
|
558
854
|
className: `bw-cal-day${sel ? " selected" : ""}${isToday ? " today" : ""}${disabled ? " disabled" : ""}`,
|
|
559
|
-
onClick: () =>
|
|
855
|
+
onClick: () => {
|
|
856
|
+
if (!disabled && !busyRef.current) setSelectedDate(date);
|
|
857
|
+
},
|
|
560
858
|
disabled,
|
|
561
859
|
"aria-label": date.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" }),
|
|
562
860
|
"aria-pressed": sel || void 0,
|
|
@@ -579,15 +877,15 @@ function BookingWidget({
|
|
|
579
877
|
/* @__PURE__ */ jsx("p", { className: "bw-times-date", children: selectedDate.toLocaleDateString("en-US", { weekday: "long", month: "short", day: "numeric" }) }),
|
|
580
878
|
groupedSlots.morning.length > 0 && /* @__PURE__ */ jsxs("div", { className: "bw-time-group", children: [
|
|
581
879
|
/* @__PURE__ */ jsx("span", { className: "bw-time-label", children: "Morning" }),
|
|
582
|
-
groupedSlots.morning.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
880
|
+
groupedSlots.morning.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading: loading || !!recovery }, slot.start))
|
|
583
881
|
] }),
|
|
584
882
|
groupedSlots.afternoon.length > 0 && /* @__PURE__ */ jsxs("div", { className: "bw-time-group", children: [
|
|
585
883
|
/* @__PURE__ */ jsx("span", { className: "bw-time-label", children: "Afternoon" }),
|
|
586
|
-
groupedSlots.afternoon.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
884
|
+
groupedSlots.afternoon.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading: loading || !!recovery }, slot.start))
|
|
587
885
|
] }),
|
|
588
886
|
groupedSlots.evening.length > 0 && /* @__PURE__ */ jsxs("div", { className: "bw-time-group", children: [
|
|
589
887
|
/* @__PURE__ */ jsx("span", { className: "bw-time-label", children: "Evening" }),
|
|
590
|
-
groupedSlots.evening.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
888
|
+
groupedSlots.evening.map((slot) => /* @__PURE__ */ jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading: loading || !!recovery }, slot.start))
|
|
591
889
|
] }),
|
|
592
890
|
(groupedSlots.afternoon.length > 0 || groupedSlots.evening.length > 0) && /* @__PURE__ */ jsx("p", { className: "bw-times-scroll-hint", children: "Scroll for more times" })
|
|
593
891
|
] }) })
|
|
@@ -595,7 +893,7 @@ function BookingWidget({
|
|
|
595
893
|
] }),
|
|
596
894
|
step === "form" && selectedType && selectedSlot && /* @__PURE__ */ jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
597
895
|
/* @__PURE__ */ jsxs("div", { className: "bw-info-header", children: [
|
|
598
|
-
/* @__PURE__ */ jsx("button", { className: "bw-back", onClick:
|
|
896
|
+
/* @__PURE__ */ jsx("button", { className: "bw-back", onClick: recoverReservation, disabled: submitting, "aria-label": "Choose another time", children: /* @__PURE__ */ jsx(ArrowLeftIcon, {}) }),
|
|
599
897
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
600
898
|
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: "Your Details" }),
|
|
601
899
|
/* @__PURE__ */ jsxs("div", { className: "bw-meta-row", children: [
|
|
@@ -609,14 +907,16 @@ function BookingWidget({
|
|
|
609
907
|
" \xB7 ",
|
|
610
908
|
formatTime(selectedSlot.start, timezone)
|
|
611
909
|
] }),
|
|
612
|
-
/* @__PURE__ */ jsx(LocationBadge, { type:
|
|
910
|
+
/* @__PURE__ */ jsx(LocationBadge, { type: displayType })
|
|
613
911
|
] })
|
|
614
912
|
] })
|
|
615
913
|
] }),
|
|
616
|
-
hold && /* @__PURE__ */ jsxs("div", { className: "bw-hold-notice", children: [
|
|
914
|
+
hold && !recovery && /* @__PURE__ */ jsxs("div", { className: "bw-hold-notice", children: [
|
|
617
915
|
/* @__PURE__ */ jsx(SpinnerIcon, {}),
|
|
618
916
|
" Slot held for you. Complete your details to confirm."
|
|
619
917
|
] }),
|
|
918
|
+
/* @__PURE__ */ jsx(LocationRow, { type: displayType, meetingFormat: meeting?.format }),
|
|
919
|
+
meeting?.requires_review && /* @__PURE__ */ jsx("p", { children: "We\u2019ll confirm your visit after reviewing travel arrangements." }),
|
|
620
920
|
/* @__PURE__ */ jsxs("form", { onSubmit: handleBookingSubmit, className: "bw-form", children: [
|
|
621
921
|
/* @__PURE__ */ jsxs("div", { className: "bw-field", children: [
|
|
622
922
|
/* @__PURE__ */ jsxs("label", { htmlFor: "bw-name", children: [
|
|
@@ -629,6 +929,7 @@ function BookingWidget({
|
|
|
629
929
|
id: "bw-name",
|
|
630
930
|
type: "text",
|
|
631
931
|
required: true,
|
|
932
|
+
readOnly: submitting,
|
|
632
933
|
value: guestInfo.name,
|
|
633
934
|
onChange: (e) => setGuestInfo((p) => ({ ...p, name: e.target.value })),
|
|
634
935
|
placeholder: "Jane Smith",
|
|
@@ -647,6 +948,7 @@ function BookingWidget({
|
|
|
647
948
|
id: "bw-email",
|
|
648
949
|
type: "email",
|
|
649
950
|
required: true,
|
|
951
|
+
readOnly: submitting,
|
|
650
952
|
value: guestInfo.email,
|
|
651
953
|
onChange: (e) => setGuestInfo((p) => ({ ...p, email: e.target.value })),
|
|
652
954
|
placeholder: "jane@example.com",
|
|
@@ -655,10 +957,15 @@ function BookingWidget({
|
|
|
655
957
|
)
|
|
656
958
|
] }),
|
|
657
959
|
/* @__PURE__ */ jsxs("div", { className: "bw-field", children: [
|
|
658
|
-
/* @__PURE__ */
|
|
960
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "bw-phone", children: [
|
|
961
|
+
"Phone ",
|
|
962
|
+
meeting?.format === "client_location" && /* @__PURE__ */ jsx("span", { className: "bw-req", children: "*" })
|
|
963
|
+
] }),
|
|
659
964
|
/* @__PURE__ */ jsx(
|
|
660
965
|
"input",
|
|
661
966
|
{
|
|
967
|
+
required: meeting?.format === "client_location",
|
|
968
|
+
readOnly: submitting,
|
|
662
969
|
id: "bw-phone",
|
|
663
970
|
type: "tel",
|
|
664
971
|
value: guestInfo.phone || "",
|
|
@@ -674,6 +981,7 @@ function BookingWidget({
|
|
|
674
981
|
"textarea",
|
|
675
982
|
{
|
|
676
983
|
id: "bw-notes",
|
|
984
|
+
readOnly: submitting,
|
|
677
985
|
value: guestInfo.notes || "",
|
|
678
986
|
onChange: (e) => setGuestInfo((p) => ({ ...p, notes: e.target.value })),
|
|
679
987
|
placeholder: "Anything you'd like us to know...",
|
|
@@ -681,15 +989,15 @@ function BookingWidget({
|
|
|
681
989
|
}
|
|
682
990
|
)
|
|
683
991
|
] }),
|
|
684
|
-
/* @__PURE__ */ jsx("button", { type: "submit", className: "bw-submit", disabled: submitting || !guestInfo.name || !guestInfo.email, children: submitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
992
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "bw-submit", disabled: submitting || !!recovery || !guestInfo.name || !guestInfo.email, children: submitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
685
993
|
/* @__PURE__ */ jsx(SpinnerIcon, {}),
|
|
686
994
|
" Confirming..."
|
|
687
|
-
] }) : "Confirm
|
|
995
|
+
] }) : meeting?.requires_review ? "Request meeting" : "Confirm booking" })
|
|
688
996
|
] })
|
|
689
997
|
] }),
|
|
690
998
|
step === "success" && bookingResult && /* @__PURE__ */ jsxs("div", { className: "bw-step bw-fade-in bw-success", children: [
|
|
691
999
|
/* @__PURE__ */ jsx("div", { className: "bw-success-icon", children: /* @__PURE__ */ jsx(CheckCircleIcon, {}) }),
|
|
692
|
-
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: "You\u2019re
|
|
1000
|
+
/* @__PURE__ */ jsx("h2", { className: "bw-heading", children: isPending ? "Meeting request received" : "You\u2019re booked!" }),
|
|
693
1001
|
/* @__PURE__ */ jsxs("div", { className: "bw-details-card", children: [
|
|
694
1002
|
/* @__PURE__ */ jsxs("div", { className: "bw-detail-row", children: [
|
|
695
1003
|
/* @__PURE__ */ jsx("span", { className: "bw-detail-label", children: "When" }),
|
|
@@ -710,26 +1018,28 @@ function BookingWidget({
|
|
|
710
1018
|
/* @__PURE__ */ jsx("span", { className: "bw-detail-label", children: "With" }),
|
|
711
1019
|
/* @__PURE__ */ jsx("span", { className: "bw-detail-value", children: bookingResult.booking.hostName })
|
|
712
1020
|
] }),
|
|
713
|
-
/* @__PURE__ */ jsx(LocationRow, { type:
|
|
1021
|
+
/* @__PURE__ */ jsx(LocationRow, { type: displayType, meetingFormat: meeting?.format })
|
|
714
1022
|
] }),
|
|
715
1023
|
/* @__PURE__ */ jsxs("p", { className: "bw-email-notice", children: [
|
|
716
|
-
"We\
|
|
1024
|
+
isPending ? "We\u2019ll send your confirmation to " : "Your meeting details will arrive at ",
|
|
717
1025
|
/* @__PURE__ */ jsx("strong", { children: guestInfo.email }),
|
|
718
|
-
"
|
|
1026
|
+
"."
|
|
719
1027
|
] }),
|
|
720
|
-
/* @__PURE__ */
|
|
721
|
-
|
|
722
|
-
/* @__PURE__ */ jsxs("
|
|
723
|
-
/* @__PURE__ */
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
/* @__PURE__ */
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
/* @__PURE__ */
|
|
732
|
-
|
|
1028
|
+
!isPending && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1029
|
+
/* @__PURE__ */ jsx("p", { className: "bw-cal-links-label", children: "Add to your calendar" }),
|
|
1030
|
+
/* @__PURE__ */ jsxs("div", { className: "bw-cal-links", children: [
|
|
1031
|
+
/* @__PURE__ */ jsxs("a", { href: bookingResult.calendarLinks.google, target: "_blank", rel: "noopener noreferrer", className: "bw-cal-link", children: [
|
|
1032
|
+
/* @__PURE__ */ jsx(CalendarPlusIcon, {}),
|
|
1033
|
+
" Google"
|
|
1034
|
+
] }),
|
|
1035
|
+
/* @__PURE__ */ jsxs("a", { href: bookingResult.calendarLinks.outlook, target: "_blank", rel: "noopener noreferrer", className: "bw-cal-link", children: [
|
|
1036
|
+
/* @__PURE__ */ jsx(CalendarPlusIcon, {}),
|
|
1037
|
+
" Outlook"
|
|
1038
|
+
] }),
|
|
1039
|
+
/* @__PURE__ */ jsxs("a", { href: bookingResult.calendarLinks.ics, download: true, className: "bw-cal-link", children: [
|
|
1040
|
+
/* @__PURE__ */ jsx(CalendarPlusIcon, {}),
|
|
1041
|
+
" iCal"
|
|
1042
|
+
] })
|
|
733
1043
|
] })
|
|
734
1044
|
] }),
|
|
735
1045
|
(bookingResult.rescheduleUrl || bookingResult.cancelUrl) && /* @__PURE__ */ jsxs("p", { className: "bw-manage-links", children: [
|
|
@@ -768,7 +1078,7 @@ function getLocationDisplay(type) {
|
|
|
768
1078
|
return { kind: "custom", label: details || "See details" };
|
|
769
1079
|
case "virtual":
|
|
770
1080
|
default:
|
|
771
|
-
return { kind: "virtual", label: "Video call" };
|
|
1081
|
+
return { kind: "virtual", label: "Video call", detail: type.video_link };
|
|
772
1082
|
}
|
|
773
1083
|
}
|
|
774
1084
|
function LocationBadge({ type }) {
|
|
@@ -780,7 +1090,7 @@ function LocationBadge({ type }) {
|
|
|
780
1090
|
loc.label
|
|
781
1091
|
] });
|
|
782
1092
|
}
|
|
783
|
-
function LocationRow({ type }) {
|
|
1093
|
+
function LocationRow({ type, meetingFormat }) {
|
|
784
1094
|
const loc = getLocationDisplay(type);
|
|
785
1095
|
if (!loc) return null;
|
|
786
1096
|
return /* @__PURE__ */ jsxs("div", { className: "bw-detail-row", children: [
|
|
@@ -789,9 +1099,13 @@ function LocationRow({ type }) {
|
|
|
789
1099
|
loc.label,
|
|
790
1100
|
loc.detail ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
791
1101
|
/* @__PURE__ */ jsx("br", {}),
|
|
792
|
-
loc.detail
|
|
1102
|
+
loc.kind === "virtual" ? /* @__PURE__ */ jsx("a", { href: loc.detail, target: "_blank", rel: "noopener noreferrer", children: "Join Google Meet" }) : loc.detail
|
|
793
1103
|
] }) : null,
|
|
794
|
-
|
|
1104
|
+
type?.location_instructions && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1105
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
1106
|
+
/* @__PURE__ */ jsx("span", { style: { whiteSpace: "pre-wrap" }, children: type.location_instructions })
|
|
1107
|
+
] }),
|
|
1108
|
+
loc.mapUrl && meetingFormat !== "client_location" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
795
1109
|
/* @__PURE__ */ jsx("br", {}),
|
|
796
1110
|
/* @__PURE__ */ jsx("a", { href: loc.mapUrl, target: "_blank", rel: "noopener noreferrer", className: "bw-where-link", children: "Get directions \u2192" })
|
|
797
1111
|
] }) : null,
|
|
@@ -871,6 +1185,10 @@ var WIDGET_CSS = `
|
|
|
871
1185
|
padding: 10px 14px; border-radius: var(--sk-radius); margin-bottom: 16px; font-size: 0.875rem;
|
|
872
1186
|
}
|
|
873
1187
|
.bw-error button { background: none; border: none; color: inherit; cursor: pointer; font-size: 1.25rem; line-height: 1; padding: 0; }
|
|
1188
|
+
.sk-booking-recovery { padding: 16px; margin-bottom: 16px; border: 1px solid var(--sk-border); border-radius: var(--sk-radius); background: var(--sk-surface); color: var(--sk-text-primary); }
|
|
1189
|
+
.sk-booking-recovery p { margin: 0 0 12px; font-size: 0.875rem; }
|
|
1190
|
+
.sk-booking-recovery .bw-submit { width: auto; }
|
|
1191
|
+
.bw-back:disabled { cursor: wait; opacity: 0.55; }
|
|
874
1192
|
|
|
875
1193
|
/* \u2500\u2500 Headings \u2500\u2500 */
|
|
876
1194
|
.bw-heading { font-size: 1.125rem; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
|
|
@@ -892,6 +1210,7 @@ var WIDGET_CSS = `
|
|
|
892
1210
|
background: var(--sk-bg); cursor: pointer; color: var(--sk-text-secondary); flex-shrink: 0; margin-top: 1px;
|
|
893
1211
|
transition: all 0.15s;
|
|
894
1212
|
}
|
|
1213
|
+
.bw-back.sk-meeting-change { width: auto; height: auto; min-height: 36px; padding: 8px 12px; border-radius: var(--sk-radius); margin-bottom: 12px; font-size: 0.8125rem; }
|
|
895
1214
|
.bw-back:hover { background: var(--sk-surface); border-color: var(--sk-border); }
|
|
896
1215
|
|
|
897
1216
|
/* \u2500\u2500 Loading \u2500\u2500 */
|
|
@@ -1086,6 +1405,6 @@ var WIDGET_CSS = `
|
|
|
1086
1405
|
.bw-manage-links a { color: var(--sk-primary, #14B8A6); text-decoration: none; font-weight: 500; }
|
|
1087
1406
|
`;
|
|
1088
1407
|
|
|
1089
|
-
export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, releaseSlotHold };
|
|
1090
|
-
//# sourceMappingURL=chunk-
|
|
1091
|
-
//# sourceMappingURL=chunk-
|
|
1408
|
+
export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, prepareMeeting, releaseSlotHold };
|
|
1409
|
+
//# sourceMappingURL=chunk-XQYC4KMH.mjs.map
|
|
1410
|
+
//# sourceMappingURL=chunk-XQYC4KMH.mjs.map
|