@wix/agent-skills 1.20.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +71 -113
  3. package/skills/wix-app/references/APP_TOOLS.md +2 -1
  4. package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  8. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  9. package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
  10. package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
  11. package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
  12. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
  13. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  14. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  15. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  16. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  17. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  18. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
  19. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  20. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  21. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  22. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
  23. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  24. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  25. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  26. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  27. package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
  28. package/skills/wix-headless-fast/SKILL.md +144 -221
  29. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  30. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
  31. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  32. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  33. package/skills/wix-headless-fast/install/AGENTS.md +35 -0
  34. package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
  35. package/skills/wix-headless-fast/install/attach.mjs +161 -86
  36. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  37. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  38. package/skills/wix-headless-fast/install/setup.mjs +259 -0
  39. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  40. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
  41. package/skills/wix-manage/references/events/create-wix-event.md +5 -1
  42. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  43. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  44. package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
  45. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
  46. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  47. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  48. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  49. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  50. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  51. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  52. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  53. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  54. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  55. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  56. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  57. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  58. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  59. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  60. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  61. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  62. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  63. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  64. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  65. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  66. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
  67. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  68. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  69. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  70. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  71. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  72. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  73. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  74. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  75. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  76. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  77. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  78. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  79. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  80. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  81. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  82. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  83. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  84. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  85. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  86. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
  87. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  88. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  89. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  90. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  91. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  92. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  93. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  94. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  95. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  96. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  97. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  98. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  99. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
  100. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  103. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  105. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  107. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  108. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  109. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  110. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  111. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  112. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  113. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  114. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  115. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  116. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  117. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  118. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  119. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  120. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  121. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
  122. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  123. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  124. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  125. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  126. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  127. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  128. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  129. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  130. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  131. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  132. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  133. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  134. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
  135. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  136. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  137. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  138. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  139. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  140. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  141. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  142. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  143. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  144. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  145. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  146. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  147. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  148. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  149. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  150. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  151. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  152. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  153. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  154. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  155. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
  156. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  157. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  158. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  159. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  160. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  161. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  162. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  163. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  164. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  165. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  166. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  167. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  168. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  169. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  170. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  171. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  172. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  173. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  174. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  175. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  176. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
  177. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
  178. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  179. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  180. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  181. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  182. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  183. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  184. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  185. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  186. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  187. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  188. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  189. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  190. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  191. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  192. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  193. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  194. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  195. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  196. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  197. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  198. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
  199. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  200. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  201. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  202. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  203. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  204. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  205. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  209. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  210. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  211. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  212. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  213. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  214. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  215. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  216. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  217. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  218. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  219. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  220. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  221. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  222. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  223. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  224. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
  225. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  226. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  227. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  228. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  229. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  230. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  231. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  232. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  233. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  234. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  235. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  236. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  237. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  238. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  239. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  240. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
  241. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  242. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  243. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  244. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  245. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  246. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  247. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  248. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  252. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
  253. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  254. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  255. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  256. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
  257. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  258. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  259. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  260. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  261. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
  262. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
@@ -1,118 +0,0 @@
1
- // REFERENCE listing surface: category filter + events grid on the @theme tokens.
2
- // Correct and complete; per the skill's model you design and build your own on useEvents.
3
- import type { ComponentType, ReactNode } from "react";
4
- import { useEvents } from "../../hooks/events/useEvents";
5
- import { imgAttrs } from "../../wix/media";
6
- import type { EventSummary } from "../../wix/events/types";
7
-
8
- export interface LinkLikeProps {
9
- href: string;
10
- className?: string;
11
- children?: ReactNode;
12
- }
13
-
14
- const PlainLink = ({ href, className, children }: LinkLikeProps) => (
15
- <a href={href} className={className}>
16
- {children}
17
- </a>
18
- );
19
-
20
- export interface EventCardProps {
21
- event: EventSummary;
22
- eventHref?: (slug: string) => string;
23
- LinkComponent?: ComponentType<LinkLikeProps>;
24
- }
25
-
26
- export function EventCard({
27
- event,
28
- eventHref = (slug) => `/events/${slug}`,
29
- LinkComponent = PlainLink,
30
- }: EventCardProps) {
31
- return (
32
- <LinkComponent href={eventHref(event.slug)} className="group block no-underline">
33
- <div className="relative aspect-[3/2] overflow-hidden rounded-lg bg-secondary">
34
- {event.imageUrl && (
35
- <img
36
- {...imgAttrs(event.imageUrl, "(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw", 2 / 3)}
37
- alt={event.title}
38
- className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]"
39
- />
40
- )}
41
- {event.soldOut && (
42
- <span className="absolute left-3 top-3 rounded-full bg-background/90 px-3 py-1 text-xs font-semibold text-foreground backdrop-blur">
43
- Sold out
44
- </span>
45
- )}
46
- </div>
47
- {event.dateLabel && <p className="eyebrow mt-3">{event.dateLabel}</p>}
48
- <p className="mt-1 text-sm font-medium text-foreground">{event.title}</p>
49
- <p className="mt-0.5 text-xs text-muted-foreground">
50
- {event.locationType === "ONLINE" ? "Online" : event.locationName}
51
- {event.priceLabel ? ` · ${event.priceLabel}` : ""}
52
- </p>
53
- </LinkComponent>
54
- );
55
- }
56
-
57
- export interface EventsViewProps {
58
- initialEvents?: EventSummary[];
59
- emptyMessage?: string;
60
- eventHref?: EventCardProps["eventHref"];
61
- LinkComponent?: ComponentType<LinkLikeProps>;
62
- CardComponent?: ComponentType<EventCardProps>;
63
- }
64
-
65
- const pill = (active: boolean) =>
66
- `rounded-full border px-4 py-1.5 text-sm font-medium transition-colors ${
67
- active
68
- ? "border-primary bg-primary text-primary-foreground"
69
- : "border-border text-foreground hover:bg-secondary"
70
- }`;
71
-
72
- export default function EventsView({
73
- initialEvents,
74
- emptyMessage = "No upcoming events — check back soon.",
75
- eventHref,
76
- LinkComponent,
77
- CardComponent = EventCard,
78
- }: EventsViewProps) {
79
- const { events, categories, activeCategoryId, setActiveCategoryId, error } = useEvents({
80
- initialEvents,
81
- });
82
-
83
- return (
84
- <div>
85
- {categories.length > 1 && (
86
- <div className="mb-8 flex flex-wrap gap-2" role="group" aria-label="Categories">
87
- <button type="button" className={pill(activeCategoryId === null)} onClick={() => setActiveCategoryId(null)}>
88
- All
89
- </button>
90
- {categories.map((c) => (
91
- <button key={c.id} type="button" className={pill(activeCategoryId === c.id)} onClick={() => setActiveCategoryId(c.id)}>
92
- {c.name}
93
- </button>
94
- ))}
95
- </div>
96
- )}
97
- {error && <p className="mb-4 text-sm text-red-600">{error}</p>}
98
- {events === null ? (
99
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3" aria-busy="true">
100
- {Array.from({ length: 6 }, (_, i) => (
101
- <div key={i}>
102
- <div className="aspect-[3/2] animate-pulse rounded-lg bg-secondary" />
103
- <div className="mt-3 h-3.5 w-2/3 animate-pulse rounded bg-secondary" />
104
- </div>
105
- ))}
106
- </div>
107
- ) : events.length === 0 ? (
108
- <p className="py-16 text-center text-muted-foreground">{emptyMessage}</p>
109
- ) : (
110
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
111
- {events.map((e) => (
112
- <CardComponent key={e.id} event={e} eventHref={eventHref} LinkComponent={LinkComponent} />
113
- ))}
114
- </div>
115
- )}
116
- </div>
117
- );
118
- }
@@ -1,35 +0,0 @@
1
- // React binding of the registration store (wix/events/registration-store.ts) — the whole
2
- // registration state machine for one event lives there, framework-free, branched on
3
- // event.registrationType: TICKETING loads the tier picker and checkout() reserves → redirects to
4
- // Wix's hosted checkout; RSVP is the built-in name+email form submitted in place. All correctness
5
- // (the visitor-public tier read, the reservation payload, the redirect callbacks, rsvpV2) lives
6
- // in the data layer; you own how it looks. One store per event — a new event id gets a fresh one.
7
- import { useEffect, useRef, useSyncExternalStore } from "react";
8
- import {
9
- createRegistrationStore,
10
- type RegistrationState,
11
- type RegistrationStore,
12
- } from "../../wix/events/registration-store";
13
- import type { EventDetail } from "../../wix/events/types";
14
-
15
- export type UseEventRegistration = RegistrationState &
16
- Pick<RegistrationStore, "setQuantity" | "setRsvpValue" | "checkout" | "rsvp">;
17
-
18
- export function useEventRegistration(event: EventDetail): UseEventRegistration {
19
- const key = `${event.id}:${event.registrationType}`;
20
- const ref = useRef<{ key: string; store: RegistrationStore } | null>(null);
21
- if (!ref.current || ref.current.key !== key) ref.current = { key, store: createRegistrationStore(event) };
22
- const store = ref.current.store;
23
- useEffect(() => {
24
- store.start();
25
- return () => store.stop();
26
- }, [store]);
27
- const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
28
- return {
29
- ...state,
30
- setQuantity: store.setQuantity,
31
- setRsvpValue: store.setRsvpValue,
32
- checkout: store.checkout,
33
- rsvp: store.rsvp,
34
- };
35
- }
@@ -1,24 +0,0 @@
1
- // React binding of the events store (wix/events/events-store.ts) — the listing state machine
2
- // lives there, framework-free; this hook subscribes to one instance per mounted listing and
3
- // exposes its state and actions under one name. SSR-friendly: pass server-fetched data as
4
- // `initialEvents` (Astro frontmatter / server component) and no client fetch happens; a SPA
5
- // passes nothing. Astro islands and React SPAs use this; a static page, Vue, or Svelte uses the
6
- // store directly.
7
- import { useEffect, useRef, useSyncExternalStore } from "react";
8
- import { createEventsStore, type EventsState, type EventsStore, type EventsStoreOptions } from "../../wix/events/events-store";
9
-
10
- export type UseEventsOptions = EventsStoreOptions;
11
-
12
- export type UseEvents = EventsState & Pick<EventsStore, "setActiveCategoryId">;
13
-
14
- export function useEvents(options: UseEventsOptions = {}): UseEvents {
15
- const ref = useRef<EventsStore | null>(null);
16
- if (!ref.current) ref.current = createEventsStore(options);
17
- const store = ref.current;
18
- useEffect(() => {
19
- store.start();
20
- return () => store.stop();
21
- }, [store]);
22
- const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
23
- return { ...state, setActiveCategoryId: store.setActiveCategoryId };
24
- }
@@ -1,130 +0,0 @@
1
- // Event rules and DTO mapping — transport-agnostic, imported by BOTH transports: ./events.ts (the
2
- // SDK, managed Astro and React) and the REST twin in references/events/rest/events.ts (fetch, a
3
- // static site or a port to another language). Every rule about statuses, fieldsets, prices,
4
- // dates, images and categories lives HERE, once. A raw event may come from the SDK (`_id`,
5
- // mainImage as a wix:image string) or from REST (`id`, mainImage as { id, url }); the mappers
6
- // accept both. Imports are type-only so a strip to JS emits no imports.
7
- import type { EventDetail, EventSummary, RegistrationType } from "./types";
8
-
9
- /** A raw Events V3 entity as either transport returns it. */
10
- export type Raw = Record<string, any>;
11
- /** Media value + size → https URL. Injected: the SDK transport scales through @wix/sdk, REST through the URL form. */
12
- export type ImgSrc = (value: any, width: number, height: number) => string;
13
-
14
- /** The Wix Events app id (reference only — frontend calls need no app-id constant). */
15
- export const EVENTS_APP_ID = "140603ad-af8d-84a5-2c80-a0f60cb47351";
16
-
17
- export const rawId = (raw: Raw | undefined | null): string => raw?._id ?? raw?.id ?? "";
18
-
19
- // Fieldsets are opt-in: without REGISTRATION there's no registration type to branch on;
20
- // without CATEGORIES the category names never arrive; DETAILS carries the formatted date
21
- // and mainImage; TEXTS carries the long description; URLS the Wix event page url.
22
- export const LIST_FIELDS = ["DETAILS", "REGISTRATION", "CATEGORIES"] as const;
23
- export const DETAIL_FIELDS = ["DETAILS", "TEXTS", "REGISTRATION", "URLS", "CATEGORIES"] as const;
24
-
25
- /** Only these are listed and linked — a past or canceled event isn't registerable. */
26
- export const LIVE_STATUSES = ["UPCOMING", "STARTED"] as const;
27
- export const START_DATE_FIELD = "dateAndTimeSettings.startDate";
28
-
29
- /**
30
- * The Query Events body for the listing: live statuses, soonest first, a positive limit.
31
- * `paging.limit` defaults to 0 — a bare query answers `total: 2, events: []` with no error — so
32
- * the limit is always sent. The SDK builder spells the same three parts.
33
- */
34
- export function listQuery({ limit = 100 } = {}): Raw {
35
- if (!Number.isInteger(limit) || limit < 1 || limit > 1000) throw new Error("limit must be between 1 and 1000.");
36
- return {
37
- filter: { status: { $in: [...LIVE_STATUSES] } },
38
- sort: [{ fieldName: START_DATE_FIELD, order: "ASC" }],
39
- paging: { limit },
40
- };
41
- }
42
-
43
- /** "From €45" (ticketed), "Free" (RSVP / free tickets), "" when nothing applies. */
44
- export function lowestPriceLabel(reg: Raw): string {
45
- const type = reg.type ?? reg.initialType;
46
- if (type === "RSVP") return "Free";
47
- if (type !== "TICKETING") return "";
48
- const lowest: Raw | undefined = reg.tickets?.lowestPrice;
49
- if (!lowest) return "";
50
- if (Number(lowest.value ?? 0) === 0) return "Free";
51
- if (lowest.formattedValue) return `From ${lowest.formattedValue}`;
52
- try {
53
- return `From ${new Intl.NumberFormat(undefined, { style: "currency", currency: lowest.currency || "USD" }).format(Number(lowest.value))}`;
54
- } catch {
55
- return `From ${lowest.value} ${lowest.currency ?? ""}`.trim();
56
- }
57
- }
58
-
59
- // event.description is Ricos rich content ({ nodes: [...] }), NOT a string — calling string
60
- // methods on it crashes the page. Extract plain paragraphs; detailedDescription (legacy plain
61
- // text) is the fallback.
62
- export function toParagraphs(rich: Raw | undefined | null, legacy: string | undefined): string[] {
63
- const collect = (nodes: Raw[] | undefined): string =>
64
- (nodes ?? [])
65
- .map((n: Raw) => (typeof n.textData?.text === "string" ? n.textData.text : collect(n.nodes)))
66
- .join("");
67
- const out: string[] = [];
68
- for (const node of rich?.nodes ?? []) {
69
- const text = collect([node]).trim();
70
- if (text) out.push(text);
71
- }
72
- if (!out.length && legacy) out.push(legacy);
73
- return out;
74
- }
75
-
76
- /**
77
- * The main image in the form imgSrc scales: the SDK carries it as a `wix:image://` string; REST
78
- * as `{ id, url, altText }` — rebuilt into the id form so both transports resolve one URL shape.
79
- */
80
- export function mainImageOf(raw: Raw): unknown {
81
- const m = raw.mainImage;
82
- if (m && typeof m === "object" && typeof m.id === "string" && m.id) {
83
- return `wix:image://v1/${m.id}/${encodeURIComponent(String(m.altText || "image"))}`;
84
- }
85
- return m;
86
- }
87
-
88
- export function toSummary(raw: Raw, imgSrc: ImgSrc): EventSummary {
89
- const reg: Raw = raw.registration ?? {};
90
- const dts: Raw = raw.dateAndTimeSettings ?? {};
91
- return {
92
- id: rawId(raw), // _id on the SDK, id on REST — never a bare .id on the SDK (undefined there)
93
- slug: raw.slug ?? "",
94
- title: raw.title ?? "",
95
- shortDescription: raw.shortDescription ?? "",
96
- dateLabel: dts.formatted?.dateAndTime ?? "",
97
- startDateIso: dts.startDate ? new Date(dts.startDate).toISOString() : "",
98
- locationName: raw.location?.name ?? "",
99
- locationType: raw.location?.locationTbd
100
- ? "TBD"
101
- : ((raw.location?.type as "VENUE" | "ONLINE") ?? "TBD"),
102
- imageUrl: imgSrc(mainImageOf(raw), 1200, 800),
103
- // `type` is the current flavor (can become EXTERNAL later); initialType is the immutable
104
- // seeded one — read type first.
105
- registrationType: (reg.type ?? reg.initialType ?? "NONE") as RegistrationType,
106
- priceLabel: lowestPriceLabel(reg),
107
- // The API reports tickets.soldOut true on an RSVP event too (it has no tickets at all) — sold
108
- // out is a ticketing signal only.
109
- soldOut: (reg.type ?? reg.initialType) === "TICKETING" && reg.tickets?.soldOut === true,
110
- // `categories` is absent on the typed Event (an SDK type gap) — the Raw boundary reads
111
- // the runtime field the CATEGORIES fieldset populates.
112
- categories: ((raw.categories?.categories ?? []) as Raw[])
113
- .map((c) => ({ id: rawId(c), name: c.name ?? "" }))
114
- .filter((c) => c.id),
115
- };
116
- }
117
-
118
- export function toDetail(raw: Raw, imgSrc: ImgSrc): EventDetail {
119
- const summary = toSummary(raw, imgSrc);
120
- const reg: Raw = raw.registration ?? {};
121
- return {
122
- ...summary,
123
- aboutParagraphs: toParagraphs(raw.description, raw.detailedDescription),
124
- // Only OPEN_* statuses (OPEN_RSVP, OPEN_TICKETS, OPEN_EXTERNAL, …) accept registrations.
125
- registrationOpen: typeof reg.status === "string" && reg.status.startsWith("OPEN_"),
126
- rsvpResponseType: reg.rsvp?.responseType === "YES_AND_NO" ? "YES_AND_NO" : "YES_ONLY",
127
- externalUrl: reg.external?.url ?? "",
128
- addToCalendar: { google: raw.calendarUrls?.google ?? "", ics: raw.calendarUrls?.ics ?? "" },
129
- };
130
- }
@@ -1,97 +0,0 @@
1
- // The events listing as a framework-free store — the logic behind useEvents, usable from React
2
- // (useEvents wraps it with useSyncExternalStore), from a static page or Vue/Svelte (subscribe and
3
- // render), or as the specification for a port. State, actions, subscribe/getState, emit after
4
- // every change.
5
- //
6
- // SSR-friendly: seed with `initialEvents` and they render at once with no client fetch; a SPA
7
- // passes nothing and `start()` fetches. The category menu is DERIVED from the loaded events (the
8
- // categories management API is admin-scope — visitors can't query it); filtering is client-side
9
- // over the live list, which is small by definition (only UPCOMING/STARTED events are listed).
10
- //
11
- // One store per mounted listing (a page can hold the index and a "next up" rail):
12
- // createEventsStore(), not a singleton.
13
- import { fetchEvents } from "./events";
14
- import type { EventSummary } from "./types";
15
-
16
- export interface EventsStoreOptions {
17
- initialEvents?: EventSummary[];
18
- }
19
-
20
- /** Everything a listing surface renders from. Read it with getState() or through a subscription. */
21
- export interface EventsState {
22
- /** null while the first load is in flight — render skeletons, not an empty state. */
23
- events: EventSummary[] | null;
24
- /** Unique assigned categories in listing order — render a filter bar only when > 1. */
25
- categories: { id: string; name: string }[];
26
- activeCategoryId: string | null;
27
- error: string | null;
28
- }
29
-
30
- export interface EventsStore {
31
- getState(): EventsState;
32
- subscribe(listener: () => void): () => void;
33
- /** Fetch when no `initialEvents` were given. Call once when mounted (a browser). */
34
- start(): void;
35
- /** Stop reacting; drop a late response. */
36
- stop(): void;
37
- setActiveCategoryId(id: string | null): void;
38
- }
39
-
40
- export function createEventsStore({ initialEvents }: EventsStoreOptions = {}): EventsStore {
41
- let all: EventSummary[] | null = initialEvents ?? null;
42
- let activeCategoryId: string | null = null;
43
- let error: string | null = null;
44
- let started = false;
45
- const listeners = new Set<() => void>();
46
- let snapshot: EventsState | null = null;
47
- const emit = () => {
48
- snapshot = null;
49
- for (const fn of listeners) fn();
50
- };
51
-
52
- function getState(): EventsState {
53
- if (snapshot) return snapshot;
54
- const seen = new Map<string, string>();
55
- for (const e of all ?? []) for (const c of e.categories) if (!seen.has(c.id)) seen.set(c.id, c.name);
56
- snapshot = {
57
- events: all === null ? null : activeCategoryId ? all.filter((e) => e.categories.some((c) => c.id === activeCategoryId)) : all,
58
- categories: [...seen.entries()].map(([id, name]) => ({ id, name })),
59
- activeCategoryId,
60
- error,
61
- };
62
- return snapshot;
63
- }
64
-
65
- return {
66
- getState,
67
- subscribe(fn) {
68
- listeners.add(fn);
69
- return () => listeners.delete(fn);
70
- },
71
- start() {
72
- if (started) return;
73
- started = true;
74
- if (initialEvents) return;
75
- fetchEvents()
76
- .then((list) => {
77
- if (!started) return;
78
- all = list;
79
- emit();
80
- })
81
- .catch((e) => {
82
- if (!started) return;
83
- all = [];
84
- error = e instanceof Error ? e.message : String(e);
85
- emit();
86
- });
87
- },
88
- stop() {
89
- started = false;
90
- },
91
- setActiveCategoryId(id) {
92
- if (id === activeCategoryId) return;
93
- activeCategoryId = id;
94
- emit();
95
- },
96
- };
97
- }
@@ -1,55 +0,0 @@
1
- // Event reads (Wix Events V3, the `wixEventsV2` module) over the SDK — the only file that touches
2
- // raw event entities on this transport. Everything it returns is a plain DTO from ./types. The
3
- // rules and mappers live in ./events-core (shared with the REST twin in references/events/rest/);
4
- // this file is the transport only. Copy as-is; extend by adding functions, not by editing these.
5
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/events-v3/query-events.md
6
- // docs: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/events-v3/get-event-by-slug.md
7
- import { wixEventsV2 } from "@wix/events";
8
- import { wixModule } from "../sdk";
9
- import { imgSrc } from "../media";
10
- import { DETAIL_FIELDS, EVENTS_APP_ID, LIST_FIELDS, LIVE_STATUSES, START_DATE_FIELD, rawId, toDetail, toSummary, type Raw } from "./events-core";
11
- import type { EventDetail, EventSummary } from "./types";
12
-
13
- export { EVENTS_APP_ID };
14
-
15
- const events = wixModule(wixEventsV2);
16
-
17
- /** List live (UPCOMING/STARTED) events, soonest first, mapped to grid-ready DTOs. */
18
- export async function fetchEvents({ limit = 100 } = {}): Promise<EventSummary[]> {
19
- // The query builder, never a flat/REST `{ query: {...} }` body (the SDK silently ignores
20
- // the unknown key and returns zero events). Always set a positive limit — it defaults to 0,
21
- // which also returns zero events with no error.
22
- const res = await events
23
- .queryEvents({ fields: LIST_FIELDS as any })
24
- .in("status", [...LIVE_STATUSES]) // never list or link a past event — it isn't registerable
25
- .ascending(START_DATE_FIELD as any)
26
- .limit(limit)
27
- .find();
28
- return (res.items ?? []).map((e: Raw) => toSummary(e, imgSrc));
29
- }
30
-
31
- /** Fetch one event by its URL slug. Null when not found. */
32
- export async function fetchEventBySlug(slug: string): Promise<EventDetail | null> {
33
- try {
34
- // getEventBySlug returns a WRAPPED { event } — unlike getEvent below.
35
- const res: Raw = await events.getEventBySlug(slug, { fields: DETAIL_FIELDS as any });
36
- const raw = res?.event;
37
- return raw ? toDetail(raw as Raw, imgSrc) : null;
38
- } catch {
39
- return null;
40
- }
41
- }
42
-
43
- /**
44
- * Fetch one event by id — the post-checkout confirmation read (the thank-you URL carries
45
- * `?orderNumber=&eventId=`). getEvent returns the Event DIRECTLY (unwrapped) — the one read
46
- * that isn't `{ event }`; assuming the wrapper crashes the page.
47
- */
48
- export async function fetchEventById(eventId: string): Promise<EventDetail | null> {
49
- try {
50
- const raw: Raw = await events.getEvent(eventId, { fields: DETAIL_FIELDS as any });
51
- return rawId(raw) ? toDetail(raw, imgSrc) : null;
52
- } catch {
53
- return null;
54
- }
55
- }
@@ -1,113 +0,0 @@
1
- // Registration rules and DTO mapping — transport-agnostic, imported by both ./registration.ts
2
- // (SDK) and the REST twin in references/events/rest/registration.ts (fetch). Tier mapping, the
3
- // reservation line items, the payment gate, the checkout callbacks, and the RSVP body live HERE,
4
- // once. Raw ticket definitions carry `_id` (SDK) or `id` (REST). Type-only imports so a strip
5
- // to JS emits none.
6
- import type { EventDetail, RegistrationResult, TicketTier } from "./types";
7
- import type { Raw } from "./events-core";
8
-
9
- const tierId = (raw: Raw | undefined | null): string => raw?._id ?? raw?.id ?? "";
10
-
11
- export function formatTierPrice(price: Raw | undefined): string {
12
- const value = price?.amount ?? price?.value;
13
- if (value == null || value === "") return "";
14
- try {
15
- return new Intl.NumberFormat(undefined, { style: "currency", currency: price?.currency || "USD" }).format(Number(value));
16
- } catch {
17
- return `${value} ${price?.currency ?? ""}`.trim();
18
- }
19
- }
20
-
21
- export function toTier(raw: Raw): TicketTier {
22
- const free = raw.free === true || Number(raw.price?.amount ?? raw.price?.value ?? 0) === 0;
23
- return {
24
- id: tierId(raw),
25
- name: raw.name ?? "",
26
- description: raw.description ?? "",
27
- price: free ? "Free" : formatTierPrice(raw.price),
28
- free,
29
- limitPerCheckout: raw.limitPerCheckout ?? 20,
30
- saleStatus: (raw.saleStatus ?? "SALE_STARTED") as TicketTier["saleStatus"],
31
- };
32
- }
33
-
34
- /** Tiers in display order (orderIndex), skipping any without an id. */
35
- export function toTiers(definitions: Raw[] | undefined): TicketTier[] {
36
- return (definitions ?? [])
37
- .slice()
38
- .sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0))
39
- .map(toTier)
40
- .filter((t) => t.id);
41
- }
42
-
43
- /** The reservation's line items from the picker's selections; throws when nothing is picked. */
44
- export function reservationTickets(selections: { tierId: string; quantity: number }[]): { ticketDefinitionId: string; quantity: number }[] {
45
- const tickets = selections
46
- .filter((s) => s.quantity > 0)
47
- .map((s) => ({ ticketDefinitionId: s.tierId, quantity: s.quantity }));
48
- if (!tickets.length) throw new Error("Pick at least one ticket first.");
49
- return tickets;
50
- }
51
-
52
- /**
53
- * The real gate on paid tickets: until the site has a premium plan AND a configured payment
54
- * method, reserving fails 403 NO_PAYMENT_METHOD_CONFIGURED. Not a permissions bug — don't
55
- * elevate (that just creates an unpayable order); surface it softly.
56
- */
57
- export function reservationError(e: unknown): Error {
58
- const msg = e instanceof Error ? e.message : String(e);
59
- if (/payment method|not configured|premium/i.test(msg)) {
60
- return new Error("Ticket sales aren't switched on yet — the organizer needs to connect a payment method in the dashboard.");
61
- }
62
- return e instanceof Error ? e : new Error(msg);
63
- }
64
-
65
- /** The reservation id out of either transport's response; throws when the hold didn't happen. */
66
- export function reservationId(reservation: Raw | null | undefined): string {
67
- const id = tierId(reservation);
68
- if (!id) throw new Error("Those tickets couldn't be reserved — they may have just sold out.");
69
- return id;
70
- }
71
-
72
- /** Where the hosted checkout returns to. Defaults are the Astro routes; a static site passes its file paths. */
73
- export interface CheckoutPaths {
74
- /** Success landing — Wix appends `?orderNumber=&eventId=`. Default `/event-confirmation`. */
75
- confirmation?: string;
76
- /** Back here on abandon. Default `/events/<slug>`. */
77
- event?: string;
78
- }
79
-
80
- /**
81
- * The redirect session's callbacks. `origin` is the published https host (window.location.origin
82
- * in a browser) — an http or server-derived origin isn't on the redirect allowlist and 403s the
83
- * return; {} when unknown (SSR).
84
- */
85
- export function checkoutCallbacks(origin: string, slug: string, paths: CheckoutPaths = {}): Raw {
86
- if (!origin) return {};
87
- return {
88
- thankYouPageUrl: `${origin}${paths.confirmation ?? "/event-confirmation"}`,
89
- postFlowUrl: `${origin}${paths.event ?? `/events/${slug}`}`,
90
- };
91
- }
92
-
93
- /** The redirect result; throws when Wix returned no URL. */
94
- export function redirectResult(session: Raw | null | undefined): RegistrationResult {
95
- const url = session?.redirectSession?.fullUrl;
96
- if (!url) throw new Error("Checkout couldn't start — please try again.");
97
- return { kind: "redirect", url };
98
- }
99
-
100
- /**
101
- * The RSVP body: the built-in form is exactly firstName + lastName + email — never a fetched
102
- * schema, never extra fields. "NO" only when the event's rsvpResponseType is "YES_AND_NO".
103
- */
104
- export function rsvpBody(eventId: string, guest: { firstName: string; lastName: string; email: string }, status: "YES" | "NO"): Raw {
105
- return { eventId, firstName: guest.firstName, lastName: guest.lastName, email: guest.email, status };
106
- }
107
-
108
- /** A full event with a waitlist answers status "WAITLIST" — tell the guest they're waitlisted, not confirmed. */
109
- export function rsvpResult(rsvp: Raw | null | undefined, sent: "YES" | "NO"): RegistrationResult {
110
- return { kind: "rsvpConfirmed", status: (rsvp?.status ?? sent) as "YES" | "NO" | "WAITLIST" };
111
- }
112
-
113
- export type CheckoutEvent = Pick<EventDetail, "id" | "slug">;