@sonordev/site-kit 5.3.2 → 5.4.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/README.md +17 -0
- package/agent-manifest.json +5 -4
- package/dist/AnalyticsProvider-2XIOMRCN.mjs +11 -0
- package/dist/{AnalyticsProvider-2XK54UZW.mjs.map → AnalyticsProvider-2XIOMRCN.mjs.map} +1 -1
- package/dist/AnalyticsProvider-Y2P2BPOI.js +32 -0
- package/dist/{AnalyticsProvider-PM7SOGOS.js.map → AnalyticsProvider-Y2P2BPOI.js.map} +1 -1
- package/dist/{BlogViewTracker-3BIUF5TI.js → BlogViewTracker-6EGEDPP3.js} +6 -6
- package/dist/{BlogViewTracker-3BIUF5TI.js.map → BlogViewTracker-6EGEDPP3.js.map} +1 -1
- package/dist/{BlogViewTracker-KFUDRDQK.mjs → BlogViewTracker-R4YQ76WP.mjs} +5 -5
- package/dist/{BlogViewTracker-KFUDRDQK.mjs.map → BlogViewTracker-R4YQ76WP.mjs.map} +1 -1
- package/dist/ChatWidget-2OFWPCWF.js +20 -0
- package/dist/{ChatWidget-7BYSGNO2.js.map → ChatWidget-2OFWPCWF.js.map} +1 -1
- package/dist/ChatWidget-4AOGHYXQ.mjs +11 -0
- package/dist/{ChatWidget-4PHZHGG5.mjs.map → ChatWidget-4AOGHYXQ.mjs.map} +1 -1
- package/dist/EngageWidget-SFO2XRNG.mjs +9 -0
- package/dist/{EngageWidget-D6M6QWEC.mjs.map → EngageWidget-SFO2XRNG.mjs.map} +1 -1
- package/dist/EngageWidget-T4KAAD3G.js +18 -0
- package/dist/{EngageWidget-Q4ITKTMJ.js.map → EngageWidget-T4KAAD3G.js.map} +1 -1
- package/dist/{FileField-PQQDX4IR.mjs → FileField-7DF2SLPF.mjs} +5 -5
- package/dist/{FileField-PQQDX4IR.mjs.map → FileField-7DF2SLPF.mjs.map} +1 -1
- package/dist/{FileField-YBBIJOCK.js → FileField-CE2XNBBG.js} +6 -6
- package/dist/{FileField-YBBIJOCK.js.map → FileField-CE2XNBBG.js.map} +1 -1
- package/dist/{FormSpotlight-7TIIWFTP.mjs → FormSpotlight-IRLKSZGV.mjs} +3 -3
- package/dist/{FormSpotlight-7TIIWFTP.mjs.map → FormSpotlight-IRLKSZGV.mjs.map} +1 -1
- package/dist/{FormSpotlight-WUN24F3P.js → FormSpotlight-ZD3WR5BC.js} +15 -15
- package/dist/{FormSpotlight-WUN24F3P.js.map → FormSpotlight-ZD3WR5BC.js.map} +1 -1
- package/dist/{FormStage-TFN2GIBO.mjs → FormStage-2OSRNQJL.mjs} +3 -3
- package/dist/{FormStage-TFN2GIBO.mjs.map → FormStage-2OSRNQJL.mjs.map} +1 -1
- package/dist/{FormStage-CM7OVLUT.js → FormStage-OSPXOUQE.js} +13 -13
- package/dist/{FormStage-CM7OVLUT.js.map → FormStage-OSPXOUQE.js.map} +1 -1
- package/dist/ManagedForm-5G37EDJT.mjs +14 -0
- package/dist/{ManagedForm-ZUXLHEQU.mjs.map → ManagedForm-5G37EDJT.mjs.map} +1 -1
- package/dist/ManagedForm-JCHGBBQW.js +23 -0
- package/dist/{ManagedForm-N63YGVNY.js.map → ManagedForm-JCHGBBQW.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-PIVJTU5L.js → ManagedNewsletterForm-4LVJZROZ.js} +8 -8
- package/dist/{ManagedNewsletterForm-PIVJTU5L.js.map → ManagedNewsletterForm-4LVJZROZ.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs → ManagedNewsletterForm-QJSVH23S.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-4AVKTZ2A.mjs.map → ManagedNewsletterForm-QJSVH23S.mjs.map} +1 -1
- package/dist/{SignalCore-LT4NCPOR.mjs → SignalCore-L6Z3YTCF.mjs} +5 -5
- package/dist/{SignalCore-LT4NCPOR.mjs.map → SignalCore-L6Z3YTCF.mjs.map} +1 -1
- package/dist/{SignalCore-2M5TISM7.js → SignalCore-NQ4YEOI7.js} +11 -11
- package/dist/{SignalCore-2M5TISM7.js.map → SignalCore-NQ4YEOI7.js.map} +1 -1
- package/dist/SitemapSync-3LUZWBTB.js +18 -0
- package/dist/{SitemapSync-7OBOJG2L.js.map → SitemapSync-3LUZWBTB.js.map} +1 -1
- package/dist/SitemapSync-MYSTLJOM.mjs +9 -0
- package/dist/{SitemapSync-G3OLECFI.mjs.map → SitemapSync-MYSTLJOM.mjs.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- 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-M7FWXEXC.js → chunk-2KIGFOPM.js} +5 -5
- package/dist/{chunk-M7FWXEXC.js.map → chunk-2KIGFOPM.js.map} +1 -1
- package/dist/chunk-4B4S56WJ.mjs +110 -0
- package/dist/chunk-4B4S56WJ.mjs.map +1 -0
- package/dist/{chunk-PZXKFHPO.js → chunk-4WQB2ORG.js} +14 -14
- package/dist/{chunk-PZXKFHPO.js.map → chunk-4WQB2ORG.js.map} +1 -1
- package/dist/{chunk-XQZTOWS3.js → chunk-5737U6DI.js} +14 -14
- package/dist/{chunk-XQZTOWS3.js.map → chunk-5737U6DI.js.map} +1 -1
- package/dist/{chunk-ZOJ3TLO5.mjs → chunk-6CUBSQMD.mjs} +3 -3
- package/dist/{chunk-ZOJ3TLO5.mjs.map → chunk-6CUBSQMD.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-E33HJMRP.js → chunk-7IPSQ5JR.js} +6 -6
- package/dist/{chunk-E33HJMRP.js.map → chunk-7IPSQ5JR.js.map} +1 -1
- package/dist/{chunk-FDVE56JS.js → chunk-7PLH3H3W.js} +3 -3
- package/dist/{chunk-FDVE56JS.js.map → chunk-7PLH3H3W.js.map} +1 -1
- package/dist/chunk-7U7C6XRI.mjs +6 -0
- package/dist/{chunk-OUERH2T4.mjs.map → chunk-7U7C6XRI.mjs.map} +1 -1
- package/dist/{chunk-DZDWBQKA.mjs → chunk-7Y2UPFSY.mjs} +3 -3
- package/dist/{chunk-DZDWBQKA.mjs.map → chunk-7Y2UPFSY.mjs.map} +1 -1
- package/dist/{chunk-JSLYNYTB.mjs → chunk-A2VLEORI.mjs} +3 -3
- package/dist/{chunk-JSLYNYTB.mjs.map → chunk-A2VLEORI.mjs.map} +1 -1
- package/dist/{chunk-6QABCGM6.mjs → chunk-ACTLQ2RH.mjs} +3 -3
- package/dist/{chunk-6QABCGM6.mjs.map → chunk-ACTLQ2RH.mjs.map} +1 -1
- package/dist/{chunk-PEEQMI7U.js → chunk-AWFZIXCT.js} +11 -11
- package/dist/{chunk-PEEQMI7U.js.map → chunk-AWFZIXCT.js.map} +1 -1
- package/dist/{chunk-HVFXFPUJ.mjs → chunk-B36PTS7B.mjs} +413 -94
- package/dist/chunk-B36PTS7B.mjs.map +1 -0
- package/dist/{chunk-KPFPSOYS.js → chunk-DPDV5Z4G.js} +12 -12
- package/dist/{chunk-KPFPSOYS.js.map → chunk-DPDV5Z4G.js.map} +1 -1
- package/dist/{chunk-JTO3K5B7.mjs → chunk-DQM5GR2P.mjs} +4 -4
- package/dist/{chunk-JTO3K5B7.mjs.map → chunk-DQM5GR2P.mjs.map} +1 -1
- package/dist/{chunk-HDQTZAGE.mjs → chunk-EBMPXFOP.mjs} +3 -3
- package/dist/{chunk-HDQTZAGE.mjs.map → chunk-EBMPXFOP.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-6VG65AIA.mjs → chunk-G5I3XEQS.mjs} +3 -3
- package/dist/{chunk-6VG65AIA.mjs.map → chunk-G5I3XEQS.mjs.map} +1 -1
- package/dist/chunk-GHECYDSZ.mjs +134 -0
- package/dist/chunk-GHECYDSZ.mjs.map +1 -0
- package/dist/{chunk-6AZTRTCG.js → chunk-GQ6CUOLA.js} +15 -15
- package/dist/{chunk-6AZTRTCG.js.map → chunk-GQ6CUOLA.js.map} +1 -1
- package/dist/{chunk-5BZDHZCN.js → chunk-HBMF3M5F.js} +4 -4
- package/dist/{chunk-5BZDHZCN.js.map → chunk-HBMF3M5F.js.map} +1 -1
- package/dist/{chunk-AVM4OZHR.mjs → chunk-HDDV63XJ.mjs} +3 -3
- package/dist/{chunk-AVM4OZHR.mjs.map → chunk-HDDV63XJ.mjs.map} +1 -1
- package/dist/{chunk-KOP3DPIR.mjs → chunk-HH5KGXTK.mjs} +4 -4
- package/dist/{chunk-KOP3DPIR.mjs.map → chunk-HH5KGXTK.mjs.map} +1 -1
- package/dist/{chunk-CQUA2AUA.mjs → chunk-I4PDSDVE.mjs} +3 -3
- package/dist/{chunk-CQUA2AUA.mjs.map → chunk-I4PDSDVE.mjs.map} +1 -1
- package/dist/{chunk-757HXAYX.js → chunk-ITFZZ6YT.js} +3 -3
- package/dist/{chunk-757HXAYX.js.map → chunk-ITFZZ6YT.js.map} +1 -1
- package/dist/{chunk-N3C323NY.mjs → chunk-JJ26JKBJ.mjs} +3 -3
- package/dist/{chunk-N3C323NY.mjs.map → chunk-JJ26JKBJ.mjs.map} +1 -1
- package/dist/{chunk-Z33JXJTJ.js → chunk-KMGGAL2X.js} +2 -2
- package/dist/{chunk-Z33JXJTJ.js.map → chunk-KMGGAL2X.js.map} +1 -1
- package/dist/{chunk-TS3N3LGZ.mjs → chunk-KQ3VAOAF.mjs} +4 -4
- package/dist/{chunk-TS3N3LGZ.mjs.map → chunk-KQ3VAOAF.mjs.map} +1 -1
- package/dist/{chunk-GPNBBUEN.js → chunk-LBS4PRC7.js} +3 -3
- package/dist/{chunk-GPNBBUEN.js.map → chunk-LBS4PRC7.js.map} +1 -1
- package/dist/chunk-LC7AM4J5.js +118 -0
- package/dist/chunk-LC7AM4J5.js.map +1 -0
- package/dist/{chunk-4DE2KJ7R.js → chunk-LF4L3ZP5.js} +8 -8
- package/dist/{chunk-4DE2KJ7R.js.map → chunk-LF4L3ZP5.js.map} +1 -1
- package/dist/{chunk-DYKFC7WY.js → chunk-LHYVFWHL.js} +8 -8
- package/dist/{chunk-DYKFC7WY.js.map → chunk-LHYVFWHL.js.map} +1 -1
- package/dist/{chunk-67CHHDBL.mjs → chunk-LIYSLNEK.mjs} +96 -644
- package/dist/chunk-LIYSLNEK.mjs.map +1 -0
- package/dist/{chunk-G3YUSRCL.js → chunk-LUYUFILE.js} +4 -4
- package/dist/{chunk-G3YUSRCL.js.map → chunk-LUYUFILE.js.map} +1 -1
- package/dist/{chunk-ZKR5AJV5.mjs → chunk-MIFP6QEQ.mjs} +4 -4
- package/dist/{chunk-ZKR5AJV5.mjs.map → chunk-MIFP6QEQ.mjs.map} +1 -1
- package/dist/{chunk-QZ54OCWD.mjs → chunk-MTANHZKJ.mjs} +7 -7
- package/dist/{chunk-QZ54OCWD.mjs.map → chunk-MTANHZKJ.mjs.map} +1 -1
- package/dist/{chunk-NSLYY62T.mjs → chunk-N6AVWMIB.mjs} +4 -4
- package/dist/{chunk-NSLYY62T.mjs.map → chunk-N6AVWMIB.mjs.map} +1 -1
- package/dist/{chunk-OC6PU7U2.mjs → chunk-N6X76QUF.mjs} +3 -3
- package/dist/{chunk-OC6PU7U2.mjs.map → chunk-N6X76QUF.mjs.map} +1 -1
- package/dist/{chunk-42F5EK24.mjs → chunk-NUH245XK.mjs} +4 -4
- package/dist/{chunk-42F5EK24.mjs.map → chunk-NUH245XK.mjs.map} +1 -1
- package/dist/{chunk-MANX6422.js → chunk-OXZYP32B.js} +7 -7
- package/dist/{chunk-MANX6422.js.map → chunk-OXZYP32B.js.map} +1 -1
- package/dist/{chunk-K37JPEQW.js → chunk-QWLL3B6U.js} +15 -15
- package/dist/{chunk-K37JPEQW.js.map → chunk-QWLL3B6U.js.map} +1 -1
- package/dist/{chunk-AXAIUCSF.mjs → chunk-SJXGIUHP.mjs} +8 -8
- package/dist/{chunk-AXAIUCSF.mjs.map → chunk-SJXGIUHP.mjs.map} +1 -1
- package/dist/{chunk-4TU246Q4.mjs → chunk-SZHKNGNR.mjs} +2 -2
- package/dist/{chunk-4TU246Q4.mjs.map → chunk-SZHKNGNR.mjs.map} +1 -1
- package/dist/{chunk-R3LYTIVN.js → chunk-U53KN4SA.js} +5 -5
- package/dist/{chunk-R3LYTIVN.js.map → chunk-U53KN4SA.js.map} +1 -1
- package/dist/{chunk-Y7SRO7MJ.mjs → chunk-UOLY4NXK.mjs} +3 -3
- package/dist/{chunk-Y7SRO7MJ.mjs.map → chunk-UOLY4NXK.mjs.map} +1 -1
- package/dist/{chunk-Z7K5AMCE.js → chunk-URVGBWCP.js} +4 -4
- package/dist/{chunk-Z7K5AMCE.js.map → chunk-URVGBWCP.js.map} +1 -1
- package/dist/chunk-UTOHMK52.js +8 -0
- package/dist/{chunk-D37M7MIH.js.map → chunk-UTOHMK52.js.map} +1 -1
- package/dist/{chunk-FFJVQWKO.js → chunk-VA36CJRV.js} +4 -4
- package/dist/{chunk-FFJVQWKO.js.map → chunk-VA36CJRV.js.map} +1 -1
- package/dist/{chunk-A3NNUKFA.js → chunk-VWDT7H6L.js} +96 -644
- package/dist/chunk-VWDT7H6L.js.map +1 -0
- package/dist/{chunk-OIJ435IZ.js → chunk-WSUQ76LN.js} +18 -18
- package/dist/{chunk-OIJ435IZ.js.map → chunk-WSUQ76LN.js.map} +1 -1
- package/dist/{chunk-XW5KNCWJ.mjs → chunk-XWF7QPIP.mjs} +3 -3
- package/dist/{chunk-XW5KNCWJ.mjs.map → chunk-XWF7QPIP.mjs.map} +1 -1
- package/dist/chunk-YQTE32QK.js +137 -0
- package/dist/chunk-YQTE32QK.js.map +1 -0
- package/dist/{chunk-DVH3JHZ3.mjs → chunk-ZDFVYSKK.mjs} +4 -4
- package/dist/{chunk-DVH3JHZ3.mjs.map → chunk-ZDFVYSKK.mjs.map} +1 -1
- package/dist/{chunk-GFNXWS3I.js → chunk-ZLPXFV5Y.js} +5 -5
- package/dist/{chunk-GFNXWS3I.js.map → chunk-ZLPXFV5Y.js.map} +1 -1
- package/dist/{chunk-W23TMUKB.js → chunk-ZY5AVC4P.js} +418 -98
- package/dist/chunk-ZY5AVC4P.js.map +1 -0
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.mjs +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/commerce/index.js +56 -56
- package/dist/commerce/index.mjs +5 -5
- package/dist/engage/index.js +10 -10
- package/dist/engage/index.mjs +7 -7
- 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/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +63 -63
- package/dist/index.mjs +9 -9
- 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/llms/index.js +12 -12
- package/dist/llms/index.mjs +2 -2
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +5 -5
- package/dist/seo/index.mjs +4 -4
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/version.d.ts +1 -1
- 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/package.json +1 -1
- 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/chunk-67CHHDBL.mjs.map +0 -1
- package/dist/chunk-A3NNUKFA.js.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-HVFXFPUJ.mjs.map +0 -1
- package/dist/chunk-JBGRXICL.js.map +0 -1
- package/dist/chunk-OUERH2T4.mjs +0 -6
- package/dist/chunk-TPL2IHFI.js +0 -43
- package/dist/chunk-TPL2IHFI.js.map +0 -1
- package/dist/chunk-W23TMUKB.js.map +0 -1
|
@@ -1,10 +1,85 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkGQ6CUOLA_js = require('./chunk-GQ6CUOLA.js');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
|
|
8
|
+
function MeetingFormatStep({ options, busy, format, address, onFormatChange, onAddressChange, onContinue, onBack }) {
|
|
9
|
+
const id = react.useId();
|
|
10
|
+
const choices = [
|
|
11
|
+
{ value: "virtual", label: "Virtual", description: "Meet online with a Google Meet link." },
|
|
12
|
+
{ value: "office", label: "Come to us", description: "Meet in person at our office." },
|
|
13
|
+
{ 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.` }
|
|
14
|
+
];
|
|
15
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: (e) => {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
if (format) onContinue(format, format === "client_location" ? address : void 0);
|
|
18
|
+
}, className: "bw-step sk-meeting-step", children: [
|
|
19
|
+
onBack && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "bw-back sk-meeting-change", onClick: onBack, disabled: busy, children: "\u2190 Change service" }),
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: "How would you like to meet?" }),
|
|
21
|
+
/* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: busy, className: "sk-meeting-choices", children: [
|
|
22
|
+
/* @__PURE__ */ jsxRuntime.jsx("legend", { className: "sk-meeting-legend", children: "Meeting format" }),
|
|
23
|
+
choices.map((choice) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `sk-meeting-choice ${format === choice.value ? "sk-meeting-selected" : ""}`, children: [
|
|
24
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", { type: "radio", name: `${id}-format`, value: choice.value, checked: format === choice.value, onChange: () => onFormatChange(choice.value), required: true }),
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
26
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: choice.label }),
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: choice.description })
|
|
28
|
+
] })
|
|
29
|
+
] }, choice.value))
|
|
30
|
+
] }),
|
|
31
|
+
format === "office" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sk-meeting-address", children: [
|
|
32
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: options.office_address }),
|
|
33
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: options.office_instructions }),
|
|
34
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(options.office_address)}`, target: "_blank", rel: "noopener noreferrer", children: "Get directions" })
|
|
35
|
+
] }),
|
|
36
|
+
format === "client_location" && /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: busy, className: "bw-form sk-meeting-fields", children: [
|
|
37
|
+
/* @__PURE__ */ jsxRuntime.jsx("legend", { children: "Your meeting address" }),
|
|
38
|
+
[
|
|
39
|
+
["street", "Street address", "street-address"],
|
|
40
|
+
["unit", "Suite or unit (optional)", "address-line2"],
|
|
41
|
+
["city", "City", "address-level2"],
|
|
42
|
+
["region", "State or region", "address-level1"],
|
|
43
|
+
["postalCode", "Postal code", "postal-code"],
|
|
44
|
+
["country", "Country", "country-name"]
|
|
45
|
+
].map(([key, label, autocomplete]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-field", children: [
|
|
46
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `${id}-${key}`, children: label }),
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
48
|
+
"input",
|
|
49
|
+
{
|
|
50
|
+
id: `${id}-${key}`,
|
|
51
|
+
value: address[key],
|
|
52
|
+
required: key !== "unit",
|
|
53
|
+
maxLength: 200,
|
|
54
|
+
autoComplete: autocomplete,
|
|
55
|
+
onChange: (e) => onAddressChange({ ...address, [key]: e.target.value })
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
] }, key)),
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-field", children: [
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `${id}-notes`, children: "Parking or access notes (optional)" }),
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("textarea", { id: `${id}-notes`, value: address.notes, maxLength: 2e3, onChange: (e) => onAddressChange({ ...address, notes: e.target.value }) })
|
|
62
|
+
] }),
|
|
63
|
+
options.travel_review_required && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "We\u2019ll reserve your requested time and confirm after checking travel arrangements." })
|
|
64
|
+
] }),
|
|
65
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-submit", type: "submit", disabled: !format || busy, children: busy ? "Checking meeting details\u2026" : "Choose a time" }),
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
67
|
+
.sk-meeting-choices { border: 0; padding: 0; margin: 20px 0; display: grid; gap: 10px; }
|
|
68
|
+
.sk-meeting-legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
|
|
69
|
+
.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); }
|
|
70
|
+
.sk-meeting-choice input { margin-top: 4px; accent-color: var(--sk-primary); }
|
|
71
|
+
.sk-meeting-choice strong { display: block; color: var(--sk-text-primary); }
|
|
72
|
+
.sk-meeting-choice span span { display: block; margin-top: 4px; font-size: 14px; color: var(--sk-text-secondary); }
|
|
73
|
+
.sk-meeting-selected { border-color: var(--sk-primary); background: var(--sk-primary-light); }
|
|
74
|
+
.sk-meeting-address { padding: 16px; background: var(--sk-surface); border-radius: var(--sk-radius); margin-bottom: 16px; white-space: pre-wrap; }
|
|
75
|
+
.sk-meeting-address a { display: inline-block; margin-top: 8px; color: var(--sk-primary); }
|
|
76
|
+
.sk-meeting-fields { border: 0; padding: 0; margin-bottom: 20px; }
|
|
77
|
+
.sk-meeting-fields legend { margin-bottom: 12px; font-weight: 600; }
|
|
78
|
+
.sk-meeting-step .bw-submit { width: 100%; }
|
|
79
|
+
` })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
|
|
8
83
|
// src/sync/api.ts
|
|
9
84
|
var DEFAULT_API_URL = "https://api.sonor.io";
|
|
10
85
|
function getApiConfig() {
|
|
@@ -22,7 +97,7 @@ async function fetchBookingTypes(orgSlug, apiUrl, apiKey) {
|
|
|
22
97
|
const url = apiUrl || cfg.apiUrl;
|
|
23
98
|
const key = apiKey || cfg.apiKey;
|
|
24
99
|
const endpoint = key ? `${url}/sync/widget/types` : `${url}/sync/public/${orgSlug}/types`;
|
|
25
|
-
const response = await
|
|
100
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
26
101
|
if (!response.ok) {
|
|
27
102
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
28
103
|
const detail = msg && typeof msg.message === "string" ? msg.message : response.statusText;
|
|
@@ -36,7 +111,7 @@ async function fetchBookingTypeDetails(typeSlug, orgSlug, apiUrl, apiKey) {
|
|
|
36
111
|
const url = apiUrl || cfg.apiUrl;
|
|
37
112
|
const key = apiKey || cfg.apiKey;
|
|
38
113
|
const endpoint = key ? `${url}/sync/widget/types/${typeSlug}` : `${url}/sync/public/${orgSlug}/types/${typeSlug}`;
|
|
39
|
-
const response = await
|
|
114
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
40
115
|
if (!response.ok) {
|
|
41
116
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
42
117
|
const detail = msg && typeof msg.message === "string" ? msg.message : response.statusText;
|
|
@@ -44,15 +119,16 @@ async function fetchBookingTypeDetails(typeSlug, orgSlug, apiUrl, apiKey) {
|
|
|
44
119
|
}
|
|
45
120
|
return response.json();
|
|
46
121
|
}
|
|
47
|
-
async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezone, hostId) {
|
|
122
|
+
async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezone, hostId, meetingToken) {
|
|
48
123
|
const cfg = getApiConfig();
|
|
49
124
|
const url = apiUrl || cfg.apiUrl;
|
|
50
125
|
const key = apiKey || cfg.apiKey;
|
|
51
126
|
const params = new URLSearchParams({ date });
|
|
52
127
|
if (timezone) params.append("timezone", timezone);
|
|
53
128
|
if (hostId) params.append("hostId", hostId);
|
|
129
|
+
if (meetingToken) params.append("meetingToken", meetingToken);
|
|
54
130
|
const endpoint = key ? `${url}/sync/widget/availability/${typeSlug}?${params}` : `${url}/sync/public/${orgSlug}/availability/${typeSlug}?${params}`;
|
|
55
|
-
const response = await
|
|
131
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, { headers: buildHeaders() }, { apiKey: key, retries: 0 });
|
|
56
132
|
if (!response.ok) {
|
|
57
133
|
const msg = await response.json().catch(() => ({ message: response.statusText }));
|
|
58
134
|
let detail = msg && typeof msg.message === "string" ? String(msg.message).trim() : (response.statusText || "").trim();
|
|
@@ -70,18 +146,23 @@ async function fetchAvailability(typeSlug, date, orgSlug, apiUrl, apiKey, timezo
|
|
|
70
146
|
available: slot.available !== false
|
|
71
147
|
}));
|
|
72
148
|
}
|
|
149
|
+
async function bookingRequestError(response, fallback) {
|
|
150
|
+
const body = await response.json().catch(() => ({}));
|
|
151
|
+
const message = Array.isArray(body.message) ? body.message.join(". ") : body.message;
|
|
152
|
+
return new Error(typeof message === "string" && message.trim() ? message : fallback);
|
|
153
|
+
}
|
|
73
154
|
async function createSlotHold(holdData, apiUrl, apiKey) {
|
|
74
155
|
const cfg = getApiConfig();
|
|
75
156
|
const url = apiUrl || cfg.apiUrl;
|
|
76
157
|
const key = apiKey || cfg.apiKey;
|
|
77
158
|
const endpoint = key ? `${url}/sync/widget/hold` : `${url}/sync/public/hold`;
|
|
78
|
-
const response = await
|
|
159
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, {
|
|
79
160
|
method: "POST",
|
|
80
161
|
headers: buildHeaders(true),
|
|
81
162
|
body: JSON.stringify(holdData)
|
|
82
163
|
}, { apiKey: key, retries: 0 });
|
|
83
164
|
if (!response.ok) {
|
|
84
|
-
throw
|
|
165
|
+
throw await bookingRequestError(response, "We couldn\u2019t reserve that time. Please choose another time.");
|
|
85
166
|
}
|
|
86
167
|
return response.json();
|
|
87
168
|
}
|
|
@@ -90,7 +171,7 @@ async function releaseSlotHold(holdId, apiUrl, apiKey) {
|
|
|
90
171
|
const url = apiUrl || cfg.apiUrl;
|
|
91
172
|
const key = apiKey || cfg.apiKey;
|
|
92
173
|
const endpoint = key ? `${url}/sync/widget/hold/${holdId}` : `${url}/sync/public/hold/${holdId}`;
|
|
93
|
-
await
|
|
174
|
+
await chunkGQ6CUOLA_js.sonorFetch(endpoint, {
|
|
94
175
|
method: "DELETE",
|
|
95
176
|
headers: buildHeaders()
|
|
96
177
|
}, { apiKey: key, retries: 0 });
|
|
@@ -100,18 +181,17 @@ async function createBooking(bookingData, apiUrl, apiKey) {
|
|
|
100
181
|
const url = apiUrl || cfg.apiUrl;
|
|
101
182
|
const key = apiKey || cfg.apiKey;
|
|
102
183
|
const endpoint = key ? `${url}/sync/widget/booking` : `${url}/sync/public/booking`;
|
|
103
|
-
const response = await
|
|
184
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, {
|
|
104
185
|
method: "POST",
|
|
105
186
|
headers: buildHeaders(true),
|
|
106
187
|
body: JSON.stringify(bookingData)
|
|
107
188
|
}, { apiKey: key, retries: 0 });
|
|
108
189
|
if (!response.ok) {
|
|
109
|
-
|
|
110
|
-
throw new Error(errorData.message || `Failed to create booking: ${response.statusText}`);
|
|
190
|
+
throw await bookingRequestError(response, "We couldn\u2019t complete your booking. Please try again.");
|
|
111
191
|
}
|
|
112
192
|
return response.json();
|
|
113
193
|
}
|
|
114
|
-
async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl, apiKey, timezone) {
|
|
194
|
+
async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl, apiKey, timezone, meetingToken) {
|
|
115
195
|
const availableDates = [];
|
|
116
196
|
const start = new Date(startDate);
|
|
117
197
|
const end = new Date(endDate);
|
|
@@ -119,7 +199,7 @@ async function fetchAvailableDates(typeSlug, startDate, endDate, orgSlug, apiUrl
|
|
|
119
199
|
while (current <= end) {
|
|
120
200
|
const dateStr = current.toISOString().split("T")[0];
|
|
121
201
|
try {
|
|
122
|
-
const slots = await fetchAvailability(typeSlug, dateStr, orgSlug, apiUrl, apiKey, timezone);
|
|
202
|
+
const slots = await fetchAvailability(typeSlug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meetingToken);
|
|
123
203
|
if (slots.some((s) => s.available)) {
|
|
124
204
|
availableDates.push(dateStr);
|
|
125
205
|
}
|
|
@@ -166,6 +246,33 @@ function formatDuration(minutes) {
|
|
|
166
246
|
}
|
|
167
247
|
return `${hours}h ${mins}m`;
|
|
168
248
|
}
|
|
249
|
+
async function prepareMeeting(bookingType, format, address, orgSlug, apiUrl, apiKey) {
|
|
250
|
+
const cfg = getApiConfig();
|
|
251
|
+
const url = apiUrl || cfg.apiUrl;
|
|
252
|
+
const key = apiKey || cfg.apiKey;
|
|
253
|
+
const endpoint = key ? `${url}/sync/widget/meeting` : `${url}/sync/public/${orgSlug}/meeting`;
|
|
254
|
+
const response = await chunkGQ6CUOLA_js.sonorFetch(endpoint, {
|
|
255
|
+
method: "POST",
|
|
256
|
+
headers: buildHeaders(true),
|
|
257
|
+
body: JSON.stringify({ bookingType, format, address })
|
|
258
|
+
}, { apiKey: key, retries: 0 });
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
throw await bookingRequestError(response, "We couldn\u2019t check your meeting details. Please try again.");
|
|
261
|
+
}
|
|
262
|
+
return response.json();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/sync/booking-flow.ts
|
|
266
|
+
function expiredBookingContext(meeting, hold, now = Date.now()) {
|
|
267
|
+
if (hold) return Date.parse(hold.expiresAt) <= now ? "hold" : null;
|
|
268
|
+
return meeting && Date.parse(meeting.expiresAt) <= now ? "meeting" : null;
|
|
269
|
+
}
|
|
270
|
+
function bookingRecoveryFromError(error) {
|
|
271
|
+
const message = error instanceof Error ? error.message : "";
|
|
272
|
+
if (/meeting details expired|choose how you.d like to meet first/i.test(message)) return "meeting";
|
|
273
|
+
if (/time reservation expired|invalid slot hold|meeting details changed/i.test(message)) return "hold";
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
169
276
|
var DEFAULT_API_URL2 = "https://api.sonor.io";
|
|
170
277
|
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
171
278
|
var MONTHS = [
|
|
@@ -277,6 +384,17 @@ function BookingWidget({
|
|
|
277
384
|
const [guestInfo, setGuestInfo] = react.useState({ name: "", email: "" });
|
|
278
385
|
const [bookingResult, setBookingResult] = react.useState(null);
|
|
279
386
|
const [submitting, setSubmitting] = react.useState(false);
|
|
387
|
+
const [meeting, setMeeting] = react.useState(null);
|
|
388
|
+
const [meetingFormat, setMeetingFormat] = react.useState(null);
|
|
389
|
+
const [meetingAddress, setMeetingAddress] = react.useState({ street: "", city: "", region: "", postalCode: "", country: "United States", unit: "", notes: "" });
|
|
390
|
+
const [recovery, setRecovery] = react.useState(null);
|
|
391
|
+
const [sessionId] = react.useState(() => `bw-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
392
|
+
const requestRef = react.useRef(0);
|
|
393
|
+
const busyRef = react.useRef(false);
|
|
394
|
+
const bookingInFlightRef = react.useRef(false);
|
|
395
|
+
const holdRef = react.useRef(null);
|
|
396
|
+
const onErrorRef = react.useRef(onError);
|
|
397
|
+
onErrorRef.current = onError;
|
|
280
398
|
const [autoProbing, setAutoProbing] = react.useState(false);
|
|
281
399
|
const probeRef = react.useRef(0);
|
|
282
400
|
const prefetchedRef = react.useRef(null);
|
|
@@ -301,26 +419,79 @@ function BookingWidget({
|
|
|
301
419
|
d.setDate(d.getDate() + daysToShow);
|
|
302
420
|
return d;
|
|
303
421
|
}, [today, daysToShow]);
|
|
422
|
+
const setActiveHold = react.useCallback((value) => {
|
|
423
|
+
holdRef.current = value;
|
|
424
|
+
setHold(value);
|
|
425
|
+
}, []);
|
|
426
|
+
const resetScheduling = react.useCallback((nextStep, clearMeeting = false) => {
|
|
427
|
+
++requestRef.current;
|
|
428
|
+
const previous = holdRef.current;
|
|
429
|
+
setActiveHold(null);
|
|
430
|
+
if (previous) releaseSlotHold(previous.holdId, apiUrl, apiKey).catch(() => {
|
|
431
|
+
});
|
|
432
|
+
setSelectedDate(null);
|
|
433
|
+
setSelectedSlot(null);
|
|
434
|
+
setConfirmedSlot(false);
|
|
435
|
+
setSlots([]);
|
|
436
|
+
setSlotsLoading(false);
|
|
437
|
+
prefetchedRef.current = null;
|
|
438
|
+
if (clearMeeting) setMeeting(null);
|
|
439
|
+
setRecovery(null);
|
|
440
|
+
setError(null);
|
|
441
|
+
setStep(nextStep);
|
|
442
|
+
}, [apiUrl, apiKey, setActiveHold]);
|
|
443
|
+
const reportRequestError = react.useCallback((err) => {
|
|
444
|
+
setRecovery(bookingRecoveryFromError(err));
|
|
445
|
+
setError(err.message);
|
|
446
|
+
onErrorRef.current?.(err);
|
|
447
|
+
}, []);
|
|
448
|
+
react.useEffect(() => () => {
|
|
449
|
+
++requestRef.current;
|
|
450
|
+
if (holdRef.current && !bookingInFlightRef.current) {
|
|
451
|
+
releaseSlotHold(holdRef.current.holdId, apiUrl, apiKey).catch(() => {
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
holdRef.current = null;
|
|
455
|
+
}, [apiUrl, apiKey]);
|
|
304
456
|
react.useEffect(() => {
|
|
457
|
+
let cancelled = false;
|
|
458
|
+
++requestRef.current;
|
|
459
|
+
busyRef.current = false;
|
|
460
|
+
bookingInFlightRef.current = false;
|
|
461
|
+
resetScheduling(bookingTypeSlug ? "datetime" : "type", true);
|
|
462
|
+
setSelectedType(null);
|
|
463
|
+
setMeetingFormat(null);
|
|
464
|
+
setBookingResult(null);
|
|
465
|
+
setSubmitting(false);
|
|
305
466
|
if (bookingTypeSlug) {
|
|
306
467
|
setLoading(true);
|
|
307
468
|
fetchBookingTypeDetails(bookingTypeSlug, orgSlug, apiUrl, apiKey).then((type) => {
|
|
308
|
-
|
|
309
|
-
|
|
469
|
+
if (!cancelled) {
|
|
470
|
+
setSelectedType(type);
|
|
471
|
+
setStep(type.meeting_options ? "format" : "datetime");
|
|
472
|
+
}
|
|
310
473
|
}).catch((err) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
474
|
+
if (!cancelled) reportRequestError(err);
|
|
475
|
+
}).finally(() => {
|
|
476
|
+
if (!cancelled) setLoading(false);
|
|
477
|
+
});
|
|
314
478
|
} else {
|
|
315
479
|
setLoading(true);
|
|
316
|
-
fetchBookingTypes(orgSlug, apiUrl, apiKey).then((types) =>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
480
|
+
fetchBookingTypes(orgSlug, apiUrl, apiKey).then((types) => {
|
|
481
|
+
if (!cancelled) setBookingTypes(types.filter((t) => t.is_active));
|
|
482
|
+
}).catch((err) => {
|
|
483
|
+
if (!cancelled) reportRequestError(err);
|
|
484
|
+
}).finally(() => {
|
|
485
|
+
if (!cancelled) setLoading(false);
|
|
486
|
+
});
|
|
320
487
|
}
|
|
321
|
-
|
|
488
|
+
return () => {
|
|
489
|
+
cancelled = true;
|
|
490
|
+
++requestRef.current;
|
|
491
|
+
};
|
|
492
|
+
}, [orgSlug, apiKey, bookingTypeSlug, apiUrl, resetScheduling, reportRequestError]);
|
|
322
493
|
react.useEffect(() => {
|
|
323
|
-
if (!selectedDate || !selectedType) return;
|
|
494
|
+
if (!selectedDate || !selectedType || selectedType.meeting_options && !meeting) return;
|
|
324
495
|
const dateStr = toLocalDateStr(selectedDate);
|
|
325
496
|
setSelectedSlot(null);
|
|
326
497
|
setConfirmedSlot(false);
|
|
@@ -331,15 +502,22 @@ function BookingWidget({
|
|
|
331
502
|
setSlotsLoading(false);
|
|
332
503
|
return;
|
|
333
504
|
}
|
|
505
|
+
let cancelled = false;
|
|
334
506
|
setSlotsLoading(true);
|
|
335
507
|
setSlots([]);
|
|
336
|
-
fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
508
|
+
fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meeting?.meetingToken).then((s) => {
|
|
509
|
+
if (!cancelled) setSlots(s.filter((slot) => slot.available));
|
|
510
|
+
}).catch((err) => {
|
|
511
|
+
if (!cancelled) reportRequestError(err);
|
|
512
|
+
}).finally(() => {
|
|
513
|
+
if (!cancelled) setSlotsLoading(false);
|
|
514
|
+
});
|
|
515
|
+
return () => {
|
|
516
|
+
cancelled = true;
|
|
517
|
+
};
|
|
518
|
+
}, [selectedDate, selectedType, orgSlug, apiKey, apiUrl, timezone, reportRequestError, meeting]);
|
|
341
519
|
react.useEffect(() => {
|
|
342
|
-
if (!autoSelectFirstDay || !selectedType || selectedDate) return;
|
|
520
|
+
if (!autoSelectFirstDay || !selectedType || selectedDate || step !== "datetime" || recovery || selectedType.meeting_options && !meeting) return;
|
|
343
521
|
const probeId = ++probeRef.current;
|
|
344
522
|
let cancelled = false;
|
|
345
523
|
const PROBE_DAYS = 14;
|
|
@@ -352,7 +530,7 @@ function BookingWidget({
|
|
|
352
530
|
d.setDate(d.getDate() + i);
|
|
353
531
|
if (d > maxDate) break;
|
|
354
532
|
const dateStr = toLocalDateStr(d);
|
|
355
|
-
const s = await fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone);
|
|
533
|
+
const s = await fetchAvailability(selectedType.slug, dateStr, orgSlug, apiUrl, apiKey, timezone, void 0, meeting?.meetingToken);
|
|
356
534
|
if (cancelled || probeRef.current !== probeId) return;
|
|
357
535
|
const open = s.filter((slot) => slot.available);
|
|
358
536
|
if (open.length > 0) {
|
|
@@ -362,7 +540,8 @@ function BookingWidget({
|
|
|
362
540
|
return;
|
|
363
541
|
}
|
|
364
542
|
}
|
|
365
|
-
} catch {
|
|
543
|
+
} catch (err) {
|
|
544
|
+
if (!cancelled && bookingRecoveryFromError(err)) reportRequestError(err);
|
|
366
545
|
} finally {
|
|
367
546
|
if (!cancelled && probeRef.current === probeId) setAutoProbing(false);
|
|
368
547
|
}
|
|
@@ -371,46 +550,92 @@ function BookingWidget({
|
|
|
371
550
|
cancelled = true;
|
|
372
551
|
setAutoProbing(false);
|
|
373
552
|
};
|
|
374
|
-
}, [autoSelectFirstDay, selectedType, selectedDate, orgSlug, apiKey, apiUrl, timezone, today, maxDate]);
|
|
553
|
+
}, [autoSelectFirstDay, selectedType, selectedDate, orgSlug, apiKey, apiUrl, timezone, today, maxDate, step, meeting, recovery, reportRequestError]);
|
|
554
|
+
react.useEffect(() => {
|
|
555
|
+
if (step !== "datetime" && step !== "form" || loading || submitting) return;
|
|
556
|
+
const expiry = hold?.expiresAt || meeting?.expiresAt;
|
|
557
|
+
if (!expiry || !Number.isFinite(Date.parse(expiry))) return;
|
|
558
|
+
const checkExpiry = () => {
|
|
559
|
+
const expired = expiredBookingContext(meeting, hold);
|
|
560
|
+
if (!busyRef.current && expired) setRecovery(expired);
|
|
561
|
+
};
|
|
562
|
+
const timer = setTimeout(checkExpiry, Math.max(0, Date.parse(expiry) - Date.now()));
|
|
563
|
+
window.addEventListener("focus", checkExpiry);
|
|
564
|
+
return () => {
|
|
565
|
+
clearTimeout(timer);
|
|
566
|
+
window.removeEventListener("focus", checkExpiry);
|
|
567
|
+
};
|
|
568
|
+
}, [meeting, hold, step, loading, submitting]);
|
|
375
569
|
const handleSlotSelect = react.useCallback((slot) => {
|
|
570
|
+
if (busyRef.current) return;
|
|
376
571
|
setSelectedSlot(slot);
|
|
377
572
|
setConfirmedSlot(false);
|
|
378
573
|
}, []);
|
|
379
574
|
const handleSlotConfirm = react.useCallback(async () => {
|
|
380
|
-
if (!selectedType || !selectedSlot) return;
|
|
381
|
-
|
|
382
|
-
|
|
575
|
+
if (!selectedType || !selectedSlot || busyRef.current || recovery) return;
|
|
576
|
+
const expired = expiredBookingContext(meeting, null);
|
|
577
|
+
if (expired) {
|
|
578
|
+
setRecovery(expired);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const requestId = ++requestRef.current;
|
|
582
|
+
busyRef.current = true;
|
|
383
583
|
setLoading(true);
|
|
584
|
+
setError(null);
|
|
384
585
|
try {
|
|
586
|
+
const previous = holdRef.current;
|
|
587
|
+
setActiveHold(null);
|
|
588
|
+
if (previous) await releaseSlotHold(previous.holdId, apiUrl, apiKey).catch(() => {
|
|
589
|
+
});
|
|
590
|
+
if (requestId !== requestRef.current) return;
|
|
385
591
|
const newHold = await createSlotHold(
|
|
386
592
|
{
|
|
593
|
+
meetingToken: meeting?.meetingToken,
|
|
594
|
+
org: apiKey ? void 0 : orgSlug,
|
|
387
595
|
bookingType: selectedType.slug,
|
|
388
596
|
slotStart: selectedSlot.start,
|
|
389
597
|
slotEnd: selectedSlot.end,
|
|
390
598
|
hostId: selectedSlot.hostId || "",
|
|
391
|
-
sessionId
|
|
599
|
+
sessionId
|
|
392
600
|
},
|
|
393
601
|
apiUrl,
|
|
394
602
|
apiKey
|
|
395
603
|
);
|
|
396
|
-
|
|
604
|
+
if (requestId !== requestRef.current) {
|
|
605
|
+
await releaseSlotHold(newHold.holdId, apiUrl, apiKey).catch(() => {
|
|
606
|
+
});
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
setActiveHold(newHold);
|
|
397
610
|
setConfirmedSlot(true);
|
|
398
611
|
setStep("form");
|
|
399
612
|
} catch (err) {
|
|
400
|
-
|
|
401
|
-
onError?.(err);
|
|
613
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
402
614
|
} finally {
|
|
403
|
-
|
|
615
|
+
if (requestId === requestRef.current) {
|
|
616
|
+
busyRef.current = false;
|
|
617
|
+
setLoading(false);
|
|
618
|
+
}
|
|
404
619
|
}
|
|
405
|
-
}, [selectedType, selectedSlot,
|
|
620
|
+
}, [selectedType, selectedSlot, apiUrl, apiKey, meeting, sessionId, orgSlug, recovery, setActiveHold, reportRequestError]);
|
|
406
621
|
const handleBookingSubmit = react.useCallback(async (e) => {
|
|
407
622
|
e.preventDefault();
|
|
408
|
-
if (!selectedType || !selectedSlot) return;
|
|
623
|
+
if (!selectedType || !selectedSlot || busyRef.current || recovery) return;
|
|
624
|
+
const expired = expiredBookingContext(meeting, hold);
|
|
625
|
+
if (expired) {
|
|
626
|
+
setRecovery(expired);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
const requestId = ++requestRef.current;
|
|
630
|
+
busyRef.current = true;
|
|
631
|
+
bookingInFlightRef.current = true;
|
|
409
632
|
setSubmitting(true);
|
|
410
633
|
setError(null);
|
|
411
634
|
try {
|
|
412
635
|
const result = await createBooking(
|
|
413
636
|
{
|
|
637
|
+
meetingToken: meeting?.meetingToken,
|
|
638
|
+
org: apiKey ? void 0 : orgSlug,
|
|
414
639
|
bookingType: selectedType.slug,
|
|
415
640
|
scheduledAt: selectedSlot.start,
|
|
416
641
|
hostId: selectedSlot.hostId || "",
|
|
@@ -421,31 +646,82 @@ function BookingWidget({
|
|
|
421
646
|
source: "main-site",
|
|
422
647
|
timezone,
|
|
423
648
|
holdId: hold?.holdId,
|
|
424
|
-
sessionId
|
|
649
|
+
sessionId,
|
|
425
650
|
sourceUrl: typeof window !== "undefined" ? window.location.href : void 0
|
|
426
651
|
},
|
|
427
652
|
apiUrl,
|
|
428
653
|
apiKey
|
|
429
654
|
);
|
|
655
|
+
if (requestId !== requestRef.current) return;
|
|
656
|
+
setActiveHold(null);
|
|
430
657
|
setBookingResult(result);
|
|
431
658
|
setStep("success");
|
|
432
659
|
onBookingComplete?.(result);
|
|
433
660
|
} catch (err) {
|
|
434
|
-
|
|
435
|
-
|
|
661
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
662
|
+
else if (hold) releaseSlotHold(hold.holdId, apiUrl, apiKey).catch(() => {
|
|
663
|
+
});
|
|
436
664
|
} finally {
|
|
437
|
-
|
|
665
|
+
if (requestId === requestRef.current) {
|
|
666
|
+
busyRef.current = false;
|
|
667
|
+
bookingInFlightRef.current = false;
|
|
668
|
+
setSubmitting(false);
|
|
669
|
+
}
|
|
438
670
|
}
|
|
439
|
-
}, [selectedType, selectedSlot, guestInfo, timezone, hold, apiUrl, apiKey, onBookingComplete,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
671
|
+
}, [selectedType, selectedSlot, guestInfo, timezone, hold, apiUrl, apiKey, onBookingComplete, meeting, sessionId, orgSlug, recovery, setActiveHold, reportRequestError]);
|
|
672
|
+
const chooseFormat = async (format, address) => {
|
|
673
|
+
if (!selectedType || busyRef.current) return;
|
|
674
|
+
const requestId = ++requestRef.current;
|
|
675
|
+
busyRef.current = true;
|
|
676
|
+
setLoading(true);
|
|
677
|
+
setError(null);
|
|
678
|
+
try {
|
|
679
|
+
const prepared = await prepareMeeting(selectedType.slug, format, address, orgSlug, apiUrl, apiKey);
|
|
680
|
+
if (requestId !== requestRef.current) return;
|
|
681
|
+
setMeeting(prepared);
|
|
682
|
+
setRecovery(null);
|
|
683
|
+
setSelectedDate(null);
|
|
684
|
+
setSelectedSlot(null);
|
|
685
|
+
prefetchedRef.current = null;
|
|
686
|
+
setStep("datetime");
|
|
687
|
+
} catch (err) {
|
|
688
|
+
if (requestId === requestRef.current) reportRequestError(err);
|
|
689
|
+
} finally {
|
|
690
|
+
if (requestId === requestRef.current) {
|
|
691
|
+
busyRef.current = false;
|
|
692
|
+
setLoading(false);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
const changeFormat = () => {
|
|
697
|
+
if (!busyRef.current) resetScheduling("format", true);
|
|
698
|
+
};
|
|
699
|
+
const changeService = () => {
|
|
700
|
+
if (busyRef.current) return;
|
|
701
|
+
resetScheduling("type", true);
|
|
702
|
+
setSelectedType(null);
|
|
703
|
+
setMeetingFormat(null);
|
|
704
|
+
};
|
|
705
|
+
const recoverReservation = () => {
|
|
706
|
+
if (busyRef.current) return;
|
|
707
|
+
const needsMeeting = recovery === "meeting" || expiredBookingContext(meeting, null) === "meeting";
|
|
708
|
+
resetScheduling(needsMeeting ? "format" : "datetime", needsMeeting);
|
|
709
|
+
};
|
|
710
|
+
const displayType = selectedType ? {
|
|
711
|
+
...selectedType,
|
|
712
|
+
...meeting ? { location_type: meeting.location_type, location_details: meeting.location_details, location_instructions: meeting.location_instructions } : {},
|
|
713
|
+
...bookingResult ? {
|
|
714
|
+
location_type: bookingResult.booking.location_type || selectedType.location_type,
|
|
715
|
+
location_details: bookingResult.booking.location_details,
|
|
716
|
+
location_instructions: bookingResult.booking.location_instructions,
|
|
717
|
+
video_link: bookingResult.booking.video_link
|
|
718
|
+
} : {}
|
|
719
|
+
} : null;
|
|
720
|
+
const isPending = bookingResult?.booking.status === "pending";
|
|
446
721
|
const canGoPrev = viewMonth.getFullYear() > today.getFullYear() || viewMonth.getMonth() > today.getMonth();
|
|
447
722
|
const canGoNext = viewMonth < maxDate;
|
|
448
723
|
const goMonth = (dir) => {
|
|
724
|
+
if (busyRef.current) return;
|
|
449
725
|
setViewMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + dir, 1));
|
|
450
726
|
};
|
|
451
727
|
const groupedSlots = react.useMemo(() => {
|
|
@@ -480,10 +756,17 @@ function BookingWidget({
|
|
|
480
756
|
"--sk-input-focus-ring": styles.primaryColor ? `color-mix(in srgb, ${styles.primaryColor} 12%, ${styles.backgroundColor || "white"})` : "#e8f1ff"
|
|
481
757
|
};
|
|
482
758
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bw-root ${className}`, style: cssVars, children: [
|
|
483
|
-
error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-error", role: "alert", children: [
|
|
759
|
+
error && !recovery && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-error", role: "alert", children: [
|
|
484
760
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: error }),
|
|
485
761
|
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setError(null), "aria-label": "Dismiss error", children: "\xD7" })
|
|
486
762
|
] }),
|
|
763
|
+
recovery && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sk-booking-recovery", role: "alert", children: [
|
|
764
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
765
|
+
recovery === "meeting" ? "Your meeting details need to be checked again." : "Your time reservation expired. Choose a time to continue.",
|
|
766
|
+
" Your entered details are saved."
|
|
767
|
+
] }),
|
|
768
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "bw-submit", onClick: recoverReservation, disabled: loading || submitting, children: recovery === "meeting" ? "Review meeting details" : "Choose another time" })
|
|
769
|
+
] }),
|
|
487
770
|
step === "type" && !hideTypeSelector && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
488
771
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: "Select a Service" }),
|
|
489
772
|
loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-loading", children: [
|
|
@@ -494,8 +777,10 @@ function BookingWidget({
|
|
|
494
777
|
{
|
|
495
778
|
className: "bw-type-card",
|
|
496
779
|
onClick: () => {
|
|
497
|
-
|
|
498
|
-
|
|
780
|
+
if (!busyRef.current) {
|
|
781
|
+
resetScheduling(type.meeting_options ? "format" : "datetime", true);
|
|
782
|
+
setSelectedType(type);
|
|
783
|
+
}
|
|
499
784
|
},
|
|
500
785
|
children: [
|
|
501
786
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-type-name", children: type.name }),
|
|
@@ -512,12 +797,23 @@ function BookingWidget({
|
|
|
512
797
|
type.id
|
|
513
798
|
)) })
|
|
514
799
|
] }),
|
|
800
|
+
step === "format" && selectedType?.meeting_options && /* @__PURE__ */ jsxRuntime.jsx(
|
|
801
|
+
MeetingFormatStep,
|
|
802
|
+
{
|
|
803
|
+
options: selectedType.meeting_options,
|
|
804
|
+
busy: loading,
|
|
805
|
+
format: meetingFormat,
|
|
806
|
+
address: meetingAddress,
|
|
807
|
+
onFormatChange: setMeetingFormat,
|
|
808
|
+
onAddressChange: setMeetingAddress,
|
|
809
|
+
onContinue: chooseFormat,
|
|
810
|
+
onBack: !bookingTypeSlug && !hideTypeSelector ? changeService : void 0
|
|
811
|
+
}
|
|
812
|
+
),
|
|
813
|
+
selectedType?.meeting_options && (step === "datetime" || step === "form") && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "bw-back sk-meeting-change", onClick: changeFormat, disabled: loading || submitting, children: "\u2190 Change meeting format" }),
|
|
515
814
|
step === "datetime" && selectedType && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
516
815
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-info-header", children: [
|
|
517
|
-
!bookingTypeSlug && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-back", onClick: ()
|
|
518
|
-
setSelectedType(null);
|
|
519
|
-
setStep("type");
|
|
520
|
-
}, children: /* @__PURE__ */ jsxRuntime.jsx(ArrowLeftIcon, {}) }),
|
|
816
|
+
!bookingTypeSlug && !hideTypeSelector && /* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-back", onClick: changeService, disabled: loading, "aria-label": "Change service", children: /* @__PURE__ */ jsxRuntime.jsx(ArrowLeftIcon, {}) }),
|
|
521
817
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
522
818
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: selectedType.name }),
|
|
523
819
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-meta-row", children: [
|
|
@@ -531,34 +827,36 @@ function BookingWidget({
|
|
|
531
827
|
" ",
|
|
532
828
|
shortTz
|
|
533
829
|
] }),
|
|
534
|
-
/* @__PURE__ */ jsxRuntime.jsx(LocationBadge, { type:
|
|
830
|
+
/* @__PURE__ */ jsxRuntime.jsx(LocationBadge, { type: displayType })
|
|
535
831
|
] })
|
|
536
832
|
] })
|
|
537
833
|
] }),
|
|
538
834
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-datetime-layout", children: [
|
|
539
835
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-calendar", children: [
|
|
540
836
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-cal-header", children: [
|
|
541
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(-1), disabled: !canGoPrev, "aria-label": "Previous month", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {}) }),
|
|
837
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(-1), disabled: !canGoPrev || loading || !!recovery, "aria-label": "Previous month", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {}) }),
|
|
542
838
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "bw-cal-title", children: [
|
|
543
839
|
MONTHS[viewMonth.getMonth()],
|
|
544
840
|
" ",
|
|
545
841
|
viewMonth.getFullYear()
|
|
546
842
|
] }),
|
|
547
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(1), disabled: !canGoNext, "aria-label": "Next month", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {}) })
|
|
843
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-cal-nav", onClick: () => goMonth(1), disabled: !canGoNext || loading || !!recovery, "aria-label": "Next month", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {}) })
|
|
548
844
|
] }),
|
|
549
845
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bw-cal-weekdays", children: DAYS.map((d) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-cal-wd", children: d }, d)) }),
|
|
550
846
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bw-cal-grid", children: days.map((date, i) => {
|
|
551
847
|
if (!date) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-cal-empty" }, `e-${i}`);
|
|
552
848
|
const past = isBeforeDay(date, today);
|
|
553
849
|
const future = date > maxDate;
|
|
554
|
-
const disabled = past || future;
|
|
850
|
+
const disabled = past || future || loading || !!recovery;
|
|
555
851
|
const sel = selectedDate && isSameDay(date, selectedDate);
|
|
556
852
|
const isToday = isSameDay(date, today);
|
|
557
853
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
558
854
|
"button",
|
|
559
855
|
{
|
|
560
856
|
className: `bw-cal-day${sel ? " selected" : ""}${isToday ? " today" : ""}${disabled ? " disabled" : ""}`,
|
|
561
|
-
onClick: () =>
|
|
857
|
+
onClick: () => {
|
|
858
|
+
if (!disabled && !busyRef.current) setSelectedDate(date);
|
|
859
|
+
},
|
|
562
860
|
disabled,
|
|
563
861
|
"aria-label": date.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" }),
|
|
564
862
|
"aria-pressed": sel || void 0,
|
|
@@ -581,15 +879,15 @@ function BookingWidget({
|
|
|
581
879
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "bw-times-date", children: selectedDate.toLocaleDateString("en-US", { weekday: "long", month: "short", day: "numeric" }) }),
|
|
582
880
|
groupedSlots.morning.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-time-group", children: [
|
|
583
881
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-time-label", children: "Morning" }),
|
|
584
|
-
groupedSlots.morning.map((slot) => /* @__PURE__ */ jsxRuntime.jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
882
|
+
groupedSlots.morning.map((slot) => /* @__PURE__ */ jsxRuntime.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))
|
|
585
883
|
] }),
|
|
586
884
|
groupedSlots.afternoon.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-time-group", children: [
|
|
587
885
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-time-label", children: "Afternoon" }),
|
|
588
|
-
groupedSlots.afternoon.map((slot) => /* @__PURE__ */ jsxRuntime.jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
886
|
+
groupedSlots.afternoon.map((slot) => /* @__PURE__ */ jsxRuntime.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))
|
|
589
887
|
] }),
|
|
590
888
|
groupedSlots.evening.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-time-group", children: [
|
|
591
889
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-time-label", children: "Evening" }),
|
|
592
|
-
groupedSlots.evening.map((slot) => /* @__PURE__ */ jsxRuntime.jsx(TimeButton, { slot, selected: selectedSlot?.start === slot.start, confirmed: confirmedSlot && selectedSlot?.start === slot.start, onClick: () => handleSlotSelect(slot), onConfirm: handleSlotConfirm, timezone, loading }, slot.start))
|
|
890
|
+
groupedSlots.evening.map((slot) => /* @__PURE__ */ jsxRuntime.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))
|
|
593
891
|
] }),
|
|
594
892
|
(groupedSlots.afternoon.length > 0 || groupedSlots.evening.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "bw-times-scroll-hint", children: "Scroll for more times" })
|
|
595
893
|
] }) })
|
|
@@ -597,7 +895,7 @@ function BookingWidget({
|
|
|
597
895
|
] }),
|
|
598
896
|
step === "form" && selectedType && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-step bw-fade-in", children: [
|
|
599
897
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-info-header", children: [
|
|
600
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-back", onClick:
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "bw-back", onClick: recoverReservation, disabled: submitting, "aria-label": "Choose another time", children: /* @__PURE__ */ jsxRuntime.jsx(ArrowLeftIcon, {}) }),
|
|
601
899
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
602
900
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: "Your Details" }),
|
|
603
901
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-meta-row", children: [
|
|
@@ -611,14 +909,16 @@ function BookingWidget({
|
|
|
611
909
|
" \xB7 ",
|
|
612
910
|
formatTime(selectedSlot.start, timezone)
|
|
613
911
|
] }),
|
|
614
|
-
/* @__PURE__ */ jsxRuntime.jsx(LocationBadge, { type:
|
|
912
|
+
/* @__PURE__ */ jsxRuntime.jsx(LocationBadge, { type: displayType })
|
|
615
913
|
] })
|
|
616
914
|
] })
|
|
617
915
|
] }),
|
|
618
|
-
hold && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-hold-notice", children: [
|
|
916
|
+
hold && !recovery && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-hold-notice", children: [
|
|
619
917
|
/* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, {}),
|
|
620
918
|
" Slot held for you. Complete your details to confirm."
|
|
621
919
|
] }),
|
|
920
|
+
/* @__PURE__ */ jsxRuntime.jsx(LocationRow, { type: displayType, meetingFormat: meeting?.format }),
|
|
921
|
+
meeting?.requires_review && /* @__PURE__ */ jsxRuntime.jsx("p", { children: "We\u2019ll confirm your visit after reviewing travel arrangements." }),
|
|
622
922
|
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleBookingSubmit, className: "bw-form", children: [
|
|
623
923
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-field", children: [
|
|
624
924
|
/* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "bw-name", children: [
|
|
@@ -631,6 +931,7 @@ function BookingWidget({
|
|
|
631
931
|
id: "bw-name",
|
|
632
932
|
type: "text",
|
|
633
933
|
required: true,
|
|
934
|
+
readOnly: submitting,
|
|
634
935
|
value: guestInfo.name,
|
|
635
936
|
onChange: (e) => setGuestInfo((p) => ({ ...p, name: e.target.value })),
|
|
636
937
|
placeholder: "Jane Smith",
|
|
@@ -649,6 +950,7 @@ function BookingWidget({
|
|
|
649
950
|
id: "bw-email",
|
|
650
951
|
type: "email",
|
|
651
952
|
required: true,
|
|
953
|
+
readOnly: submitting,
|
|
652
954
|
value: guestInfo.email,
|
|
653
955
|
onChange: (e) => setGuestInfo((p) => ({ ...p, email: e.target.value })),
|
|
654
956
|
placeholder: "jane@example.com",
|
|
@@ -657,10 +959,15 @@ function BookingWidget({
|
|
|
657
959
|
)
|
|
658
960
|
] }),
|
|
659
961
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-field", children: [
|
|
660
|
-
/* @__PURE__ */ jsxRuntime.
|
|
962
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: "bw-phone", children: [
|
|
963
|
+
"Phone ",
|
|
964
|
+
meeting?.format === "client_location" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-req", children: "*" })
|
|
965
|
+
] }),
|
|
661
966
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
662
967
|
"input",
|
|
663
968
|
{
|
|
969
|
+
required: meeting?.format === "client_location",
|
|
970
|
+
readOnly: submitting,
|
|
664
971
|
id: "bw-phone",
|
|
665
972
|
type: "tel",
|
|
666
973
|
value: guestInfo.phone || "",
|
|
@@ -676,6 +983,7 @@ function BookingWidget({
|
|
|
676
983
|
"textarea",
|
|
677
984
|
{
|
|
678
985
|
id: "bw-notes",
|
|
986
|
+
readOnly: submitting,
|
|
679
987
|
value: guestInfo.notes || "",
|
|
680
988
|
onChange: (e) => setGuestInfo((p) => ({ ...p, notes: e.target.value })),
|
|
681
989
|
placeholder: "Anything you'd like us to know...",
|
|
@@ -683,15 +991,15 @@ function BookingWidget({
|
|
|
683
991
|
}
|
|
684
992
|
)
|
|
685
993
|
] }),
|
|
686
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: "bw-submit", disabled: submitting || !guestInfo.name || !guestInfo.email, children: submitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
994
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: "bw-submit", disabled: submitting || !!recovery || !guestInfo.name || !guestInfo.email, children: submitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
687
995
|
/* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, {}),
|
|
688
996
|
" Confirming..."
|
|
689
|
-
] }) : "Confirm
|
|
997
|
+
] }) : meeting?.requires_review ? "Request meeting" : "Confirm booking" })
|
|
690
998
|
] })
|
|
691
999
|
] }),
|
|
692
1000
|
step === "success" && bookingResult && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-step bw-fade-in bw-success", children: [
|
|
693
1001
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bw-success-icon", children: /* @__PURE__ */ jsxRuntime.jsx(CheckCircleIcon, {}) }),
|
|
694
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: "You\u2019re
|
|
1002
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "bw-heading", children: isPending ? "Meeting request received" : "You\u2019re booked!" }),
|
|
695
1003
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-details-card", children: [
|
|
696
1004
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-detail-row", children: [
|
|
697
1005
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-detail-label", children: "When" }),
|
|
@@ -712,26 +1020,28 @@ function BookingWidget({
|
|
|
712
1020
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-detail-label", children: "With" }),
|
|
713
1021
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "bw-detail-value", children: bookingResult.booking.hostName })
|
|
714
1022
|
] }),
|
|
715
|
-
/* @__PURE__ */ jsxRuntime.jsx(LocationRow, { type:
|
|
1023
|
+
/* @__PURE__ */ jsxRuntime.jsx(LocationRow, { type: displayType, meetingFormat: meeting?.format })
|
|
716
1024
|
] }),
|
|
717
1025
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "bw-email-notice", children: [
|
|
718
|
-
"We\
|
|
1026
|
+
isPending ? "We\u2019ll send your confirmation to " : "Your meeting details will arrive at ",
|
|
719
1027
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: guestInfo.email }),
|
|
720
|
-
"
|
|
1028
|
+
"."
|
|
721
1029
|
] }),
|
|
722
|
-
/* @__PURE__ */ jsxRuntime.
|
|
723
|
-
|
|
724
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
725
|
-
/* @__PURE__ */ jsxRuntime.
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
/* @__PURE__ */ jsxRuntime.
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
/* @__PURE__ */ jsxRuntime.
|
|
734
|
-
|
|
1030
|
+
!isPending && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "bw-cal-links-label", children: "Add to your calendar" }),
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-cal-links", children: [
|
|
1033
|
+
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: bookingResult.calendarLinks.google, target: "_blank", rel: "noopener noreferrer", className: "bw-cal-link", children: [
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsx(CalendarPlusIcon, {}),
|
|
1035
|
+
" Google"
|
|
1036
|
+
] }),
|
|
1037
|
+
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: bookingResult.calendarLinks.outlook, target: "_blank", rel: "noopener noreferrer", className: "bw-cal-link", children: [
|
|
1038
|
+
/* @__PURE__ */ jsxRuntime.jsx(CalendarPlusIcon, {}),
|
|
1039
|
+
" Outlook"
|
|
1040
|
+
] }),
|
|
1041
|
+
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: bookingResult.calendarLinks.ics, download: true, className: "bw-cal-link", children: [
|
|
1042
|
+
/* @__PURE__ */ jsxRuntime.jsx(CalendarPlusIcon, {}),
|
|
1043
|
+
" iCal"
|
|
1044
|
+
] })
|
|
735
1045
|
] })
|
|
736
1046
|
] }),
|
|
737
1047
|
(bookingResult.rescheduleUrl || bookingResult.cancelUrl) && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "bw-manage-links", children: [
|
|
@@ -770,7 +1080,7 @@ function getLocationDisplay(type) {
|
|
|
770
1080
|
return { kind: "custom", label: details || "See details" };
|
|
771
1081
|
case "virtual":
|
|
772
1082
|
default:
|
|
773
|
-
return { kind: "virtual", label: "Video call" };
|
|
1083
|
+
return { kind: "virtual", label: "Video call", detail: type.video_link };
|
|
774
1084
|
}
|
|
775
1085
|
}
|
|
776
1086
|
function LocationBadge({ type }) {
|
|
@@ -782,7 +1092,7 @@ function LocationBadge({ type }) {
|
|
|
782
1092
|
loc.label
|
|
783
1093
|
] });
|
|
784
1094
|
}
|
|
785
|
-
function LocationRow({ type }) {
|
|
1095
|
+
function LocationRow({ type, meetingFormat }) {
|
|
786
1096
|
const loc = getLocationDisplay(type);
|
|
787
1097
|
if (!loc) return null;
|
|
788
1098
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bw-detail-row", children: [
|
|
@@ -791,9 +1101,13 @@ function LocationRow({ type }) {
|
|
|
791
1101
|
loc.label,
|
|
792
1102
|
loc.detail ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
793
1103
|
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
794
|
-
loc.detail
|
|
1104
|
+
loc.kind === "virtual" ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: loc.detail, target: "_blank", rel: "noopener noreferrer", children: "Join Google Meet" }) : loc.detail
|
|
795
1105
|
] }) : null,
|
|
796
|
-
|
|
1106
|
+
type?.location_instructions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1107
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { whiteSpace: "pre-wrap" }, children: type.location_instructions })
|
|
1109
|
+
] }),
|
|
1110
|
+
loc.mapUrl && meetingFormat !== "client_location" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
797
1111
|
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
798
1112
|
/* @__PURE__ */ jsxRuntime.jsx("a", { href: loc.mapUrl, target: "_blank", rel: "noopener noreferrer", className: "bw-where-link", children: "Get directions \u2192" })
|
|
799
1113
|
] }) : null,
|
|
@@ -873,6 +1187,10 @@ var WIDGET_CSS = `
|
|
|
873
1187
|
padding: 10px 14px; border-radius: var(--sk-radius); margin-bottom: 16px; font-size: 0.875rem;
|
|
874
1188
|
}
|
|
875
1189
|
.bw-error button { background: none; border: none; color: inherit; cursor: pointer; font-size: 1.25rem; line-height: 1; padding: 0; }
|
|
1190
|
+
.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); }
|
|
1191
|
+
.sk-booking-recovery p { margin: 0 0 12px; font-size: 0.875rem; }
|
|
1192
|
+
.sk-booking-recovery .bw-submit { width: auto; }
|
|
1193
|
+
.bw-back:disabled { cursor: wait; opacity: 0.55; }
|
|
876
1194
|
|
|
877
1195
|
/* \u2500\u2500 Headings \u2500\u2500 */
|
|
878
1196
|
.bw-heading { font-size: 1.125rem; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
|
|
@@ -894,6 +1212,7 @@ var WIDGET_CSS = `
|
|
|
894
1212
|
background: var(--sk-bg); cursor: pointer; color: var(--sk-text-secondary); flex-shrink: 0; margin-top: 1px;
|
|
895
1213
|
transition: all 0.15s;
|
|
896
1214
|
}
|
|
1215
|
+
.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; }
|
|
897
1216
|
.bw-back:hover { background: var(--sk-surface); border-color: var(--sk-border); }
|
|
898
1217
|
|
|
899
1218
|
/* \u2500\u2500 Loading \u2500\u2500 */
|
|
@@ -1099,6 +1418,7 @@ exports.fetchBookingTypes = fetchBookingTypes;
|
|
|
1099
1418
|
exports.formatDate = formatDate;
|
|
1100
1419
|
exports.formatDuration = formatDuration;
|
|
1101
1420
|
exports.formatTime = formatTime;
|
|
1421
|
+
exports.prepareMeeting = prepareMeeting;
|
|
1102
1422
|
exports.releaseSlotHold = releaseSlotHold;
|
|
1103
|
-
//# sourceMappingURL=chunk-
|
|
1104
|
-
//# sourceMappingURL=chunk-
|
|
1423
|
+
//# sourceMappingURL=chunk-ZY5AVC4P.js.map
|
|
1424
|
+
//# sourceMappingURL=chunk-ZY5AVC4P.js.map
|