@wix/agent-skills 1.21.0 → 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 (258) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +60 -4
  3. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  4. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  5. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  6. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  7. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  8. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  9. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  10. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  11. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  12. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  13. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  14. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  15. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  16. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  17. package/skills/wix-headless-fast/SKILL.md +61 -223
  18. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  19. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +11 -12
  20. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  21. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  22. package/skills/wix-headless-fast/install/AGENTS.md +6 -3
  23. package/skills/wix-headless-fast/install/attach.mjs +15 -47
  24. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  25. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  26. package/skills/wix-headless-fast/install/setup.mjs +32 -12
  27. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  28. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  29. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  30. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -303
  31. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  32. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  33. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  34. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  35. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  36. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  37. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  38. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  39. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  40. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  41. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  42. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  43. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  44. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  45. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  46. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  47. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  48. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  49. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  50. package/skills/wix-headless-fast/references/blog/seed/read-site.mjs +0 -22
  51. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  52. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -277
  53. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  54. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  55. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  56. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  57. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  58. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  59. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  60. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  61. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  62. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  63. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  64. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  65. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  66. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  67. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  68. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  69. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  70. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  71. package/skills/wix-headless-fast/references/bookings/seed/read-site.mjs +0 -28
  72. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  73. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -355
  74. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  75. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  76. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  77. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  78. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  79. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  80. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  81. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  82. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  83. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  84. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  85. package/skills/wix-headless-fast/references/cms/seed/read-site.mjs +0 -20
  86. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  87. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -307
  88. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  89. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  90. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  91. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  92. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  93. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  94. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  95. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  96. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  97. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  98. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  99. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  100. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  101. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  102. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  103. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  104. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  105. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  106. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  107. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  108. package/skills/wix-headless-fast/references/events/seed/read-site.mjs +0 -26
  109. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  110. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -340
  111. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  112. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  113. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  114. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  115. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  116. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  117. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  118. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  119. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  120. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  121. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  122. package/skills/wix-headless-fast/references/forms/seed/read-site.mjs +0 -20
  123. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  124. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -316
  125. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  126. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  127. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  128. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  129. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  130. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  131. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  132. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  133. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  134. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  135. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  136. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  137. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  138. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  139. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  140. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  141. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  142. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  143. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  144. package/skills/wix-headless-fast/references/members/seed/read-site.mjs +0 -15
  145. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  146. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -315
  147. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  148. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  149. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  150. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  151. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  152. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  153. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  154. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  155. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  156. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  157. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  158. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  159. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  160. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  161. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  162. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  163. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  164. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  165. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  166. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  167. package/skills/wix-headless-fast/references/portfolio/seed/read-site.mjs +0 -20
  168. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -256
  169. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -296
  170. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  171. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  172. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  173. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  174. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  175. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  176. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  177. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  178. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  179. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  180. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  181. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  182. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  183. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  184. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  185. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  186. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  187. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  188. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  189. package/skills/wix-headless-fast/references/pricing-plans/seed/read-site.mjs +0 -21
  190. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  191. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -360
  192. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  193. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  194. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  195. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  196. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  197. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  198. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  199. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  200. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  201. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  202. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  203. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  204. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  205. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  209. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  210. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  211. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  212. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  213. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  214. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  215. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  216. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  217. package/skills/wix-headless-fast/references/restaurants/seed/read-site.mjs +0 -25
  218. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -499
  219. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  220. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  221. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  222. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  223. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  224. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  225. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  226. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  227. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  228. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  229. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  230. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  231. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  232. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  233. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  234. package/skills/wix-headless-fast/references/shared/seed/read-site.mjs +0 -99
  235. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -612
  236. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  237. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  238. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  239. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  240. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  241. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  242. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  243. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  244. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  245. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  246. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  247. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -314
  248. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -169
  252. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  253. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  254. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  255. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  256. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -130
  257. package/skills/wix-headless-fast/references/storefront/seed/read-site.mjs +0 -38
  258. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -561
@@ -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">;