@fluid-app/portal-sdk 0.1.350 → 0.1.352
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/dist/{AddressAutocompleteInput-JBXGT1iL.cjs → AddressAutocompleteInput-BQz2jaUO.cjs} +134 -79
- package/dist/AddressAutocompleteInput-BQz2jaUO.cjs.map +1 -0
- package/dist/{AddressAutocompleteInput-BANMgwzR.mjs → AddressAutocompleteInput-Dds2GjGt.mjs} +134 -79
- package/dist/AddressAutocompleteInput-Dds2GjGt.mjs.map +1 -0
- package/dist/{AlertWidget-BmOGoxTA.mjs → AlertWidget-DMwOt9u8.mjs} +3 -3
- package/dist/{AlertWidget-BmOGoxTA.mjs.map → AlertWidget-DMwOt9u8.mjs.map} +1 -1
- package/dist/{AppDownloadScreen-C78ggXk3.mjs → AppDownloadScreen-CBg2shvo.mjs} +5 -5
- package/dist/{AppDownloadScreen-C78ggXk3.mjs.map → AppDownloadScreen-CBg2shvo.mjs.map} +1 -1
- package/dist/{AppDownloadScreen-DIcwvAZ4.cjs → AppDownloadScreen-CMR1y4kP.cjs} +4 -4
- package/dist/{AppDownloadScreen-DIcwvAZ4.cjs.map → AppDownloadScreen-CMR1y4kP.cjs.map} +1 -1
- package/dist/{AppNavigationContext-BCj6iFxr.mjs → AppNavigationContext-B-wToUBG.mjs} +3 -3
- package/dist/AppNavigationContext-B-wToUBG.mjs.map +1 -0
- package/dist/{AppNavigationContext-CoNtdUrr.cjs → AppNavigationContext-CLOwdlpx.cjs} +2 -2
- package/dist/AppNavigationContext-CLOwdlpx.cjs.map +1 -0
- package/dist/{BulletListWidget-AIIf29RP.mjs → BulletListWidget-D--Mmasw.mjs} +2 -2
- package/dist/{BulletListWidget-AIIf29RP.mjs.map → BulletListWidget-D--Mmasw.mjs.map} +1 -1
- package/dist/{CalendarWidget-DW5wz5ke.cjs → CalendarWidget-Aa7H9M7f.cjs} +4 -4
- package/dist/{CalendarWidget-DW5wz5ke.cjs.map → CalendarWidget-Aa7H9M7f.cjs.map} +1 -1
- package/dist/{CalendarWidget-Dn55musX.mjs → CalendarWidget-Cx6KvkaG.mjs} +5 -5
- package/dist/{CalendarWidget-Dn55musX.mjs.map → CalendarWidget-Cx6KvkaG.mjs.map} +1 -1
- package/dist/{CardWidget-DsfLoyup.cjs → CardWidget-Caytu8qs.cjs} +3 -3
- package/dist/{CardWidget--S5FBquC.cjs → CardWidget-CqewqU5a.cjs} +2 -2
- package/dist/{CardWidget--S5FBquC.cjs.map → CardWidget-CqewqU5a.cjs.map} +1 -1
- package/dist/{CardWidget-ChfurL_z.mjs → CardWidget-DARqLSwy.mjs} +3 -3
- package/dist/{CardWidget-ChfurL_z.mjs.map → CardWidget-DARqLSwy.mjs.map} +1 -1
- package/dist/{CarouselWidget-SrCl4cSn.mjs → CarouselWidget-Bnl_iggA.mjs} +2 -2
- package/dist/{CarouselWidget-SrCl4cSn.mjs.map → CarouselWidget-Bnl_iggA.mjs.map} +1 -1
- package/dist/{CatchUpWidget-B_in7Bjq.mjs → CatchUpWidget-Bplozt8D.mjs} +5 -5
- package/dist/{CatchUpWidget-B_in7Bjq.mjs.map → CatchUpWidget-Bplozt8D.mjs.map} +1 -1
- package/dist/{CatchUpWidget-_ErrC-e8.cjs → CatchUpWidget-DEyXTEFj.cjs} +4 -4
- package/dist/{CatchUpWidget-_ErrC-e8.cjs.map → CatchUpWidget-DEyXTEFj.cjs.map} +1 -1
- package/dist/{ChartWidget-CIr3v8x6.mjs → ChartWidget-BPOZNKI_.mjs} +2 -2
- package/dist/{ChartWidget-CIr3v8x6.mjs.map → ChartWidget-BPOZNKI_.mjs.map} +1 -1
- package/dist/{ContactsScreen-f3dXV198.cjs → ContactsScreen-BFbWTMu9.cjs} +4 -4
- package/dist/{ContactsScreen-f3dXV198.cjs.map → ContactsScreen-BFbWTMu9.cjs.map} +1 -1
- package/dist/{ContactsScreen-DJ8O35Pl.mjs → ContactsScreen-CnLSICv5.mjs} +5 -5
- package/dist/{ContactsScreen-DJ8O35Pl.mjs.map → ContactsScreen-CnLSICv5.mjs.map} +1 -1
- package/dist/{ContactsScreen-CVmYvRZi.cjs → ContactsScreen-DQjdfcAV.cjs} +5 -5
- package/dist/{ContainerWidget-BHWPtBmF.mjs → ContainerWidget-Bv0f8-TC.mjs} +3 -3
- package/dist/{ContainerWidget-BHWPtBmF.mjs.map → ContainerWidget-Bv0f8-TC.mjs.map} +1 -1
- package/dist/{ContainerWidget-Cf_D4TAi.cjs → ContainerWidget-CF6VDxd8.cjs} +2 -2
- package/dist/{ContainerWidget-Cf_D4TAi.cjs.map → ContainerWidget-CF6VDxd8.cjs.map} +1 -1
- package/dist/ContainerWidget-D3JoA0IP.cjs +8 -0
- package/dist/{CustomersScreen-DGBwaZrt.mjs → CustomersScreen-BHqlHdHZ.mjs} +3 -3
- package/dist/{CustomersScreen-DGBwaZrt.mjs.map → CustomersScreen-BHqlHdHZ.mjs.map} +1 -1
- package/dist/{CustomersScreen-BXvWK7Y1.cjs → CustomersScreen-C8b3P79M.cjs} +2 -2
- package/dist/{CustomersScreen-BXvWK7Y1.cjs.map → CustomersScreen-C8b3P79M.cjs.map} +1 -1
- package/dist/{EmbedWidget-D5kFw9HS.mjs → EmbedWidget-DRfjHvRs.mjs} +2 -2
- package/dist/{EmbedWidget-D5kFw9HS.mjs.map → EmbedWidget-DRfjHvRs.mjs.map} +1 -1
- package/dist/{FluidProvider-BVJmIM13.cjs → FluidProvider-CMfpLju8.cjs} +73 -47
- package/dist/FluidProvider-CMfpLju8.cjs.map +1 -0
- package/dist/{FluidProvider-CYBXFElI.mjs → FluidProvider-tPt9UpYz.mjs} +101 -81
- package/dist/FluidProvider-tPt9UpYz.mjs.map +1 -0
- package/dist/{ImageWidget-B3ZTuy4v.mjs → ImageWidget-C7nfRJ6p.mjs} +2 -2
- package/dist/{ImageWidget-B3ZTuy4v.mjs.map → ImageWidget-C7nfRJ6p.mjs.map} +1 -1
- package/dist/{LayoutWidget-3G-w-YLz.cjs → LayoutWidget-6_Huueb4.cjs} +3 -3
- package/dist/{LayoutWidget-CrZG6Ipw.mjs → LayoutWidget-CSFWeXYY.mjs} +3 -3
- package/dist/{LayoutWidget-CrZG6Ipw.mjs.map → LayoutWidget-CSFWeXYY.mjs.map} +1 -1
- package/dist/{LayoutWidget-CG-dWz_c.cjs → LayoutWidget-DD1ZqWXg.cjs} +2 -2
- package/dist/{LayoutWidget-CG-dWz_c.cjs.map → LayoutWidget-DD1ZqWXg.cjs.map} +1 -1
- package/dist/{LinkWidget-fPowKN73.mjs → LinkWidget-DI2Uod5O.mjs} +2 -2
- package/dist/{LinkWidget-fPowKN73.mjs.map → LinkWidget-DI2Uod5O.mjs.map} +1 -1
- package/dist/{ListWidget-CQuNRg_g.mjs → ListWidget-BdUhs2fo.mjs} +2 -2
- package/dist/{ListWidget-CQuNRg_g.mjs.map → ListWidget-BdUhs2fo.mjs.map} +1 -1
- package/dist/{MessagingScreen-3o_Qb6u_.mjs → MessagingScreen-8hyxHThw.mjs} +10 -10
- package/dist/MessagingScreen-8hyxHThw.mjs.map +1 -0
- package/dist/{MessagingScreen-Db6wQydU.cjs → MessagingScreen-CaSUJhJc.cjs} +25 -25
- package/dist/MessagingScreen-CpMlE96f.mjs +50 -0
- package/dist/{MessagingScreen-C4SUSPy3.cjs → MessagingScreen-CvyQL50O.cjs} +8 -8
- package/dist/MessagingScreen-CvyQL50O.cjs.map +1 -0
- package/dist/{MySiteScreen-D3rkI2UJ.cjs → MySiteScreen-BZnLxHAq.cjs} +6 -6
- package/dist/{MySiteScreen-D3rkI2UJ.cjs.map → MySiteScreen-BZnLxHAq.cjs.map} +1 -1
- package/dist/MySiteScreen-CYGVxzCE.cjs +11 -0
- package/dist/{MySiteScreen-BC_K8gIq.mjs → MySiteScreen-tKgO4G0B.mjs} +7 -7
- package/dist/{MySiteScreen-BC_K8gIq.mjs.map → MySiteScreen-tKgO4G0B.mjs.map} +1 -1
- package/dist/{MySiteWidget-D6QyWuzN.cjs → MySiteWidget-CabBtq5C.cjs} +4 -4
- package/dist/{MySiteWidget-D6QyWuzN.cjs.map → MySiteWidget-CabBtq5C.cjs.map} +1 -1
- package/dist/{MySiteWidget-BLALS8Ve.mjs → MySiteWidget-ivytLi6H.mjs} +5 -5
- package/dist/{MySiteWidget-BLALS8Ve.mjs.map → MySiteWidget-ivytLi6H.mjs.map} +1 -1
- package/dist/{NestedWidget-DuNuNaeT.mjs → NestedWidget-gqdWZS9Q.mjs} +2 -2
- package/dist/{NestedWidget-DuNuNaeT.mjs.map → NestedWidget-gqdWZS9Q.mjs.map} +1 -1
- package/dist/OrdersScreen-BGVPWrEg.cjs +50 -0
- package/dist/OrdersScreen-BZ2iBfWQ.mjs +48 -0
- package/dist/{OrdersScreen-CJzegrYb.cjs → OrdersScreen-Ckt7uChL.cjs} +11 -11
- package/dist/OrdersScreen-Ckt7uChL.cjs.map +1 -0
- package/dist/{OrdersScreen-FaoTq71a.mjs → OrdersScreen-DsKspc_8.mjs} +12 -12
- package/dist/OrdersScreen-DsKspc_8.mjs.map +1 -0
- package/dist/{PointsWidget-BvGANrJq.mjs → PointsWidget-BJlOIK6o.mjs} +5 -5
- package/dist/{PointsWidget-BvGANrJq.mjs.map → PointsWidget-BJlOIK6o.mjs.map} +1 -1
- package/dist/{PointsWidget-Byd2-eEi.cjs → PointsWidget-Him7U2k2.cjs} +4 -4
- package/dist/{PointsWidget-Byd2-eEi.cjs.map → PointsWidget-Him7U2k2.cjs.map} +1 -1
- package/dist/{PortalTenantClientProvider-Bpm-CZq1.cjs → PortalTenantClientProvider-C0eJp8MN.cjs} +3 -3
- package/dist/PortalTenantClientProvider-C0eJp8MN.cjs.map +1 -0
- package/dist/{PortalTenantClientProvider-BmRtQAbi.mjs → PortalTenantClientProvider-DVClpfbi.mjs} +4 -4
- package/dist/PortalTenantClientProvider-DVClpfbi.mjs.map +1 -0
- package/dist/{ProfileScreen-DxjLSL0A.cjs → ProfileScreen-21MnRuNH.cjs} +12 -8
- package/dist/ProfileScreen-21MnRuNH.cjs.map +1 -0
- package/dist/{ProfileScreen-CU4Y3sBq.mjs → ProfileScreen-DA3vl5EU.mjs} +12 -8
- package/dist/ProfileScreen-DA3vl5EU.mjs.map +1 -0
- package/dist/ProfileScreen-DzxUqJJD.cjs +53 -0
- package/dist/ProfileScreen-Uw_6u6Ew.mjs +51 -0
- package/dist/{QuickLinksWidget-D8LqZkUS.mjs → QuickLinksWidget-DJUI7r5_.mjs} +2 -2
- package/dist/{QuickLinksWidget-D8LqZkUS.mjs.map → QuickLinksWidget-DJUI7r5_.mjs.map} +1 -1
- package/dist/{QuickShareWidget-BJpqzZp0.mjs → QuickShareWidget-B7DhQOyt.mjs} +2 -2
- package/dist/{QuickShareWidget-BJpqzZp0.mjs.map → QuickShareWidget-B7DhQOyt.mjs.map} +1 -1
- package/dist/{RecentActivityWidget-ClgOlTXl.mjs → RecentActivityWidget-BMGeLSUa.mjs} +5 -5
- package/dist/{RecentActivityWidget-ClgOlTXl.mjs.map → RecentActivityWidget-BMGeLSUa.mjs.map} +1 -1
- package/dist/{RecentActivityWidget-BYzAzBI-.cjs → RecentActivityWidget-DvrmBGsD.cjs} +4 -4
- package/dist/{RecentActivityWidget-BYzAzBI-.cjs.map → RecentActivityWidget-DvrmBGsD.cjs.map} +1 -1
- package/dist/{ScreenHeaderContext-BiGgRqjY.cjs → ScreenHeaderContext-VOp8pVHr.cjs} +4 -4
- package/dist/ScreenHeaderContext-VOp8pVHr.cjs.map +1 -0
- package/dist/{ScreenHeaderContext-BjpQOCck.mjs → ScreenHeaderContext-cuVMk00X.mjs} +5 -5
- package/dist/ScreenHeaderContext-cuVMk00X.mjs.map +1 -0
- package/dist/{ScreenRenderer-TobkTBMC.mjs → ScreenRenderer-D3zNFSr3.mjs} +4 -4
- package/dist/ScreenRenderer-D3zNFSr3.mjs.map +1 -0
- package/dist/{ScreenRenderer-CLDJUinO.cjs → ScreenRenderer-IMkMMnUJ.cjs} +3 -3
- package/dist/ScreenRenderer-IMkMMnUJ.cjs.map +1 -0
- package/dist/{SearchSort-B5hq2j-l.cjs → SearchSort-BjjBpuEi.cjs} +2 -2
- package/dist/SearchSort-BjjBpuEi.cjs.map +1 -0
- package/dist/{SearchSort-CMUL0qt3.mjs → SearchSort-C6RV6d9g.mjs} +3 -3
- package/dist/SearchSort-C6RV6d9g.mjs.map +1 -0
- package/dist/{SeparatorWidget-CDvDjL-k.mjs → SeparatorWidget-CGFzy35l.mjs} +2 -2
- package/dist/{SeparatorWidget-CDvDjL-k.mjs.map → SeparatorWidget-CGFzy35l.mjs.map} +1 -1
- package/dist/{ShareablesScreen-COg_WpdP.cjs → ShareablesScreen-B0vxU7i6.cjs} +20 -20
- package/dist/ShareablesScreen-B0vxU7i6.cjs.map +1 -0
- package/dist/{ShareablesScreen-C9EmRZJW.mjs → ShareablesScreen-CefIC5H8.mjs} +22 -22
- package/dist/ShareablesScreen-CefIC5H8.mjs.map +1 -0
- package/dist/ShareablesScreen-Cs8iC1qk.mjs +15 -0
- package/dist/ShareablesScreen-igzq70Xz.cjs +17 -0
- package/dist/{ShopScreen-DTL5xiPY.mjs → ShopScreen-CbeH9wRR.mjs} +10 -10
- package/dist/ShopScreen-CbeH9wRR.mjs.map +1 -0
- package/dist/{ShopScreen-Bgx6548O.cjs → ShopScreen-Cme3j61f.cjs} +10 -10
- package/dist/ShopScreen-Cme3j61f.cjs.map +1 -0
- package/dist/ShopScreen-D2LDk2xr.mjs +48 -0
- package/dist/ShopScreen-D6xtA_0b.cjs +50 -0
- package/dist/{ShopWidget-Cmx4Pb6Q.cjs → ShopWidget-BWURiWyx.cjs} +4 -4
- package/dist/{ShopWidget-Cmx4Pb6Q.cjs.map → ShopWidget-BWURiWyx.cjs.map} +1 -1
- package/dist/{ShopWidget-C76SSZwW.cjs → ShopWidget-C4jeRRut.cjs} +4 -4
- package/dist/{ShopWidget-BzAuvfyC.mjs → ShopWidget-Cqnwq0AG.mjs} +5 -5
- package/dist/{ShopWidget-BzAuvfyC.mjs.map → ShopWidget-Cqnwq0AG.mjs.map} +1 -1
- package/dist/{SpacerWidget-B0l19UqF.mjs → SpacerWidget-BhxIaqYF.mjs} +2 -2
- package/dist/{SpacerWidget-B0l19UqF.mjs.map → SpacerWidget-BhxIaqYF.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-qKJoibtI.mjs → SubscriptionsScreen-Br_gugTG.mjs} +32 -27
- package/dist/SubscriptionsScreen-Br_gugTG.mjs.map +1 -0
- package/dist/SubscriptionsScreen-CG3OldGE.mjs +50 -0
- package/dist/{SubscriptionsScreen-DGE3efWd.cjs → SubscriptionsScreen-CvM68asd.cjs} +26 -26
- package/dist/{SubscriptionsScreen-D8bjSX3s.cjs → SubscriptionsScreen-HbrDZhaX.cjs} +31 -26
- package/dist/SubscriptionsScreen-HbrDZhaX.cjs.map +1 -0
- package/dist/{TableWidget-CpHI9CGQ.mjs → TableWidget-Dwud4Fif.mjs} +2 -2
- package/dist/{TableWidget-CpHI9CGQ.mjs.map → TableWidget-Dwud4Fif.mjs.map} +1 -1
- package/dist/{TextWidget-Jy-Ktqje.mjs → TextWidget-B5ZtQMX-.mjs} +2 -2
- package/dist/{TextWidget-Jy-Ktqje.mjs.map → TextWidget-B5ZtQMX-.mjs.map} +1 -1
- package/dist/ToDoWidget-BJ2Ip97m.cjs +11 -0
- package/dist/{ToDoWidget-BaWksZpJ.mjs → ToDoWidget-Bnml3xLS.mjs} +6 -6
- package/dist/{ToDoWidget-BaWksZpJ.mjs.map → ToDoWidget-Bnml3xLS.mjs.map} +1 -1
- package/dist/{ToDoWidget-CZh5a5-z.cjs → ToDoWidget-C3Ob2TP2.cjs} +5 -5
- package/dist/{ToDoWidget-CZh5a5-z.cjs.map → ToDoWidget-C3Ob2TP2.cjs.map} +1 -1
- package/dist/{UpgradeScreen-VpfRqKdO.cjs → UpgradeScreen-B40dCeub.cjs} +3 -3
- package/dist/{UpgradeScreen-VpfRqKdO.cjs.map → UpgradeScreen-B40dCeub.cjs.map} +1 -1
- package/dist/{UpgradeScreen-C55rEuCN.cjs → UpgradeScreen-CbdTRnIj.cjs} +3 -3
- package/dist/{UpgradeScreen-x9TdC5aR.mjs → UpgradeScreen-GzkZOOR4.mjs} +4 -4
- package/dist/{UpgradeScreen-x9TdC5aR.mjs.map → UpgradeScreen-GzkZOOR4.mjs.map} +1 -1
- package/dist/{VideoWidget-DP-VHt2s.mjs → VideoWidget-Cm3UQ3-Z.mjs} +2 -2
- package/dist/{VideoWidget-DP-VHt2s.mjs.map → VideoWidget-Cm3UQ3-Z.mjs.map} +1 -1
- package/dist/{countries-api-context-G-NW4BoH.cjs → countries-api-context-16PZpF7O.cjs} +2 -2
- package/dist/countries-api-context-16PZpF7O.cjs.map +1 -0
- package/dist/{countries-api-context-DScC_39w.mjs → countries-api-context-Donus2X5.mjs} +3 -3
- package/dist/countries-api-context-Donus2X5.mjs.map +1 -0
- package/dist/{error-state-DvzIn9Tz.mjs → error-state-BUe589mD.mjs} +3 -3
- package/dist/error-state-BUe589mD.mjs.map +1 -0
- package/dist/{error-state-DJq7C-23.cjs → error-state-CU87JUpz.cjs} +2 -2
- package/dist/error-state-CU87JUpz.cjs.map +1 -0
- package/dist/{es-jA6aVeLD.mjs → es-C19weaa-.mjs} +2 -2
- package/dist/{es-jA6aVeLD.mjs.map → es-C19weaa-.mjs.map} +1 -1
- package/dist/index.cjs +65 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +83 -83
- package/dist/index.mjs.map +1 -1
- package/dist/{mysite-api-context-kUTM3GNG.mjs → mysite-api-context-CoLr9vIf.mjs} +3 -3
- package/dist/mysite-api-context-CoLr9vIf.mjs.map +1 -0
- package/dist/{mysite-api-context-CilZcDS4.cjs → mysite-api-context-DtEXblIV.cjs} +2 -2
- package/dist/mysite-api-context-DtEXblIV.cjs.map +1 -0
- package/dist/{preview-context-D9ZzEfWh.mjs → preview-context-BXEGWx9T.mjs} +3 -3
- package/dist/preview-context-BXEGWx9T.mjs.map +1 -0
- package/dist/{preview-context-BWCl-xyj.cjs → preview-context-DrXkIImI.cjs} +2 -2
- package/dist/preview-context-DrXkIImI.cjs.map +1 -0
- package/dist/{registry-context-BKvTiuXB.mjs → registry-context-CcoVxCii.mjs} +3 -3
- package/dist/{registry-context-BKvTiuXB.mjs.map → registry-context-CcoVxCii.mjs.map} +1 -1
- package/dist/{registry-context-DJ5xiVnt.cjs → registry-context-Q_1Iq2Ea.cjs} +2 -2
- package/dist/{registry-context-DJ5xiVnt.cjs.map → registry-context-Q_1Iq2Ea.cjs.map} +1 -1
- package/dist/{static-dict-adapter-JAau5LHb.cjs → static-dict-adapter-BLq4QzCI.cjs} +2 -2
- package/dist/static-dict-adapter-BLq4QzCI.cjs.map +1 -0
- package/dist/{static-dict-adapter-DjCpubZc.mjs → static-dict-adapter-DRBq3ndO.mjs} +3 -3
- package/dist/static-dict-adapter-DRBq3ndO.mjs.map +1 -0
- package/dist/{store-api-context-DViwxyG4.mjs → store-api-context-B_vtKkXO.mjs} +3 -3
- package/dist/store-api-context-B_vtKkXO.mjs.map +1 -0
- package/dist/{store-api-context-D1gZn22Z.cjs → store-api-context-CGH3YsZB.cjs} +2 -2
- package/dist/store-api-context-CGH3YsZB.cjs.map +1 -0
- package/dist/{task-composer-form-D_Pbl6qk.mjs → task-composer-form-CZgRqbIc.mjs} +4 -4
- package/dist/task-composer-form-CZgRqbIc.mjs.map +1 -0
- package/dist/{task-composer-form-BEZGTBBZ.cjs → task-composer-form-Cz8hpMTT.cjs} +3 -3
- package/dist/task-composer-form-Cz8hpMTT.cjs.map +1 -0
- package/dist/{translation-api-context-factory-BSRK6Z50.cjs → translation-api-context-factory-CjRDqIhF.cjs} +2 -2
- package/dist/translation-api-context-factory-CjRDqIhF.cjs.map +1 -0
- package/dist/{translation-api-context-factory-CJrVq_EB.mjs → translation-api-context-factory-DFr9yJ6Q.mjs} +3 -3
- package/dist/translation-api-context-factory-DFr9yJ6Q.mjs.map +1 -0
- package/dist/{use-account-CQ-mhA3W.cjs → use-account-DltRHEwC.cjs} +2 -2
- package/dist/{use-account-CQ-mhA3W.cjs.map → use-account-DltRHEwC.cjs.map} +1 -1
- package/dist/{use-account-CwGoFpwg.mjs → use-account-Dm6Svko1.mjs} +2 -2
- package/dist/{use-account-CwGoFpwg.mjs.map → use-account-Dm6Svko1.mjs.map} +1 -1
- package/dist/{use-mysite-portal-ChDJ4z34.mjs → use-mysite-portal-3Tn3bFoE.mjs} +2 -2
- package/dist/{use-mysite-portal-ChDJ4z34.mjs.map → use-mysite-portal-3Tn3bFoE.mjs.map} +1 -1
- package/dist/{use-mysite-portal-CH9ZQROw.cjs → use-mysite-portal-D3X51_Ax.cjs} +2 -2
- package/dist/{use-mysite-portal-CH9ZQROw.cjs.map → use-mysite-portal-D3X51_Ax.cjs.map} +1 -1
- package/dist/{use-navigation-parent-DvHbbMB0.mjs → use-navigation-parent-GjQMvU4i.mjs} +2 -2
- package/dist/{use-navigation-parent-DvHbbMB0.mjs.map → use-navigation-parent-GjQMvU4i.mjs.map} +1 -1
- package/dist/{use-navigation-parent-DQ8CiN9L.cjs → use-navigation-parent-q-la1wD2.cjs} +2 -2
- package/dist/{use-navigation-parent-DQ8CiN9L.cjs.map → use-navigation-parent-q-la1wD2.cjs.map} +1 -1
- package/dist/{use-store-cwcCLxl_.mjs → use-store-C6KYHvRw.mjs} +2 -2
- package/dist/{use-store-cwcCLxl_.mjs.map → use-store-C6KYHvRw.mjs.map} +1 -1
- package/dist/{use-store-lOOUcpRT.cjs → use-store-j_6I4DU4.cjs} +2 -2
- package/dist/{use-store-lOOUcpRT.cjs.map → use-store-j_6I4DU4.cjs.map} +1 -1
- package/package.json +19 -18
- package/dist/AddressAutocompleteInput-BANMgwzR.mjs.map +0 -1
- package/dist/AddressAutocompleteInput-JBXGT1iL.cjs.map +0 -1
- package/dist/AppNavigationContext-BCj6iFxr.mjs.map +0 -1
- package/dist/AppNavigationContext-CoNtdUrr.cjs.map +0 -1
- package/dist/ContainerWidget-CyDVJu83.cjs +0 -8
- package/dist/FluidProvider-BVJmIM13.cjs.map +0 -1
- package/dist/FluidProvider-CYBXFElI.mjs.map +0 -1
- package/dist/MessagingScreen-3o_Qb6u_.mjs.map +0 -1
- package/dist/MessagingScreen-C4SUSPy3.cjs.map +0 -1
- package/dist/MessagingScreen-D-wunIkf.mjs +0 -50
- package/dist/MySiteScreen-DiCU6P9d.cjs +0 -11
- package/dist/OrdersScreen-BL5Ta3Tt.cjs +0 -50
- package/dist/OrdersScreen-B_JxQTW8.mjs +0 -48
- package/dist/OrdersScreen-CJzegrYb.cjs.map +0 -1
- package/dist/OrdersScreen-FaoTq71a.mjs.map +0 -1
- package/dist/PortalTenantClientProvider-BmRtQAbi.mjs.map +0 -1
- package/dist/PortalTenantClientProvider-Bpm-CZq1.cjs.map +0 -1
- package/dist/ProfileScreen-CU4Y3sBq.mjs.map +0 -1
- package/dist/ProfileScreen-DMDKlk20.cjs +0 -53
- package/dist/ProfileScreen-Dcjp4wNO.mjs +0 -51
- package/dist/ProfileScreen-DxjLSL0A.cjs.map +0 -1
- package/dist/ScreenHeaderContext-BiGgRqjY.cjs.map +0 -1
- package/dist/ScreenHeaderContext-BjpQOCck.mjs.map +0 -1
- package/dist/ScreenRenderer-CLDJUinO.cjs.map +0 -1
- package/dist/ScreenRenderer-TobkTBMC.mjs.map +0 -1
- package/dist/SearchSort-B5hq2j-l.cjs.map +0 -1
- package/dist/SearchSort-CMUL0qt3.mjs.map +0 -1
- package/dist/ShareablesScreen-BQd1-Og8.mjs +0 -15
- package/dist/ShareablesScreen-C9EmRZJW.mjs.map +0 -1
- package/dist/ShareablesScreen-COg_WpdP.cjs.map +0 -1
- package/dist/ShareablesScreen-CoFM63kh.cjs +0 -17
- package/dist/ShopScreen-Bgx6548O.cjs.map +0 -1
- package/dist/ShopScreen-Bm2RlZas.cjs +0 -50
- package/dist/ShopScreen-Cz7aMt4z.mjs +0 -48
- package/dist/ShopScreen-DTL5xiPY.mjs.map +0 -1
- package/dist/SubscriptionsScreen-CF6AuW3I.mjs +0 -50
- package/dist/SubscriptionsScreen-D8bjSX3s.cjs.map +0 -1
- package/dist/SubscriptionsScreen-qKJoibtI.mjs.map +0 -1
- package/dist/ToDoWidget-1wI1ntdD.cjs +0 -11
- package/dist/countries-api-context-DScC_39w.mjs.map +0 -1
- package/dist/countries-api-context-G-NW4BoH.cjs.map +0 -1
- package/dist/error-state-DJq7C-23.cjs.map +0 -1
- package/dist/error-state-DvzIn9Tz.mjs.map +0 -1
- package/dist/mysite-api-context-CilZcDS4.cjs.map +0 -1
- package/dist/mysite-api-context-kUTM3GNG.mjs.map +0 -1
- package/dist/preview-context-BWCl-xyj.cjs.map +0 -1
- package/dist/preview-context-D9ZzEfWh.mjs.map +0 -1
- package/dist/static-dict-adapter-DjCpubZc.mjs.map +0 -1
- package/dist/static-dict-adapter-JAau5LHb.cjs.map +0 -1
- package/dist/store-api-context-D1gZn22Z.cjs.map +0 -1
- package/dist/store-api-context-DViwxyG4.mjs.map +0 -1
- package/dist/task-composer-form-BEZGTBBZ.cjs.map +0 -1
- package/dist/task-composer-form-D_Pbl6qk.mjs.map +0 -1
- package/dist/translation-api-context-factory-BSRK6Z50.cjs.map +0 -1
- package/dist/translation-api-context-factory-CJrVq_EB.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShopWidget-BzAuvfyC.mjs","names":[],"sources":["../../../shop/core/src/translation-api-context.ts","../../../shop/ui/src/utils/media-helpers.ts","../../../shop/ui/src/components/product-card.tsx","../../widgets/src/widgets/ShopWidget.tsx"],"sourcesContent":["import { createTranslationContext } from \"@fluid-app/i18n/translation-api-context-factory\";\nimport type { ShopDict } from \"./translation-dictionary\";\n\nconst { Provider, useTranslation } = createTranslationContext<ShopDict>(\"Shop\");\n\nexport const ShopTranslationProvider = Provider;\nexport const useShopTranslation = useTranslation;\n","const VIDEO_EXTENSIONS = [\n \".mp4\",\n \".webm\",\n \".mov\",\n \".avi\",\n \".m4v\",\n \".mkv\",\n \".ogv\",\n \".ogg\",\n \".wmv\",\n \".flv\",\n \".3gp\",\n];\n\nconst IMAGE_EXTENSIONS = [\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".gif\",\n \".webp\",\n \".svg\",\n \".bmp\",\n \".ico\",\n \".tiff\",\n \".tif\",\n];\n\nexport function isVideoUrl(url: string | undefined | null): boolean {\n if (!url) return false;\n const lowerUrl = url.toLowerCase();\n return VIDEO_EXTENSIONS.some((ext) => lowerUrl.includes(ext));\n}\n\nexport function isImageUrl(url: string | undefined | null): boolean {\n if (!url) return false;\n const lowerUrl = url.toLowerCase();\n return IMAGE_EXTENSIONS.some((ext) => lowerUrl.includes(ext));\n}\n\nexport function getMediaTypeFromUrl(\n url: string | undefined | null,\n): \"video\" | \"image\" | \"unknown\" {\n if (isVideoUrl(url)) return \"video\";\n if (isImageUrl(url)) return \"image\";\n return \"unknown\";\n}\n\nexport function getVideoThumbnailUrl(videoUrl: string): string {\n if (videoUrl.includes(\"ik.imagekit.io\")) {\n return `${videoUrl}/ik-thumbnail.jpg`;\n }\n return videoUrl;\n}\n\nexport function ensureImageIsFeatured<\n T extends { image_url: string; position?: number },\n>(items: T[]): T[] {\n if (items.length === 0) return items;\n\n const firstItem = items[0];\n if (!firstItem || !isVideoUrl(firstItem.image_url)) {\n return items;\n }\n\n const firstImageIndex = items.findIndex(\n (item) => !isVideoUrl(item.image_url),\n );\n\n if (firstImageIndex === -1) {\n return items;\n }\n\n const reordered = [...items];\n const [imageToMove] = reordered.splice(firstImageIndex, 1);\n if (imageToMove) {\n reordered.unshift(imageToMove);\n }\n\n return reordered;\n}\n","import type React from \"react\";\nimport { useState, type ReactNode } from \"react\";\nimport type { products, portalProducts } from \"@fluid-app/products-core\";\nimport {\n determineProductPrice,\n getProductImageUrl,\n} from \"@fluid-app/products-core\";\nimport { Card } from \"@fluid-app/ui-primitives\";\nimport { useShopTranslation } from \"@fluid-app/shop-core/translation-api-context\";\nimport { CirclePlay } from \"lucide-react\";\nimport { getVideoThumbnailUrl, isVideoUrl } from \"../utils/media-helpers\";\n\ntype LegacyProduct = (products.Product | products.ShopProduct) & {\n kind?: string;\n video_url?: string;\n};\n\nexport interface RenderImageProps {\n src: string;\n alt: string;\n fill?: boolean;\n className?: string;\n onError?: (e: React.SyntheticEvent<HTMLImageElement>) => void;\n unoptimized?: boolean;\n}\n\ntype TaggedPortalProduct = portalProducts.Product & {\n readonly __portalProduct: true;\n};\n\nexport type ProductCardProduct = LegacyProduct | TaggedPortalProduct;\n\ninterface ProductCardProps {\n product: ProductCardProduct;\n countryIso?: string;\n companyLogoUrl?: string | null;\n showShareModal?: boolean;\n setShareModalOpen?: (open: boolean) => void;\n setSelectedProduct?: (product: LegacyProduct) => void;\n renderLink?: (props: { href: string; children: ReactNode }) => ReactNode;\n renderImage?: (props: RenderImageProps) => ReactNode;\n onClick?: () => void;\n}\n\nexport function tagPortalProduct(\n product: portalProducts.Product,\n): TaggedPortalProduct {\n return { ...product, __portalProduct: true as const };\n}\n\nfunction isPortalProduct(\n product: ProductCardProduct,\n): product is TaggedPortalProduct {\n return \"__portalProduct\" in product && product.__portalProduct === true;\n}\n\nfunction getPortalProductCoverImage(\n product: portalProducts.Product,\n): string | null {\n if (product.images && product.images.length > 0) {\n return product.images[0]?.url ?? null;\n }\n return null;\n}\n\nfunction defaultRenderImage({\n src,\n alt,\n fill,\n className,\n onError,\n}: RenderImageProps): ReactNode {\n return (\n <img\n src={src}\n alt={alt}\n className={`${fill ? \"absolute inset-0 h-full w-full\" : \"\"} ${className ?? \"\"}`}\n onError={onError}\n />\n );\n}\n\nfunction formatPortalPrice(\n price: string | undefined,\n currency: string | undefined,\n): string | null {\n if (!price) return null;\n const numericPrice = Number(price);\n if (Number.isNaN(numericPrice)) return `${currency ?? \"\"}${price}`;\n try {\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currency || \"USD\",\n }).format(numericPrice);\n } catch {\n return `$${price}`;\n }\n}\n\nfunction ProductCardContent({\n product,\n countryIso,\n companyLogoUrl,\n renderImage = defaultRenderImage,\n}: {\n product: ProductCardProduct;\n countryIso?: string;\n companyLogoUrl?: string | null;\n renderImage?: (props: RenderImageProps) => ReactNode;\n}) {\n const [isHovered, setIsHovered] = useState(false);\n const { t } = useShopTranslation();\n\n const isPortal = isPortalProduct(product);\n const coverImage = isPortal\n ? getPortalProductCoverImage(product)\n : getProductImageUrl(product as Parameters<typeof getProductImageUrl>[0]);\n const isVideo = isVideoUrl(coverImage);\n const productName = isPortal\n ? product.name || t(\"no_title\")\n : (product as LegacyProduct).title || t(\"no_title\");\n\n let repPrice: string | null | undefined = null;\n let price: string | null | undefined = null;\n if (isPortal) {\n // wholesale_price is non-null for reps, null for customers\n if (product.wholesale_price) {\n repPrice = formatPortalPrice(product.wholesale_price, product.currency);\n // Show retail as strikethrough if different from wholesale\n const retailFormatted = formatPortalPrice(\n product.price,\n product.currency,\n );\n if (retailFormatted !== repPrice) {\n price = retailFormatted;\n }\n } else {\n repPrice = formatPortalPrice(product.price, product.currency);\n }\n } else if (countryIso) {\n const prices = determineProductPrice(product, countryIso);\n repPrice = prices.repPrice;\n price = prices.price;\n }\n\n return (\n <>\n {/* Image/Video container */}\n <div\n className=\"bg-muted relative aspect-square overflow-hidden\"\n onMouseEnter={() => isVideo && setIsHovered(true)}\n onMouseLeave={() => isVideo && setIsHovered(false)}\n >\n {isVideo && isHovered ? (\n <video\n src={coverImage || \"\"}\n className=\"absolute inset-0 h-full w-full object-cover\"\n autoPlay\n muted\n loop\n playsInline\n />\n ) : (\n renderImage({\n src:\n isVideo && coverImage\n ? getVideoThumbnailUrl(coverImage)\n : coverImage ||\n \"https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png\",\n alt: productName,\n fill: true,\n className:\n \"object-cover transition-transform group-hover:scale-105\",\n onError: (e) => {\n e.currentTarget.src =\n companyLogoUrl ||\n \"https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png\";\n },\n unoptimized: true,\n })\n )}\n\n {/* Video play indicator */}\n {isVideo && !isHovered && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"flex size-16 items-center justify-center rounded-full bg-black/50 backdrop-blur-sm\">\n <CirclePlay className=\"size-12 text-white\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Product info */}\n <div className=\"px-3 pt-2 pb-4\">\n <h3 className=\"text-foreground line-clamp-1 text-sm font-bold\">\n {productName}\n </h3>\n\n <div className=\"flex items-center gap-2\">\n {repPrice && (\n <span className=\"text-foreground text-sm font-bold\">\n {repPrice}\n </span>\n )}\n {price && (\n <span className=\"text-muted-foreground text-sm line-through\">\n {price}\n </span>\n )}\n </div>\n\n {!isPortal && countryIso && (\n <div className=\"text-muted-foreground text-sm\">\n CV{\" \"}\n {getVariantCountryValue(\n getSelectedVariant(product as LegacyProduct),\n countryIso,\n \"cv\",\n ) || \"-\"}{\" \"}\n | QV{\" \"}\n {getVariantCountryValue(\n getSelectedVariant(product as LegacyProduct),\n countryIso,\n \"qv\",\n ) || \"-\"}\n </div>\n )}\n\n {isPortal && product.wholesale_price != null && (\n <div className=\"text-muted-foreground text-sm\">\n CV {product.cv ?? \"-\"} | QV {product.qv ?? \"-\"}\n </div>\n )}\n </div>\n </>\n );\n}\n\nfunction getSelectedVariant(\n product: LegacyProduct,\n): products.Variant | products.ShopVariant | null {\n if (!product.variants || product.variants.length === 0) return null;\n\n const masterVariant = product.variants.find(\n (v: products.Variant | products.ShopVariant) => {\n return \"is_master\" in v && v.is_master;\n },\n );\n if (masterVariant) return masterVariant;\n\n return product.variants[0] || null;\n}\n\nfunction getVariantCountryValue(\n variant: products.Variant | products.ShopVariant | null,\n countryIso: string,\n field: \"cv\" | \"qv\",\n): number | null {\n if (!variant || !variant.variant_countries) return null;\n\n if (\n typeof variant.variant_countries === \"object\" &&\n !Array.isArray(variant.variant_countries)\n ) {\n const countryData = variant.variant_countries[countryIso] as\n | products.VariantCountry\n | undefined;\n return countryData?.[field] ?? null;\n }\n\n if (Array.isArray(variant.variant_countries)) {\n const countryData = variant.variant_countries.find(\n (vc: products.ShopVariantCountry) => vc.country_iso === countryIso,\n );\n return countryData?.[field] ?? null;\n }\n\n return null;\n}\n\nexport default function ProductCard({\n product,\n countryIso,\n companyLogoUrl,\n showShareModal = false,\n setShareModalOpen,\n setSelectedProduct,\n renderLink,\n renderImage,\n onClick,\n}: ProductCardProps): React.JSX.Element {\n const cardContent = (\n <ProductCardContent\n product={product}\n {...(countryIso !== undefined && { countryIso })}\n {...(companyLogoUrl !== undefined && { companyLogoUrl })}\n {...(renderImage !== undefined && { renderImage })}\n />\n );\n\n const cardClassName = \"overflow-hidden border-0 shadow-none pt-0 gap-0\";\n\n if (showShareModal && !isPortalProduct(product)) {\n const handleShareClick = () => {\n if (setSelectedProduct && setShareModalOpen) {\n setSelectedProduct(product);\n setShareModalOpen(true);\n }\n };\n return (\n <Card className={cardClassName}>\n <button\n onClick={handleShareClick}\n className=\"group block w-full cursor-pointer text-left\"\n >\n {cardContent}\n </button>\n </Card>\n );\n }\n\n if (onClick) {\n return (\n <Card className={cardClassName}>\n <button\n onClick={onClick}\n className=\"group block w-full cursor-pointer text-left\"\n >\n {cardContent}\n </button>\n </Card>\n );\n }\n\n const href = `/portal/shop/${product.id}`;\n\n if (renderLink) {\n return (\n <Card className={cardClassName}>\n {renderLink({ href, children: cardContent })}\n </Card>\n );\n }\n\n return (\n <Card className={cardClassName}>\n <a href={href} className=\"group block cursor-pointer\">\n {cardContent}\n </a>\n </Card>\n );\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ComponentProps,\n} from \"react\";\nimport type React from \"react\";\nimport {\n usePortalProductCatalog,\n type PortalProductPageParam,\n type portalProducts,\n} from \"@fluid-app/products-core\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Skeleton,\n} from \"@fluid-app/ui-primitives\";\nimport { SearchSort } from \"@fluid-app/ui-components/components/SearchSort\";\nimport ProductCard, {\n tagPortalProduct,\n} from \"@fluid-app/shop-ui/components/product-card\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { ArrowUpDown, ImageIcon } from \"lucide-react\";\nimport {\n getBorderRadiusField,\n getColorField,\n getPaddingField,\n} from \"../core/fields\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\n\ntype ColumnsKey = 2 | 3 | 4 | 5 | 6;\n\ntype ShopWidgetProps = ComponentProps<\"div\"> & {\n titleEnabled?: boolean;\n title?: string;\n titleColor?: ColorOptions;\n showSearch?: boolean;\n showSort?: boolean;\n columns?: ColumnsKey;\n pageSize?: number;\n useDataSource?: boolean;\n products?: portalProducts.Product[];\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n cardBackground?: ColorOptions;\n cardTextColor?: ColorOptions;\n};\n\nconst GRID_BY_COLUMNS: Record<ColumnsKey, string> = {\n 2: \"grid grid-cols-2 gap-3 sm:gap-6\",\n 3: \"grid grid-cols-2 gap-3 sm:gap-6 md:grid-cols-3\",\n 4: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4\",\n 5: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5\",\n 6: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6\",\n};\n\nconst SORT_OPTIONS = [\n { id: \"title_asc\", label: \"Title (A–Z)\" },\n { id: \"title_desc\", label: \"Title (Z–A)\" },\n { id: \"price_asc\", label: \"Price (Low to High)\" },\n { id: \"price_desc\", label: \"Price (High to Low)\" },\n { id: \"created_at_desc\", label: \"Recently added\" },\n { id: \"created_at_asc\", label: \"Oldest\" },\n] as const;\n\nconst PREVIEW_PRODUCTS: ReadonlyArray<{\n id: string;\n name: string;\n price: string;\n}> = [\n { id: \"preview-1\", name: \"Premium Wireless Headphones\", price: \"$249\" },\n { id: \"preview-2\", name: \"Smart Watch Series X\", price: \"$199\" },\n { id: \"preview-3\", name: \"Sunglasses\", price: \"$79\" },\n { id: \"preview-4\", name: \"Trail Running Shoes\", price: \"$129\" },\n { id: \"preview-5\", name: \"Daypack Backpack\", price: \"$89\" },\n { id: \"preview-6\", name: \"Stainless Bottle\", price: \"$32\" },\n { id: \"preview-7\", name: \"Linen Throw\", price: \"$59\" },\n { id: \"preview-8\", name: \"Ceramic Mug\", price: \"$24\" },\n { id: \"preview-9\", name: \"Wool Blanket\", price: \"$148\" },\n { id: \"preview-10\", name: \"Leather Wallet\", price: \"$45\" },\n { id: \"preview-11\", name: \"Pour-Over Kettle\", price: \"$78\" },\n { id: \"preview-12\", name: \"Linen Shirt\", price: \"$95\" },\n];\n\nfunction clampColumns(value: number | undefined): ColumnsKey {\n const n = Math.round(value ?? 4);\n if (n <= 2) return 2;\n if (n >= 6) return 6;\n return n as ColumnsKey;\n}\n\nfunction clampPageSize(value: number | undefined): number {\n const n = Math.round(value ?? 25);\n return Math.min(100, Math.max(5, n));\n}\n\n// Data sources can deliver products in legacy/shareable shape (`title`,\n// `image_url`/`imageUrl`/`thumbnail_url`) or portal shape (`name`, `images`).\n// Modeled as a typed superset so the probe doesn't lose type-safety.\ntype LegacyProductFields = {\n title?: string;\n image_url?: string;\n imageUrl?: string;\n thumbnail_url?: string;\n};\n\ntype LegacyImageFields = {\n url?: string;\n image_url?: string;\n alt?: string | null;\n};\n\nfunction normalizeDataSourceProduct(\n input: portalProducts.Product,\n): portalProducts.Product {\n const r = input as portalProducts.Product & LegacyProductFields;\n const name = r.name ?? r.title ?? \"\";\n\n let images: portalProducts.ProductImage[];\n if (Array.isArray(r.images) && r.images.length > 0) {\n images = r.images.flatMap<portalProducts.ProductImage>((img) => {\n const i = img as LegacyImageFields;\n const url = i.url ?? i.image_url;\n if (!url) return [];\n return [{ url, alt: i.alt ?? null }];\n });\n } else {\n const url = r.image_url ?? r.imageUrl ?? r.thumbnail_url;\n images = url ? [{ url, alt: null }] : [];\n }\n\n // Strip undefined props from the spread so EOPT accepts the result.\n const cleaned: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(r)) {\n if (v !== undefined) cleaned[k] = v;\n }\n return { ...(cleaned as portalProducts.Product), name, images };\n}\n\n// Tailwind v4 @theme inline aliases --color-*; remap the underlying --card / --foreground tokens.\nfunction cardScopedStyle(\n cardBackground: ColorOptions | undefined,\n cardTextColor: ColorOptions | undefined,\n): React.CSSProperties {\n const style: Record<string, string> = {};\n if (cardBackground) style[\"--card\"] = `var(--${cardBackground})`;\n if (cardTextColor) style[\"--foreground\"] = `var(--${cardTextColor})`;\n return style as React.CSSProperties;\n}\n\nexport function ShopWidget({\n titleEnabled = true,\n title = \"\",\n titleColor = \"foreground\",\n showSearch = true,\n showSort = true,\n columns = 4,\n pageSize = 25,\n useDataSource = false,\n products,\n\n background = { type: \"solid\", color: \"background\" },\n padding = 6,\n borderRadius = \"lg\",\n\n cardBackground,\n cardTextColor,\n\n className,\n ...props\n}: ShopWidgetProps): React.JSX.Element {\n const { isPreview } = useWidgetPreviewContext();\n const safeColumns = clampColumns(columns);\n const safePageSize = clampPageSize(pageSize);\n\n const backgroundColor = background.color ?? \"background\";\n const backgroundImage =\n background.type === \"image\" &&\n (background.resource?.image_url || background.resource?.imageUrl)\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n return (\n <div\n className={`bg-${backgroundColor} p-${padding} rounded-${borderRadius} @container ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {isPreview ? (\n <PreviewBody\n columns={safeColumns}\n titleEnabled={titleEnabled}\n title={title}\n titleColor={titleColor}\n showSearch={showSearch}\n showSort={showSort}\n cardBackground={cardBackground}\n cardTextColor={cardTextColor}\n />\n ) : (\n <LiveBody\n columns={safeColumns}\n pageSize={safePageSize}\n titleEnabled={titleEnabled}\n title={title}\n titleColor={titleColor}\n showSearch={showSearch}\n showSort={showSort}\n useDataSource={useDataSource}\n products={products}\n cardBackground={cardBackground}\n cardTextColor={cardTextColor}\n />\n )}\n </div>\n );\n}\n\nfunction PreviewBody({\n columns,\n titleEnabled,\n title,\n titleColor,\n showSearch,\n showSort,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const hasTitle = titleEnabled && !!title;\n const hasHeader = hasTitle || showSearch || showSort;\n return (\n <div>\n {hasHeader && (\n <div className=\"mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2\">\n {hasTitle && (\n <h2\n className={`text-${titleColor} text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {(showSearch || showSort) && (\n <div className=\"flex items-center gap-2 sm:ml-auto\">\n {showSearch && (\n <div\n aria-hidden\n className=\"bg-muted h-9 w-full max-w-sm rounded-md sm:w-64\"\n />\n )}\n {showSort && (\n <div aria-hidden className=\"bg-muted size-9 rounded-md\" />\n )}\n </div>\n )}\n </div>\n )}\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {PREVIEW_PRODUCTS.slice(0, columns * 2).map((p) => (\n <ProductCardCompact\n key={p.id}\n name={p.name}\n imageUrl={null}\n price={p.price}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction LiveBody({\n useDataSource,\n products,\n ...rest\n}: {\n columns: ColumnsKey;\n pageSize: number;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n useDataSource: boolean;\n products: portalProducts.Product[] | undefined;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n // Branch at the component level so the catalog hook (which throws when\n // PortalProductsCoreProvider is missing) is only called in catalog mode.\n if (useDataSource) {\n return (\n <DataSourceBody\n columns={rest.columns}\n titleEnabled={rest.titleEnabled}\n title={rest.title}\n titleColor={rest.titleColor}\n products={products ?? []}\n cardBackground={rest.cardBackground}\n cardTextColor={rest.cardTextColor}\n />\n );\n }\n return <CatalogBody {...rest} />;\n}\n\nfunction DataSourceBody({\n columns,\n titleEnabled,\n title,\n titleColor,\n products,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n products: portalProducts.Product[];\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const { onNavigate } = useWidgetInteraction();\n const handleSelect = useCallback(\n (id: string | number) => {\n onNavigate?.(`shop/${id}`);\n },\n [onNavigate],\n );\n\n const hasTitle = titleEnabled && !!title;\n\n return (\n <div>\n {hasTitle && (\n <h2\n className={`text-${titleColor} mb-6 text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {products.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">No products yet.</p>\n </div>\n ) : (\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {products.map((product) => {\n if (product.id == null) return null;\n // Defensive: older widgets may have a data source that returns\n // non-product shareables (Medium, EnrollmentPack, Page, Library).\n // The shop widget only knows how to navigate to product detail,\n // so skip anything that isn't a Product. Items without\n // `shareable_type` (static products / untagged feeds) fall through.\n const shareableType = (product as { shareable_type?: string })\n .shareable_type;\n if (shareableType != null && shareableType !== \"Product\")\n return null;\n const productId = product.id;\n return (\n <ProductCard\n key={productId}\n product={tagPortalProduct(normalizeDataSourceProduct(product))}\n onClick={() => handleSelect(productId)}\n />\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\nfunction CatalogBody({\n columns,\n pageSize,\n titleEnabled,\n title,\n titleColor,\n showSearch,\n showSort,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n pageSize: number;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const observerTarget = useRef<HTMLDivElement>(null);\n const { onNavigate } = useWidgetInteraction();\n\n const catalog = usePortalProductCatalog({ perPage: pageSize });\n const {\n data,\n isLoading,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n error,\n isFetched,\n } = useInfiniteQuery({\n queryKey: catalog.queryKey,\n queryFn: ({ pageParam, signal }) =>\n catalog.fetchProducts(pageParam, signal),\n getNextPageParam: catalog.getNextPageParam,\n initialPageParam: undefined as PortalProductPageParam,\n });\n\n const allProducts = useMemo(\n () => data?.pages.flatMap((page) => page.products) ?? [],\n [data?.pages],\n );\n\n // Hard cap so pageSize doubles as a \"show at most N\" limit.\n const visibleProducts = useMemo(\n () => allProducts.slice(0, pageSize),\n [allProducts, pageSize],\n );\n const reachedLimit = visibleProducts.length >= pageSize;\n\n const handleIntersect = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n if (\n entries[0]?.isIntersecting &&\n hasNextPage &&\n !isFetchingNextPage &&\n !reachedLimit\n ) {\n fetchNextPage();\n }\n },\n [hasNextPage, isFetchingNextPage, fetchNextPage, reachedLimit],\n );\n\n useEffect(() => {\n const target = observerTarget.current;\n if (!target) return;\n const observer = new IntersectionObserver(handleIntersect, {\n threshold: 0.1,\n rootMargin: \"200px\",\n });\n observer.observe(target);\n return () => observer.disconnect();\n }, [handleIntersect]);\n\n const handleSelect = useCallback(\n (id: string | number) => {\n onNavigate?.(`shop/${id}`);\n },\n [onNavigate],\n );\n\n const hasTitle = titleEnabled && !!title;\n const hasHeader = hasTitle || showSearch || showSort;\n\n return (\n <div>\n {hasHeader && (\n <div className=\"mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2\">\n {hasTitle && (\n <h2\n className={`text-${titleColor} text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {(showSearch || showSort) && (\n <div className=\"flex items-center gap-2 sm:ml-auto\">\n {showSearch && (\n <div className=\"w-full max-w-sm sm:w-64\">\n <SearchSort\n searchValue={catalog.searchTerm}\n onSearchChange={catalog.setSearchTerm}\n placeholder=\"Search products\"\n />\n </div>\n )}\n {showSort && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"border-foreground/10 size-9 shrink-0\"\n >\n <ArrowUpDown className=\"size-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n <DropdownMenuLabel>Sort by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup\n value={catalog.currentSort}\n onValueChange={catalog.setCurrentSort}\n >\n {SORT_OPTIONS.map((opt) => (\n <DropdownMenuRadioItem key={opt.id} value={opt.id}>\n {opt.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n )}\n </div>\n )}\n\n {isLoading ? (\n <SkeletonGrid columns={columns} count={columns * 2} />\n ) : error && visibleProducts.length === 0 ? (\n <div className=\"bg-destructive/10 text-destructive my-6 rounded-lg px-4 py-3 text-sm\">\n Couldn’t load products. Try again later.\n </div>\n ) : isFetched && visibleProducts.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">\n {catalog.searchTerm\n ? `No products match “${catalog.searchTerm}”.`\n : \"No products yet.\"}\n </p>\n </div>\n ) : (\n <>\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {visibleProducts.map((product) => {\n if (product.id == null) return null;\n const productId = product.id;\n return (\n <ProductCard\n key={productId}\n product={tagPortalProduct(product)}\n onClick={() => handleSelect(productId)}\n />\n );\n })}\n </div>\n {!reachedLimit && <div ref={observerTarget} />}\n {isFetchingNextPage && !reachedLimit && (\n <div className=\"mt-6\">\n <SkeletonGrid columns={columns} count={columns} />\n </div>\n )}\n {error && (\n <div className=\"bg-destructive/10 text-destructive mt-6 rounded-lg px-4 py-3 text-sm\">\n Couldn’t load more products. Try again later.\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction ProductCardCompact({\n name,\n imageUrl,\n price,\n onClick,\n}: {\n name: string;\n imageUrl: string | null;\n price: string | null;\n onClick?: () => void;\n}) {\n const interactive = !!onClick;\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={!interactive}\n className={`bg-card text-card-foreground group flex flex-col overflow-hidden rounded-lg border border-transparent text-left ${interactive ? \"hover:border-border cursor-pointer transition-shadow hover:shadow-md\" : \"cursor-default\"} focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none`}\n >\n <div className=\"bg-muted relative aspect-square w-full overflow-hidden\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={name}\n className=\"h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <ImageIcon className=\"text-muted-foreground/40 size-10\" />\n </div>\n )}\n </div>\n <div className=\"p-3\">\n <h3 className=\"text-foreground line-clamp-2 text-sm font-medium\">\n {name}\n </h3>\n {price && (\n <p className=\"text-foreground mt-1 text-sm font-semibold\">{price}</p>\n )}\n </div>\n </button>\n );\n}\n\nfunction SkeletonGrid({\n columns,\n count,\n}: {\n columns: ColumnsKey;\n count: number;\n}) {\n return (\n <div className={GRID_BY_COLUMNS[columns]}>\n {Array.from({ length: count }, (_, i) => (\n <div key={i} className=\"space-y-3\">\n <Skeleton className=\"aspect-square w-full rounded-lg\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/3\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport const shopWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShopWidget\",\n displayName: \"Shop\",\n tabsConfig: [\n { id: \"styling\", label: \"Styling\" },\n { id: \"data\", label: \"Data\" },\n ],\n dataSourceTargetProps: [\"products\"],\n fields: [\n // Title group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the heading shown above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"title\",\n label: \"Title\",\n type: \"text\",\n description: \"Heading text shown above the grid\",\n defaultValue: \"\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color of the heading text\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Display group\n {\n key: \"showSearch\",\n label: \"Show Search\",\n type: \"boolean\",\n description: \"Display the search input above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"showSort\",\n label: \"Show Sort\",\n type: \"boolean\",\n description: \"Display the sort menu above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"columns\",\n label: \"Columns (desktop)\",\n type: \"select\",\n description:\n \"Max columns at the largest breakpoint. Mobile is always 2 columns; intermediate sizes scale smoothly between.\",\n options: [\n { label: \"2\", value: 2 },\n { label: \"3\", value: 3 },\n { label: \"4\", value: 4 },\n { label: \"5\", value: 5 },\n { label: \"6\", value: 6 },\n ],\n defaultValue: 4,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Container background\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Inner spacing around the grid\",\n defaultValue: 6,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Container corner radius\",\n defaultValue: \"lg\",\n tab: \"styling\",\n group: \"Design\",\n }),\n\n // Card group — optional theme overrides; unset means \"inherit from theme\".\n getColorField({\n key: \"cardBackground\",\n label: \"Card Background\",\n description:\n \"Override the card background color. Leave unset to use the theme's card color.\",\n tab: \"styling\",\n group: \"Card\",\n }),\n getColorField({\n key: \"cardTextColor\",\n label: \"Card Text\",\n description:\n \"Override title + price color inside each card. Leave unset to use the theme's foreground color.\",\n tab: \"styling\",\n group: \"Card\",\n }),\n\n // Data tab\n {\n key: \"useDataSource\",\n label: \"Use Data Source\",\n type: \"boolean\",\n description:\n \"Off shows all products from the catalog. On replaces the catalog with a data source — disables search and sort.\",\n defaultValue: false,\n tab: \"data\",\n group: \"Data Configuration\",\n },\n {\n key: \"pageSize\",\n label: \"Products to show\",\n type: \"number\",\n description: \"Maximum number of products rendered in the grid\",\n defaultValue: 25,\n min: 5,\n max: 100,\n step: 5,\n tab: \"data\",\n group: \"Data Configuration\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"dataSource\",\n label: \"Data Source\",\n type: \"dataSource\",\n description: \"\",\n tab: \"data\",\n group: \"Data Configuration\",\n requiresKeyToBeTrue: \"useDataSource\",\n },\n ],\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ShopWidget-Cqnwq0AG.mjs","names":[],"sources":["../../../shop/core/src/translation-api-context.ts","../../../shop/ui/src/utils/media-helpers.ts","../../../shop/ui/src/components/product-card.tsx","../../widgets/src/widgets/ShopWidget.tsx"],"sourcesContent":["import { createTranslationContext } from \"@fluid-app/i18n/translation-api-context-factory\";\nimport type { ShopDict } from \"./translation-dictionary\";\n\nconst { Provider, useTranslation } = createTranslationContext<ShopDict>(\"Shop\");\n\nexport const ShopTranslationProvider = Provider;\nexport const useShopTranslation = useTranslation;\n","const VIDEO_EXTENSIONS = [\n \".mp4\",\n \".webm\",\n \".mov\",\n \".avi\",\n \".m4v\",\n \".mkv\",\n \".ogv\",\n \".ogg\",\n \".wmv\",\n \".flv\",\n \".3gp\",\n];\n\nconst IMAGE_EXTENSIONS = [\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".gif\",\n \".webp\",\n \".svg\",\n \".bmp\",\n \".ico\",\n \".tiff\",\n \".tif\",\n];\n\nexport function isVideoUrl(url: string | undefined | null): boolean {\n if (!url) return false;\n const lowerUrl = url.toLowerCase();\n return VIDEO_EXTENSIONS.some((ext) => lowerUrl.includes(ext));\n}\n\nexport function isImageUrl(url: string | undefined | null): boolean {\n if (!url) return false;\n const lowerUrl = url.toLowerCase();\n return IMAGE_EXTENSIONS.some((ext) => lowerUrl.includes(ext));\n}\n\nexport function getMediaTypeFromUrl(\n url: string | undefined | null,\n): \"video\" | \"image\" | \"unknown\" {\n if (isVideoUrl(url)) return \"video\";\n if (isImageUrl(url)) return \"image\";\n return \"unknown\";\n}\n\nexport function getVideoThumbnailUrl(videoUrl: string): string {\n if (videoUrl.includes(\"ik.imagekit.io\")) {\n return `${videoUrl}/ik-thumbnail.jpg`;\n }\n return videoUrl;\n}\n\nexport function ensureImageIsFeatured<\n T extends { image_url: string; position?: number },\n>(items: T[]): T[] {\n if (items.length === 0) return items;\n\n const firstItem = items[0];\n if (!firstItem || !isVideoUrl(firstItem.image_url)) {\n return items;\n }\n\n const firstImageIndex = items.findIndex(\n (item) => !isVideoUrl(item.image_url),\n );\n\n if (firstImageIndex === -1) {\n return items;\n }\n\n const reordered = [...items];\n const [imageToMove] = reordered.splice(firstImageIndex, 1);\n if (imageToMove) {\n reordered.unshift(imageToMove);\n }\n\n return reordered;\n}\n","import type React from \"react\";\nimport { useState, type ReactNode } from \"react\";\nimport type { products, portalProducts } from \"@fluid-app/products-core\";\nimport {\n determineProductPrice,\n getProductImageUrl,\n} from \"@fluid-app/products-core\";\nimport { Card } from \"@fluid-app/ui-primitives\";\nimport { useShopTranslation } from \"@fluid-app/shop-core/translation-api-context\";\nimport { CirclePlay } from \"lucide-react\";\nimport { getVideoThumbnailUrl, isVideoUrl } from \"../utils/media-helpers\";\n\ntype LegacyProduct = (products.Product | products.ShopProduct) & {\n kind?: string;\n video_url?: string;\n};\n\nexport interface RenderImageProps {\n src: string;\n alt: string;\n fill?: boolean;\n className?: string;\n onError?: (e: React.SyntheticEvent<HTMLImageElement>) => void;\n unoptimized?: boolean;\n}\n\ntype TaggedPortalProduct = portalProducts.Product & {\n readonly __portalProduct: true;\n};\n\nexport type ProductCardProduct = LegacyProduct | TaggedPortalProduct;\n\ninterface ProductCardProps {\n product: ProductCardProduct;\n countryIso?: string;\n companyLogoUrl?: string | null;\n showShareModal?: boolean;\n setShareModalOpen?: (open: boolean) => void;\n setSelectedProduct?: (product: LegacyProduct) => void;\n renderLink?: (props: { href: string; children: ReactNode }) => ReactNode;\n renderImage?: (props: RenderImageProps) => ReactNode;\n onClick?: () => void;\n}\n\nexport function tagPortalProduct(\n product: portalProducts.Product,\n): TaggedPortalProduct {\n return { ...product, __portalProduct: true as const };\n}\n\nfunction isPortalProduct(\n product: ProductCardProduct,\n): product is TaggedPortalProduct {\n return \"__portalProduct\" in product && product.__portalProduct === true;\n}\n\nfunction getPortalProductCoverImage(\n product: portalProducts.Product,\n): string | null {\n if (product.images && product.images.length > 0) {\n return product.images[0]?.url ?? null;\n }\n return null;\n}\n\nfunction defaultRenderImage({\n src,\n alt,\n fill,\n className,\n onError,\n}: RenderImageProps): ReactNode {\n return (\n <img\n src={src}\n alt={alt}\n className={`${fill ? \"absolute inset-0 h-full w-full\" : \"\"} ${className ?? \"\"}`}\n onError={onError}\n />\n );\n}\n\nfunction formatPortalPrice(\n price: string | undefined,\n currency: string | undefined,\n): string | null {\n if (!price) return null;\n const numericPrice = Number(price);\n if (Number.isNaN(numericPrice)) return `${currency ?? \"\"}${price}`;\n try {\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currency || \"USD\",\n }).format(numericPrice);\n } catch {\n return `$${price}`;\n }\n}\n\nfunction ProductCardContent({\n product,\n countryIso,\n companyLogoUrl,\n renderImage = defaultRenderImage,\n}: {\n product: ProductCardProduct;\n countryIso?: string;\n companyLogoUrl?: string | null;\n renderImage?: (props: RenderImageProps) => ReactNode;\n}) {\n const [isHovered, setIsHovered] = useState(false);\n const { t } = useShopTranslation();\n\n const isPortal = isPortalProduct(product);\n const coverImage = isPortal\n ? getPortalProductCoverImage(product)\n : getProductImageUrl(product as Parameters<typeof getProductImageUrl>[0]);\n const isVideo = isVideoUrl(coverImage);\n const productName = isPortal\n ? product.name || t(\"no_title\")\n : (product as LegacyProduct).title || t(\"no_title\");\n\n let repPrice: string | null | undefined = null;\n let price: string | null | undefined = null;\n if (isPortal) {\n // wholesale_price is non-null for reps, null for customers\n if (product.wholesale_price) {\n repPrice = formatPortalPrice(product.wholesale_price, product.currency);\n // Show retail as strikethrough if different from wholesale\n const retailFormatted = formatPortalPrice(\n product.price,\n product.currency,\n );\n if (retailFormatted !== repPrice) {\n price = retailFormatted;\n }\n } else {\n repPrice = formatPortalPrice(product.price, product.currency);\n }\n } else if (countryIso) {\n const prices = determineProductPrice(product, countryIso);\n repPrice = prices.repPrice;\n price = prices.price;\n }\n\n return (\n <>\n {/* Image/Video container */}\n <div\n className=\"bg-muted relative aspect-square overflow-hidden\"\n onMouseEnter={() => isVideo && setIsHovered(true)}\n onMouseLeave={() => isVideo && setIsHovered(false)}\n >\n {isVideo && isHovered ? (\n <video\n src={coverImage || \"\"}\n className=\"absolute inset-0 h-full w-full object-cover\"\n autoPlay\n muted\n loop\n playsInline\n />\n ) : (\n renderImage({\n src:\n isVideo && coverImage\n ? getVideoThumbnailUrl(coverImage)\n : coverImage ||\n \"https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png\",\n alt: productName,\n fill: true,\n className:\n \"object-cover transition-transform group-hover:scale-105\",\n onError: (e) => {\n e.currentTarget.src =\n companyLogoUrl ||\n \"https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png\";\n },\n unoptimized: true,\n })\n )}\n\n {/* Video play indicator */}\n {isVideo && !isHovered && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"flex size-16 items-center justify-center rounded-full bg-black/50 backdrop-blur-sm\">\n <CirclePlay className=\"size-12 text-white\" />\n </div>\n </div>\n )}\n </div>\n\n {/* Product info */}\n <div className=\"px-3 pt-2 pb-4\">\n <h3 className=\"text-foreground line-clamp-1 text-sm font-bold\">\n {productName}\n </h3>\n\n <div className=\"flex items-center gap-2\">\n {repPrice && (\n <span className=\"text-foreground text-sm font-bold\">\n {repPrice}\n </span>\n )}\n {price && (\n <span className=\"text-muted-foreground text-sm line-through\">\n {price}\n </span>\n )}\n </div>\n\n {!isPortal && countryIso && (\n <div className=\"text-muted-foreground text-sm\">\n CV{\" \"}\n {getVariantCountryValue(\n getSelectedVariant(product as LegacyProduct),\n countryIso,\n \"cv\",\n ) || \"-\"}{\" \"}\n | QV{\" \"}\n {getVariantCountryValue(\n getSelectedVariant(product as LegacyProduct),\n countryIso,\n \"qv\",\n ) || \"-\"}\n </div>\n )}\n\n {isPortal && product.wholesale_price != null && (\n <div className=\"text-muted-foreground text-sm\">\n CV {product.cv ?? \"-\"} | QV {product.qv ?? \"-\"}\n </div>\n )}\n </div>\n </>\n );\n}\n\nfunction getSelectedVariant(\n product: LegacyProduct,\n): products.Variant | products.ShopVariant | null {\n if (!product.variants || product.variants.length === 0) return null;\n\n const masterVariant = product.variants.find(\n (v: products.Variant | products.ShopVariant) => {\n return \"is_master\" in v && v.is_master;\n },\n );\n if (masterVariant) return masterVariant;\n\n return product.variants[0] || null;\n}\n\nfunction getVariantCountryValue(\n variant: products.Variant | products.ShopVariant | null,\n countryIso: string,\n field: \"cv\" | \"qv\",\n): number | null {\n if (!variant || !variant.variant_countries) return null;\n\n if (\n typeof variant.variant_countries === \"object\" &&\n !Array.isArray(variant.variant_countries)\n ) {\n const countryData = variant.variant_countries[countryIso] as\n | products.VariantCountry\n | undefined;\n return countryData?.[field] ?? null;\n }\n\n if (Array.isArray(variant.variant_countries)) {\n const countryData = variant.variant_countries.find(\n (vc: products.ShopVariantCountry) => vc.country_iso === countryIso,\n );\n return countryData?.[field] ?? null;\n }\n\n return null;\n}\n\nexport default function ProductCard({\n product,\n countryIso,\n companyLogoUrl,\n showShareModal = false,\n setShareModalOpen,\n setSelectedProduct,\n renderLink,\n renderImage,\n onClick,\n}: ProductCardProps): React.JSX.Element {\n const cardContent = (\n <ProductCardContent\n product={product}\n {...(countryIso !== undefined && { countryIso })}\n {...(companyLogoUrl !== undefined && { companyLogoUrl })}\n {...(renderImage !== undefined && { renderImage })}\n />\n );\n\n const cardClassName = \"overflow-hidden border-0 shadow-none pt-0 gap-0\";\n\n if (showShareModal && !isPortalProduct(product)) {\n const handleShareClick = () => {\n if (setSelectedProduct && setShareModalOpen) {\n setSelectedProduct(product);\n setShareModalOpen(true);\n }\n };\n return (\n <Card className={cardClassName}>\n <button\n onClick={handleShareClick}\n className=\"group block w-full cursor-pointer text-left\"\n >\n {cardContent}\n </button>\n </Card>\n );\n }\n\n if (onClick) {\n return (\n <Card className={cardClassName}>\n <button\n onClick={onClick}\n className=\"group block w-full cursor-pointer text-left\"\n >\n {cardContent}\n </button>\n </Card>\n );\n }\n\n const href = `/portal/shop/${product.id}`;\n\n if (renderLink) {\n return (\n <Card className={cardClassName}>\n {renderLink({ href, children: cardContent })}\n </Card>\n );\n }\n\n return (\n <Card className={cardClassName}>\n <a href={href} className=\"group block cursor-pointer\">\n {cardContent}\n </a>\n </Card>\n );\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ComponentProps,\n} from \"react\";\nimport type React from \"react\";\nimport {\n usePortalProductCatalog,\n type PortalProductPageParam,\n type portalProducts,\n} from \"@fluid-app/products-core\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Skeleton,\n} from \"@fluid-app/ui-primitives\";\nimport { SearchSort } from \"@fluid-app/ui-components/components/SearchSort\";\nimport ProductCard, {\n tagPortalProduct,\n} from \"@fluid-app/shop-ui/components/product-card\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { ArrowUpDown, ImageIcon } from \"lucide-react\";\nimport {\n getBorderRadiusField,\n getColorField,\n getPaddingField,\n} from \"../core/fields\";\nimport { useWidgetInteraction } from \"../contexts/WidgetInteractionContext\";\n\ntype ColumnsKey = 2 | 3 | 4 | 5 | 6;\n\ntype ShopWidgetProps = ComponentProps<\"div\"> & {\n titleEnabled?: boolean;\n title?: string;\n titleColor?: ColorOptions;\n showSearch?: boolean;\n showSort?: boolean;\n columns?: ColumnsKey;\n pageSize?: number;\n useDataSource?: boolean;\n products?: portalProducts.Product[];\n background?: BackgroundValue;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n cardBackground?: ColorOptions;\n cardTextColor?: ColorOptions;\n};\n\nconst GRID_BY_COLUMNS: Record<ColumnsKey, string> = {\n 2: \"grid grid-cols-2 gap-3 sm:gap-6\",\n 3: \"grid grid-cols-2 gap-3 sm:gap-6 md:grid-cols-3\",\n 4: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4\",\n 5: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5\",\n 6: \"grid grid-cols-2 gap-3 sm:gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6\",\n};\n\nconst SORT_OPTIONS = [\n { id: \"title_asc\", label: \"Title (A–Z)\" },\n { id: \"title_desc\", label: \"Title (Z–A)\" },\n { id: \"price_asc\", label: \"Price (Low to High)\" },\n { id: \"price_desc\", label: \"Price (High to Low)\" },\n { id: \"created_at_desc\", label: \"Recently added\" },\n { id: \"created_at_asc\", label: \"Oldest\" },\n] as const;\n\nconst PREVIEW_PRODUCTS: ReadonlyArray<{\n id: string;\n name: string;\n price: string;\n}> = [\n { id: \"preview-1\", name: \"Premium Wireless Headphones\", price: \"$249\" },\n { id: \"preview-2\", name: \"Smart Watch Series X\", price: \"$199\" },\n { id: \"preview-3\", name: \"Sunglasses\", price: \"$79\" },\n { id: \"preview-4\", name: \"Trail Running Shoes\", price: \"$129\" },\n { id: \"preview-5\", name: \"Daypack Backpack\", price: \"$89\" },\n { id: \"preview-6\", name: \"Stainless Bottle\", price: \"$32\" },\n { id: \"preview-7\", name: \"Linen Throw\", price: \"$59\" },\n { id: \"preview-8\", name: \"Ceramic Mug\", price: \"$24\" },\n { id: \"preview-9\", name: \"Wool Blanket\", price: \"$148\" },\n { id: \"preview-10\", name: \"Leather Wallet\", price: \"$45\" },\n { id: \"preview-11\", name: \"Pour-Over Kettle\", price: \"$78\" },\n { id: \"preview-12\", name: \"Linen Shirt\", price: \"$95\" },\n];\n\nfunction clampColumns(value: number | undefined): ColumnsKey {\n const n = Math.round(value ?? 4);\n if (n <= 2) return 2;\n if (n >= 6) return 6;\n return n as ColumnsKey;\n}\n\nfunction clampPageSize(value: number | undefined): number {\n const n = Math.round(value ?? 25);\n return Math.min(100, Math.max(5, n));\n}\n\n// Data sources can deliver products in legacy/shareable shape (`title`,\n// `image_url`/`imageUrl`/`thumbnail_url`) or portal shape (`name`, `images`).\n// Modeled as a typed superset so the probe doesn't lose type-safety.\ntype LegacyProductFields = {\n title?: string;\n image_url?: string;\n imageUrl?: string;\n thumbnail_url?: string;\n};\n\ntype LegacyImageFields = {\n url?: string;\n image_url?: string;\n alt?: string | null;\n};\n\nfunction normalizeDataSourceProduct(\n input: portalProducts.Product,\n): portalProducts.Product {\n const r = input as portalProducts.Product & LegacyProductFields;\n const name = r.name ?? r.title ?? \"\";\n\n let images: portalProducts.ProductImage[];\n if (Array.isArray(r.images) && r.images.length > 0) {\n images = r.images.flatMap<portalProducts.ProductImage>((img) => {\n const i = img as LegacyImageFields;\n const url = i.url ?? i.image_url;\n if (!url) return [];\n return [{ url, alt: i.alt ?? null }];\n });\n } else {\n const url = r.image_url ?? r.imageUrl ?? r.thumbnail_url;\n images = url ? [{ url, alt: null }] : [];\n }\n\n // Strip undefined props from the spread so EOPT accepts the result.\n const cleaned: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(r)) {\n if (v !== undefined) cleaned[k] = v;\n }\n return { ...(cleaned as portalProducts.Product), name, images };\n}\n\n// Tailwind v4 @theme inline aliases --color-*; remap the underlying --card / --foreground tokens.\nfunction cardScopedStyle(\n cardBackground: ColorOptions | undefined,\n cardTextColor: ColorOptions | undefined,\n): React.CSSProperties {\n const style: Record<string, string> = {};\n if (cardBackground) style[\"--card\"] = `var(--${cardBackground})`;\n if (cardTextColor) style[\"--foreground\"] = `var(--${cardTextColor})`;\n return style as React.CSSProperties;\n}\n\nexport function ShopWidget({\n titleEnabled = true,\n title = \"\",\n titleColor = \"foreground\",\n showSearch = true,\n showSort = true,\n columns = 4,\n pageSize = 25,\n useDataSource = false,\n products,\n\n background = { type: \"solid\", color: \"background\" },\n padding = 6,\n borderRadius = \"lg\",\n\n cardBackground,\n cardTextColor,\n\n className,\n ...props\n}: ShopWidgetProps): React.JSX.Element {\n const { isPreview } = useWidgetPreviewContext();\n const safeColumns = clampColumns(columns);\n const safePageSize = clampPageSize(pageSize);\n\n const backgroundColor = background.color ?? \"background\";\n const backgroundImage =\n background.type === \"image\" &&\n (background.resource?.image_url || background.resource?.imageUrl)\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n return (\n <div\n className={`bg-${backgroundColor} p-${padding} rounded-${borderRadius} @container ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {isPreview ? (\n <PreviewBody\n columns={safeColumns}\n titleEnabled={titleEnabled}\n title={title}\n titleColor={titleColor}\n showSearch={showSearch}\n showSort={showSort}\n cardBackground={cardBackground}\n cardTextColor={cardTextColor}\n />\n ) : (\n <LiveBody\n columns={safeColumns}\n pageSize={safePageSize}\n titleEnabled={titleEnabled}\n title={title}\n titleColor={titleColor}\n showSearch={showSearch}\n showSort={showSort}\n useDataSource={useDataSource}\n products={products}\n cardBackground={cardBackground}\n cardTextColor={cardTextColor}\n />\n )}\n </div>\n );\n}\n\nfunction PreviewBody({\n columns,\n titleEnabled,\n title,\n titleColor,\n showSearch,\n showSort,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const hasTitle = titleEnabled && !!title;\n const hasHeader = hasTitle || showSearch || showSort;\n return (\n <div>\n {hasHeader && (\n <div className=\"mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2\">\n {hasTitle && (\n <h2\n className={`text-${titleColor} text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {(showSearch || showSort) && (\n <div className=\"flex items-center gap-2 sm:ml-auto\">\n {showSearch && (\n <div\n aria-hidden\n className=\"bg-muted h-9 w-full max-w-sm rounded-md sm:w-64\"\n />\n )}\n {showSort && (\n <div aria-hidden className=\"bg-muted size-9 rounded-md\" />\n )}\n </div>\n )}\n </div>\n )}\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {PREVIEW_PRODUCTS.slice(0, columns * 2).map((p) => (\n <ProductCardCompact\n key={p.id}\n name={p.name}\n imageUrl={null}\n price={p.price}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction LiveBody({\n useDataSource,\n products,\n ...rest\n}: {\n columns: ColumnsKey;\n pageSize: number;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n useDataSource: boolean;\n products: portalProducts.Product[] | undefined;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n // Branch at the component level so the catalog hook (which throws when\n // PortalProductsCoreProvider is missing) is only called in catalog mode.\n if (useDataSource) {\n return (\n <DataSourceBody\n columns={rest.columns}\n titleEnabled={rest.titleEnabled}\n title={rest.title}\n titleColor={rest.titleColor}\n products={products ?? []}\n cardBackground={rest.cardBackground}\n cardTextColor={rest.cardTextColor}\n />\n );\n }\n return <CatalogBody {...rest} />;\n}\n\nfunction DataSourceBody({\n columns,\n titleEnabled,\n title,\n titleColor,\n products,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n products: portalProducts.Product[];\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const { onNavigate } = useWidgetInteraction();\n const handleSelect = useCallback(\n (id: string | number) => {\n onNavigate?.(`shop/${id}`);\n },\n [onNavigate],\n );\n\n const hasTitle = titleEnabled && !!title;\n\n return (\n <div>\n {hasTitle && (\n <h2\n className={`text-${titleColor} mb-6 text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {products.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">No products yet.</p>\n </div>\n ) : (\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {products.map((product) => {\n if (product.id == null) return null;\n // Defensive: older widgets may have a data source that returns\n // non-product shareables (Medium, EnrollmentPack, Page, Library).\n // The shop widget only knows how to navigate to product detail,\n // so skip anything that isn't a Product. Items without\n // `shareable_type` (static products / untagged feeds) fall through.\n const shareableType = (product as { shareable_type?: string })\n .shareable_type;\n if (shareableType != null && shareableType !== \"Product\")\n return null;\n const productId = product.id;\n return (\n <ProductCard\n key={productId}\n product={tagPortalProduct(normalizeDataSourceProduct(product))}\n onClick={() => handleSelect(productId)}\n />\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\nfunction CatalogBody({\n columns,\n pageSize,\n titleEnabled,\n title,\n titleColor,\n showSearch,\n showSort,\n cardBackground,\n cardTextColor,\n}: {\n columns: ColumnsKey;\n pageSize: number;\n titleEnabled: boolean;\n title: string | undefined;\n titleColor: ColorOptions;\n showSearch: boolean;\n showSort: boolean;\n cardBackground: ColorOptions | undefined;\n cardTextColor: ColorOptions | undefined;\n}) {\n const observerTarget = useRef<HTMLDivElement>(null);\n const { onNavigate } = useWidgetInteraction();\n\n const catalog = usePortalProductCatalog({ perPage: pageSize });\n const {\n data,\n isLoading,\n isFetchingNextPage,\n hasNextPage,\n fetchNextPage,\n error,\n isFetched,\n } = useInfiniteQuery({\n queryKey: catalog.queryKey,\n queryFn: ({ pageParam, signal }) =>\n catalog.fetchProducts(pageParam, signal),\n getNextPageParam: catalog.getNextPageParam,\n initialPageParam: undefined as PortalProductPageParam,\n });\n\n const allProducts = useMemo(\n () => data?.pages.flatMap((page) => page.products) ?? [],\n [data?.pages],\n );\n\n // Hard cap so pageSize doubles as a \"show at most N\" limit.\n const visibleProducts = useMemo(\n () => allProducts.slice(0, pageSize),\n [allProducts, pageSize],\n );\n const reachedLimit = visibleProducts.length >= pageSize;\n\n const handleIntersect = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n if (\n entries[0]?.isIntersecting &&\n hasNextPage &&\n !isFetchingNextPage &&\n !reachedLimit\n ) {\n fetchNextPage();\n }\n },\n [hasNextPage, isFetchingNextPage, fetchNextPage, reachedLimit],\n );\n\n useEffect(() => {\n const target = observerTarget.current;\n if (!target) return;\n const observer = new IntersectionObserver(handleIntersect, {\n threshold: 0.1,\n rootMargin: \"200px\",\n });\n observer.observe(target);\n return () => observer.disconnect();\n }, [handleIntersect]);\n\n const handleSelect = useCallback(\n (id: string | number) => {\n onNavigate?.(`shop/${id}`);\n },\n [onNavigate],\n );\n\n const hasTitle = titleEnabled && !!title;\n const hasHeader = hasTitle || showSearch || showSort;\n\n return (\n <div>\n {hasHeader && (\n <div className=\"mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2\">\n {hasTitle && (\n <h2\n className={`text-${titleColor} text-2xl font-semibold tracking-tight`}\n >\n {title}\n </h2>\n )}\n {(showSearch || showSort) && (\n <div className=\"flex items-center gap-2 sm:ml-auto\">\n {showSearch && (\n <div className=\"w-full max-w-sm sm:w-64\">\n <SearchSort\n searchValue={catalog.searchTerm}\n onSearchChange={catalog.setSearchTerm}\n placeholder=\"Search products\"\n />\n </div>\n )}\n {showSort && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"border-foreground/10 size-9 shrink-0\"\n >\n <ArrowUpDown className=\"size-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n <DropdownMenuLabel>Sort by</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup\n value={catalog.currentSort}\n onValueChange={catalog.setCurrentSort}\n >\n {SORT_OPTIONS.map((opt) => (\n <DropdownMenuRadioItem key={opt.id} value={opt.id}>\n {opt.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n )}\n </div>\n )}\n\n {isLoading ? (\n <SkeletonGrid columns={columns} count={columns * 2} />\n ) : error && visibleProducts.length === 0 ? (\n <div className=\"bg-destructive/10 text-destructive my-6 rounded-lg px-4 py-3 text-sm\">\n Couldn’t load products. Try again later.\n </div>\n ) : isFetched && visibleProducts.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <p className=\"text-muted-foreground text-sm\">\n {catalog.searchTerm\n ? `No products match “${catalog.searchTerm}”.`\n : \"No products yet.\"}\n </p>\n </div>\n ) : (\n <>\n <div\n className={GRID_BY_COLUMNS[columns]}\n style={cardScopedStyle(cardBackground, cardTextColor)}\n >\n {visibleProducts.map((product) => {\n if (product.id == null) return null;\n const productId = product.id;\n return (\n <ProductCard\n key={productId}\n product={tagPortalProduct(product)}\n onClick={() => handleSelect(productId)}\n />\n );\n })}\n </div>\n {!reachedLimit && <div ref={observerTarget} />}\n {isFetchingNextPage && !reachedLimit && (\n <div className=\"mt-6\">\n <SkeletonGrid columns={columns} count={columns} />\n </div>\n )}\n {error && (\n <div className=\"bg-destructive/10 text-destructive mt-6 rounded-lg px-4 py-3 text-sm\">\n Couldn’t load more products. Try again later.\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction ProductCardCompact({\n name,\n imageUrl,\n price,\n onClick,\n}: {\n name: string;\n imageUrl: string | null;\n price: string | null;\n onClick?: () => void;\n}) {\n const interactive = !!onClick;\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={!interactive}\n className={`bg-card text-card-foreground group flex flex-col overflow-hidden rounded-lg border border-transparent text-left ${interactive ? \"hover:border-border cursor-pointer transition-shadow hover:shadow-md\" : \"cursor-default\"} focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none`}\n >\n <div className=\"bg-muted relative aspect-square w-full overflow-hidden\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={name}\n className=\"h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]\"\n loading=\"lazy\"\n />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center\">\n <ImageIcon className=\"text-muted-foreground/40 size-10\" />\n </div>\n )}\n </div>\n <div className=\"p-3\">\n <h3 className=\"text-foreground line-clamp-2 text-sm font-medium\">\n {name}\n </h3>\n {price && (\n <p className=\"text-foreground mt-1 text-sm font-semibold\">{price}</p>\n )}\n </div>\n </button>\n );\n}\n\nfunction SkeletonGrid({\n columns,\n count,\n}: {\n columns: ColumnsKey;\n count: number;\n}) {\n return (\n <div className={GRID_BY_COLUMNS[columns]}>\n {Array.from({ length: count }, (_, i) => (\n <div key={i} className=\"space-y-3\">\n <Skeleton className=\"aspect-square w-full rounded-lg\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/3\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport const shopWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShopWidget\",\n displayName: \"Shop\",\n tabsConfig: [\n { id: \"styling\", label: \"Styling\" },\n { id: \"data\", label: \"Data\" },\n ],\n dataSourceTargetProps: [\"products\"],\n fields: [\n // Title group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the heading shown above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"title\",\n label: \"Title\",\n type: \"text\",\n description: \"Heading text shown above the grid\",\n defaultValue: \"\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color of the heading text\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Display group\n {\n key: \"showSearch\",\n label: \"Show Search\",\n type: \"boolean\",\n description: \"Display the search input above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"showSort\",\n label: \"Show Sort\",\n type: \"boolean\",\n description: \"Display the sort menu above the grid\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"columns\",\n label: \"Columns (desktop)\",\n type: \"select\",\n description:\n \"Max columns at the largest breakpoint. Mobile is always 2 columns; intermediate sizes scale smoothly between.\",\n options: [\n { label: \"2\", value: 2 },\n { label: \"3\", value: 3 },\n { label: \"4\", value: 4 },\n { label: \"5\", value: 5 },\n { label: \"6\", value: 6 },\n ],\n defaultValue: 4,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Container background\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Inner spacing around the grid\",\n defaultValue: 6,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Container corner radius\",\n defaultValue: \"lg\",\n tab: \"styling\",\n group: \"Design\",\n }),\n\n // Card group — optional theme overrides; unset means \"inherit from theme\".\n getColorField({\n key: \"cardBackground\",\n label: \"Card Background\",\n description:\n \"Override the card background color. Leave unset to use the theme's card color.\",\n tab: \"styling\",\n group: \"Card\",\n }),\n getColorField({\n key: \"cardTextColor\",\n label: \"Card Text\",\n description:\n \"Override title + price color inside each card. Leave unset to use the theme's foreground color.\",\n tab: \"styling\",\n group: \"Card\",\n }),\n\n // Data tab\n {\n key: \"useDataSource\",\n label: \"Use Data Source\",\n type: \"boolean\",\n description:\n \"Off shows all products from the catalog. On replaces the catalog with a data source — disables search and sort.\",\n defaultValue: false,\n tab: \"data\",\n group: \"Data Configuration\",\n },\n {\n key: \"pageSize\",\n label: \"Products to show\",\n type: \"number\",\n description: \"Maximum number of products rendered in the grid\",\n defaultValue: 25,\n min: 5,\n max: 100,\n step: 5,\n tab: \"data\",\n group: \"Data Configuration\",\n requiresKeyValue: { key: \"useDataSource\", value: false },\n },\n {\n key: \"dataSource\",\n label: \"Data Source\",\n type: \"dataSource\",\n description: \"\",\n tab: \"data\",\n group: \"Data Configuration\",\n requiresKeyToBeTrue: \"useDataSource\",\n },\n ],\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { vt as __exportAll } from "./PortalTenantClientProvider-
|
|
1
|
+
import { vt as __exportAll } from "./PortalTenantClientProvider-DVClpfbi.mjs";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ArrowUpDown } from "lucide-react";
|
|
4
4
|
//#region ../widgets/src/widgets/SpacerWidget.tsx
|
|
@@ -56,4 +56,4 @@ const spacerWidgetPropertySchema = {
|
|
|
56
56
|
//#endregion
|
|
57
57
|
export { SpacerWidget_exports as n, spacerWidgetPropertySchema as r, SpacerWidget as t };
|
|
58
58
|
|
|
59
|
-
//# sourceMappingURL=SpacerWidget-
|
|
59
|
+
//# sourceMappingURL=SpacerWidget-BhxIaqYF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpacerWidget-
|
|
1
|
+
{"version":3,"file":"SpacerWidget-BhxIaqYF.mjs","names":[],"sources":["../../widgets/src/widgets/SpacerWidget.tsx"],"sourcesContent":["import { type WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { ArrowUpDown } from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport type React from \"react\";\n\ntype SpacerWidgetProps = ComponentProps<\"div\"> & {\n /**\n * Custom height as a CSS value (e.g., \"128px\", \"8rem\", \"20vh\")\n */\n customHeight?: string;\n /**\n * Not customizable, determines if we should show a preview image in the container\n */\n previewMode?: boolean;\n};\n\nexport function SpacerWidget({\n customHeight = \"128px\",\n previewMode = false,\n className,\n style,\n ...props\n}: SpacerWidgetProps): React.JSX.Element {\n return (\n <div\n className={`w-full ${className ?? \"\"}`}\n style={{ height: customHeight, ...style }}\n aria-hidden=\"true\"\n {...props}\n >\n {previewMode && (\n <div className=\"border-muted/40 bg-muted text-muted-foreground flex h-full w-full items-center justify-center gap-1 border border-dashed\">\n <ArrowUpDown />\n <span>SPACER</span>\n </div>\n )}\n </div>\n );\n}\n\nexport const spacerWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"SpacerWidget\",\n displayName: \"Spacer\",\n fields: [\n {\n key: \"customHeight\",\n label: \"Height\",\n type: \"cssUnit\",\n description: \"Height of the spacer\",\n defaultValue: \"128px\",\n allowedUnits: [\"px\", \"vh\", \"rem\"],\n minByUnit: { px: 1, vh: 1, rem: 0.25 },\n maxByUnit: { px: 2000, vh: 100, rem: 125 },\n stepByUnit: { px: 1, vh: 1, rem: 0.25 },\n group: \"Spacing\",\n },\n ],\n};\n"],"mappings":";;;;;;;;AAgBA,SAAgB,aAAa,EAC3B,eAAe,SACf,cAAc,OACd,WACA,OACA,GAAG,SACoC;AACvC,QACE,oBAAC,OAAD;EACE,WAAW,UAAU,aAAa;EAClC,OAAO;GAAE,QAAQ;GAAc,GAAG;GAAO;EACzC,eAAY;EACZ,GAAI;YAEH,eACC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,aAAD,EAAe,CAAA,EACf,oBAAC,QAAD,EAAA,UAAM,UAAa,CAAA,CACf;;EAEJ,CAAA;;AAIV,MAAa,6BAAmD;CAC9D,YAAY;CACZ,aAAa;CACb,QAAQ,CACN;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,aAAa;EACb,cAAc;EACd,cAAc;GAAC;GAAM;GAAM;GAAM;EACjC,WAAW;GAAE,IAAI;GAAG,IAAI;GAAG,KAAK;GAAM;EACtC,WAAW;GAAE,IAAI;GAAM,IAAI;GAAK,KAAK;GAAK;EAC1C,YAAY;GAAE,IAAI;GAAG,IAAI;GAAG,KAAK;GAAM;EACvC,OAAO;EACR,CACF;CACF"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { at as subscriptions_list, ct as subscriptions_resume, dt as subscriptions_skip, ft as subscriptions_update, it as subscriptions_cancel, lt as subscriptions_retry, n as usePortalTenantClient, nt as subscription_bundles_create, ot as subscriptions_pause, rt as subscription_bundles_list, st as subscriptions_reactivate, ut as subscriptions_show } from "./PortalTenantClientProvider-
|
|
2
|
-
import {
|
|
3
|
-
import { n as useCountriesApi } from "./countries-api-context-
|
|
4
|
-
import { a as useActiveLocale, n as createDomainTranslations, r as useDomainDict, t as createStaticDictAdapter } from "./static-dict-adapter-
|
|
5
|
-
import { t as createTranslationContext } from "./translation-api-context-factory-
|
|
1
|
+
import { at as subscriptions_list, ct as subscriptions_resume, dt as subscriptions_skip, ft as subscriptions_update, it as subscriptions_cancel, lt as subscriptions_retry, n as usePortalTenantClient, nt as subscription_bundles_create, ot as subscriptions_pause, rt as subscription_bundles_list, st as subscriptions_reactivate, ut as subscriptions_show } from "./PortalTenantClientProvider-DVClpfbi.mjs";
|
|
2
|
+
import { H as usePayApi, R as isApiError, n as useFluidContext } from "./FluidProvider-tPt9UpYz.mjs";
|
|
3
|
+
import { n as useCountriesApi } from "./countries-api-context-Donus2X5.mjs";
|
|
4
|
+
import { a as useActiveLocale, n as createDomainTranslations, r as useDomainDict, t as createStaticDictAdapter } from "./static-dict-adapter-DRBq3ndO.mjs";
|
|
5
|
+
import { t as createTranslationContext } from "./translation-api-context-factory-DFr9yJ6Q.mjs";
|
|
6
6
|
import { $t as startOfISOWeek, At as Calendar$1, Bt as getWeek, C as SelectContent, Cn as AlertDialogTitle, Dn as PortalContainerProvider, E as SelectValue, Ft as format, Ht as getISOWeek, It as isProtectedDayOfYearToken, Jt as addWeeks, Lt as isProtectedWeekYearToken, Pt as isAfter, Q as DialogContent, Qt as getTimezoneOffsetInMilliseconds, R as Label, Rt as warnOrThrowProtectedError, S as Select, Sn as AlertDialogHeader, T as SelectTrigger, Ut as enUS, Vt as getWeekYear, X as Dialog, _ as SheetContent, an as constructFrom, at as Popover, b as SheetTitle, bn as AlertDialogDescription, cn as millisecondsInSecond, ct as PopoverTrigger, dn as BreadcrumbLink, en as startOfWeek, et as DialogFooter, f as fluidToast, fn as BreadcrumbList, g as Sheet, gn as AlertDialog, h as Skeleton, in as toDate, it as DialogTitle, k as Input, kn as cn$1, ln as Breadcrumb, mn as BreadcrumbSeparator, nn as addMonths, on as millisecondsInHour, pn as BreadcrumbPage, qt as addYears, rn as addDays, sn as millisecondsInMinute, st as PopoverContent, tn as getDefaultOptions$1, tt as DialogHeader, un as BreadcrumbItem, vn as AlertDialogCancel, w as SelectItem, wn as Button, xn as AlertDialogFooter, yn as AlertDialogContent, zt as longFormatters } from "./src-CJw6JbdS.mjs";
|
|
7
|
-
import { n as ScreenHeaderBreadcrumbs } from "./ScreenHeaderContext-
|
|
8
|
-
import { t as useStore } from "./use-store-
|
|
7
|
+
import { n as ScreenHeaderBreadcrumbs } from "./ScreenHeaderContext-cuVMk00X.mjs";
|
|
8
|
+
import { t as useStore } from "./use-store-C6KYHvRw.mjs";
|
|
9
9
|
import { n as payKeys, r as storeKeys } from "./query-keys-xJy_fapN.mjs";
|
|
10
|
-
import { t as useAccount } from "./use-account-
|
|
11
|
-
import { n as useAppNavigation } from "./AppNavigationContext-
|
|
12
|
-
import { a as AddressFormDialog, c as PaymentIcon, f as ConfirmActionDialog, h as useProfileTranslation, i as CreditCardFormDialog, l as getCardDisplayName, m as ProfileTranslationBridge, n as createFluidPayApiAdapter, o as EditPaymentMethodDialog, p as EllipsesDropdown, r as mapToFluidPayPaymentMethod, s as FluidPayCoreProvider, t as AddressAutocompleteInput, u as getCardExpiry } from "./AddressAutocompleteInput-
|
|
13
|
-
import { createContext,
|
|
10
|
+
import { t as useAccount } from "./use-account-Dm6Svko1.mjs";
|
|
11
|
+
import { n as useAppNavigation } from "./AppNavigationContext-B-wToUBG.mjs";
|
|
12
|
+
import { a as AddressFormDialog, c as PaymentIcon, f as ConfirmActionDialog, h as useProfileTranslation, i as CreditCardFormDialog, l as getCardDisplayName, m as ProfileTranslationBridge, n as createFluidPayApiAdapter, o as EditPaymentMethodDialog, p as EllipsesDropdown, r as mapToFluidPayPaymentMethod, s as FluidPayCoreProvider, t as AddressAutocompleteInput, u as getCardExpiry } from "./AddressAutocompleteInput-Dds2GjGt.mjs";
|
|
13
|
+
import { createContext, use, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
14
14
|
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
15
15
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
import { AlertCircle, BadgeAlert, Banknote, Calendar, CalendarClock, CalendarDays, CalendarIcon, Check, ChevronDown, ChevronLeft, ChevronRight, CircleDollarSign, CreditCard, DollarSign, ImageOff, Minus, Package, Pause, PiggyBank, Play, Plus, Receipt, RefreshCw, Repeat, RotateCcw, ShieldCheck, SkipForward, Sparkles, Truck, Wallet, X, XCircle } from "lucide-react";
|
|
@@ -2079,7 +2079,7 @@ function cleanEscapedString(input) {
|
|
|
2079
2079
|
const SubscriptionsApiContext = createContext(null);
|
|
2080
2080
|
const SubscriptionsApiProvider = SubscriptionsApiContext.Provider;
|
|
2081
2081
|
function useSubscriptionsApi() {
|
|
2082
|
-
const api =
|
|
2082
|
+
const api = use(SubscriptionsApiContext);
|
|
2083
2083
|
if (!api) throw new Error("useSubscriptionsApi must be used within a SubscriptionsCoreProvider");
|
|
2084
2084
|
return api;
|
|
2085
2085
|
}
|
|
@@ -2115,7 +2115,7 @@ const bundlesKeys = {
|
|
|
2115
2115
|
const BundlesApiContext = createContext(null);
|
|
2116
2116
|
const BundlesApiProvider = BundlesApiContext.Provider;
|
|
2117
2117
|
function useBundlesApi() {
|
|
2118
|
-
const api =
|
|
2118
|
+
const api = use(BundlesApiContext);
|
|
2119
2119
|
if (!api) throw new Error("useBundlesApi must be used within a BundlesCoreProvider");
|
|
2120
2120
|
return api;
|
|
2121
2121
|
}
|
|
@@ -4571,6 +4571,7 @@ function SubscriptionsListScreenInner({ customerId, isLoadingCustomer, onToast }
|
|
|
4571
4571
|
const { t } = useSubscriptionsTranslation();
|
|
4572
4572
|
const { t: profileT } = useProfileTranslation();
|
|
4573
4573
|
const { config } = useFluidContext();
|
|
4574
|
+
const { locale } = useActiveLocale();
|
|
4574
4575
|
const { data: store } = useStore();
|
|
4575
4576
|
const bundlingEnabled = !!store?.bundle_subscriptions_enabled;
|
|
4576
4577
|
const { data: addresses = [] } = useQuery({
|
|
@@ -4729,6 +4730,7 @@ function SubscriptionsListScreenInner({ customerId, isLoadingCustomer, onToast }
|
|
|
4729
4730
|
}),
|
|
4730
4731
|
selectedAddress: addressDialog.selected,
|
|
4731
4732
|
defaultCountry: addresses.find((a) => a.default)?.country_code ?? config.countryIso ?? "US",
|
|
4733
|
+
languageIso: locale,
|
|
4732
4734
|
t: addressDialogT,
|
|
4733
4735
|
onSubmit: async (formData) => {
|
|
4734
4736
|
try {
|
|
@@ -4772,6 +4774,7 @@ function SubscriptionsListScreenInner({ customerId, isLoadingCustomer, onToast }
|
|
|
4772
4774
|
onClose,
|
|
4773
4775
|
selectedAddress: null,
|
|
4774
4776
|
defaultCountry: addresses.find((a) => a.default)?.country_code ?? config.countryIso ?? "US",
|
|
4777
|
+
languageIso: locale,
|
|
4775
4778
|
t: addressDialogT,
|
|
4776
4779
|
onSubmit: async (formData) => {
|
|
4777
4780
|
try {
|
|
@@ -4971,7 +4974,7 @@ function PauseSubscriptionDialog({ open, onOpenChange, onConfirm, isLoading, err
|
|
|
4971
4974
|
className: "space-y-4",
|
|
4972
4975
|
children: [
|
|
4973
4976
|
/* @__PURE__ */ jsxs("div", {
|
|
4974
|
-
className: "flex items-center
|
|
4977
|
+
className: "flex items-center gap-x-2",
|
|
4975
4978
|
children: [/* @__PURE__ */ jsx("input", {
|
|
4976
4979
|
id: "pause-indefinitely",
|
|
4977
4980
|
type: "radio",
|
|
@@ -4987,7 +4990,7 @@ function PauseSubscriptionDialog({ open, onOpenChange, onConfirm, isLoading, err
|
|
|
4987
4990
|
/* @__PURE__ */ jsxs("div", {
|
|
4988
4991
|
className: "space-y-2",
|
|
4989
4992
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
4990
|
-
className: "flex items-center
|
|
4993
|
+
className: "flex items-center gap-x-2",
|
|
4991
4994
|
children: [/* @__PURE__ */ jsx("input", {
|
|
4992
4995
|
id: "pause-order-count",
|
|
4993
4996
|
type: "radio",
|
|
@@ -5031,7 +5034,7 @@ function PauseSubscriptionDialog({ open, onOpenChange, onConfirm, isLoading, err
|
|
|
5031
5034
|
children: errorMessage
|
|
5032
5035
|
}),
|
|
5033
5036
|
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs("div", {
|
|
5034
|
-
className: "flex w-full flex-row justify-between
|
|
5037
|
+
className: "flex w-full flex-row justify-between gap-x-2",
|
|
5035
5038
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
5036
5039
|
variant: "outline",
|
|
5037
5040
|
className: "h-10 min-w-[70px] rounded p-3",
|
|
@@ -5164,7 +5167,7 @@ function ResumeSubscriptionDialog({ open, onOpenChange, onConfirm, isLoading, er
|
|
|
5164
5167
|
children: errorMessage
|
|
5165
5168
|
}),
|
|
5166
5169
|
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs("div", {
|
|
5167
|
-
className: "flex w-full flex-row justify-between
|
|
5170
|
+
className: "flex w-full flex-row justify-between gap-x-2",
|
|
5168
5171
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
5169
5172
|
className: "bg-muted text-foreground ring-border hover:bg-muted/80 h-10 min-w-[70px] rounded p-3 ring-1",
|
|
5170
5173
|
onClick: () => handleDismiss(false),
|
|
@@ -5422,7 +5425,7 @@ function EditBillDateDialog({ open, onOpenChange, onConfirm, isLoading, errorMes
|
|
|
5422
5425
|
children: errorMessage
|
|
5423
5426
|
}),
|
|
5424
5427
|
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs("div", {
|
|
5425
|
-
className: "flex w-full flex-row justify-between
|
|
5428
|
+
className: "flex w-full flex-row justify-between gap-x-2",
|
|
5426
5429
|
children: [/* @__PURE__ */ jsx(Button, {
|
|
5427
5430
|
variant: "outline",
|
|
5428
5431
|
className: "h-10 min-w-[70px] rounded p-3",
|
|
@@ -5624,7 +5627,7 @@ function SubscriptionDetailSkeleton() {
|
|
|
5624
5627
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full rounded" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full rounded" })]
|
|
5625
5628
|
}),
|
|
5626
5629
|
/* @__PURE__ */ jsxs("div", {
|
|
5627
|
-
className: "mt-6 flex items-center
|
|
5630
|
+
className: "mt-6 flex items-center gap-x-4",
|
|
5628
5631
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "size-24 rounded" }), /* @__PURE__ */ jsxs("div", {
|
|
5629
5632
|
className: "flex-1 space-y-2",
|
|
5630
5633
|
children: [
|
|
@@ -5836,9 +5839,9 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
|
|
|
5836
5839
|
/* @__PURE__ */ jsx("div", {
|
|
5837
5840
|
className: "py-6",
|
|
5838
5841
|
children: /* @__PURE__ */ jsxs("div", {
|
|
5839
|
-
className: "flex flex-row items-center
|
|
5842
|
+
className: "flex flex-row items-center gap-x-4",
|
|
5840
5843
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
5841
|
-
className: "flex min-w-0 flex-1 flex-row
|
|
5844
|
+
className: "flex min-w-0 flex-1 flex-row gap-x-4",
|
|
5842
5845
|
children: [/* @__PURE__ */ jsx("div", {
|
|
5843
5846
|
className: "relative shrink-0",
|
|
5844
5847
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -5858,7 +5861,7 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
|
|
|
5858
5861
|
})]
|
|
5859
5862
|
})
|
|
5860
5863
|
}), /* @__PURE__ */ jsxs("div", {
|
|
5861
|
-
className: "flex min-w-0 flex-col
|
|
5864
|
+
className: "flex min-w-0 flex-col gap-y-0.5",
|
|
5862
5865
|
children: [
|
|
5863
5866
|
/* @__PURE__ */ jsx("p", {
|
|
5864
5867
|
className: "text-foreground truncate text-sm font-medium",
|
|
@@ -6563,11 +6566,11 @@ function SelectablePaymentMethodDropdown({ title, displayPaymentMethod, paymentM
|
|
|
6563
6566
|
id: sectionId,
|
|
6564
6567
|
role: "listbox",
|
|
6565
6568
|
"aria-label": title,
|
|
6566
|
-
className: "mt-5 flex max-h-[400px] flex-col
|
|
6569
|
+
className: "mt-5 flex max-h-[400px] flex-col gap-y-4 overflow-y-auto pr-0.5",
|
|
6567
6570
|
children: isLoading ? /* @__PURE__ */ jsx(Fragment$1, { children: [1, 2].map((i) => /* @__PURE__ */ jsxs("div", {
|
|
6568
|
-
className: "bg-muted flex flex-row items-center
|
|
6571
|
+
className: "bg-muted flex flex-row items-center gap-x-2 rounded-sm p-3",
|
|
6569
6572
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-10" }), /* @__PURE__ */ jsxs("div", {
|
|
6570
|
-
className: "flex flex-col
|
|
6573
|
+
className: "flex flex-col gap-y-1",
|
|
6571
6574
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-32" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })]
|
|
6572
6575
|
})]
|
|
6573
6576
|
}, `skeleton-${i}`)) }) : paymentMethodList.map((paymentMethod) => {
|
|
@@ -6974,7 +6977,7 @@ function SelectableAddressDropdown({ title, displayAddress, addressList, selecte
|
|
|
6974
6977
|
id: sectionId,
|
|
6975
6978
|
role: "listbox",
|
|
6976
6979
|
"aria-label": title,
|
|
6977
|
-
className: "mt-5 flex max-h-[400px] flex-col
|
|
6980
|
+
className: "mt-5 flex max-h-[400px] flex-col gap-y-4 overflow-y-auto pr-0.5",
|
|
6978
6981
|
children: isLoading ? /* @__PURE__ */ jsx(Fragment$1, { children: [1, 2].map((i) => /* @__PURE__ */ jsxs("div", {
|
|
6979
6982
|
className: "bg-muted rounded-sm p-3",
|
|
6980
6983
|
children: [
|
|
@@ -7087,6 +7090,7 @@ function PortalSubscriptionShippingAddressSectionInner({ address: currentAddress
|
|
|
7087
7090
|
const { t: profileT } = useProfileTranslation();
|
|
7088
7091
|
const { t: subsT } = useSubscriptionsTranslation();
|
|
7089
7092
|
const { config } = useFluidContext();
|
|
7093
|
+
const { locale } = useActiveLocale();
|
|
7090
7094
|
const tFn = useCallback((key) => profileT(key), [profileT]);
|
|
7091
7095
|
const payApi = usePayApi();
|
|
7092
7096
|
const queryClient = useQueryClient();
|
|
@@ -7246,6 +7250,7 @@ function PortalSubscriptionShippingAddressSectionInner({ address: currentAddress
|
|
|
7246
7250
|
onClose: handleCloseFormDialog,
|
|
7247
7251
|
selectedAddress: editingAddress,
|
|
7248
7252
|
defaultCountry: addresses.find((a) => a.default)?.country_code ?? currentAddress?.country_code ?? config.countryIso ?? "US",
|
|
7253
|
+
languageIso: locale,
|
|
7249
7254
|
t: tFn,
|
|
7250
7255
|
onSubmit: async (data) => {
|
|
7251
7256
|
try {
|
|
@@ -7375,4 +7380,4 @@ const subscriptionsScreenPropertySchema = {
|
|
|
7375
7380
|
//#endregion
|
|
7376
7381
|
export { subscriptionsScreenPropertySchema as n, SubscriptionsScreen as t };
|
|
7377
7382
|
|
|
7378
|
-
//# sourceMappingURL=SubscriptionsScreen-
|
|
7383
|
+
//# sourceMappingURL=SubscriptionsScreen-Br_gugTG.mjs.map
|