@wix/agent-skills 1.16.3 → 1.18.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 (283) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +115 -12
  3. package/skills/wix-app/references/APP_MARKET_REVIEW.md +1 -1
  4. package/skills/wix-app/references/BACKEND_API.md +18 -0
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +6 -0
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +10 -2
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +32 -70
  8. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +145 -127
  9. package/skills/wix-app/references/SITE_PLUGIN.md +14 -2
  10. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +74 -68
  11. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +2 -2
  12. package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +79 -0
  13. package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +73 -0
  14. package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +52 -0
  15. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +184 -0
  16. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +182 -99
  17. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +94 -49
  18. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +16 -6
  19. package/skills/wix-app/references/editor-react-component/BROWSER-SUPPORT.md +56 -0
  20. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +275 -0
  21. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +35 -40
  22. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +167 -445
  23. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +56 -29
  24. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +53 -158
  25. package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +78 -0
  26. package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +42 -134
  27. package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +11 -3
  28. package/skills/wix-app/references/editor-react-component/PARTS.md +46 -24
  29. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +63 -179
  30. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +79 -163
  31. package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +36 -21
  32. package/skills/wix-app/references/editor-react-component/SSR.md +30 -99
  33. package/skills/wix-base44-connector/SKILL.md +156 -50
  34. package/skills/wix-base44-connector/references/CAPABILITY_MAP.md +78 -0
  35. package/skills/wix-base44-connector/scripts/utils.js +239 -45
  36. package/skills/wix-headless/entry/bootstrap.mjs +9 -2
  37. package/skills/wix-headless/entry/skill.md +1 -1
  38. package/skills/wix-headless/references/CAPABILITIES.md +9 -1
  39. package/skills/wix-headless/references/DESIGN.md +1 -0
  40. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  41. package/skills/wix-headless/references/IMAGE_GENERATION.md +1 -0
  42. package/skills/wix-headless/references/SDK_HANDOFF.md +5 -2
  43. package/skills/wix-headless/references/SEED.md +2 -1
  44. package/skills/wix-headless/references/SETUP.md +1 -0
  45. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +2 -2
  46. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +68 -31
  47. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +26 -10
  48. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +8 -8
  49. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +1 -1
  50. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +1 -1
  51. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +10 -8
  52. package/skills/wix-headless/references/inline-recipes/how-to-code-rentals.md +254 -0
  53. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +27 -24
  54. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +13 -0
  55. package/skills/wix-headless/references/inline-recipes/setup-rentals.md +254 -0
  56. package/skills/wix-headless/references/managed/AUTHENTICATION.md +5 -0
  57. package/skills/wix-headless/references/non-astro.md +1 -1
  58. package/skills/wix-headless-fast/SKILL.md +166 -0
  59. package/skills/wix-headless-fast/entry/skill.md +99 -0
  60. package/skills/wix-headless-fast/install/deploy.mjs +433 -0
  61. package/skills/wix-headless-fast/install/fast-path.mjs +141 -0
  62. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +137 -0
  63. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +137 -0
  64. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +113 -0
  65. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +42 -0
  66. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +123 -0
  67. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +70 -0
  68. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +99 -0
  69. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +76 -0
  70. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +62 -0
  71. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +40 -0
  72. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +99 -0
  73. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +24 -0
  74. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +16156 -0
  75. package/skills/wix-headless-fast/references/blog/seed/SEED.md +72 -0
  76. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +287 -0
  77. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +129 -0
  78. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +143 -0
  79. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +119 -0
  80. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +138 -0
  81. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +54 -0
  82. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +206 -0
  83. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +96 -0
  84. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +70 -0
  85. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +40 -0
  86. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +76 -0
  87. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +22 -0
  88. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +11962 -0
  89. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +61 -0
  90. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +302 -0
  91. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +179 -0
  92. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +83 -0
  93. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +57 -0
  94. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +151 -0
  95. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +75 -0
  96. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +41 -0
  97. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +11262 -0
  98. package/skills/wix-headless-fast/references/cms/seed/SEED.md +103 -0
  99. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +324 -0
  100. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +149 -0
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +66 -0
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +176 -0
  103. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +118 -0
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +117 -0
  105. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +59 -0
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +136 -0
  107. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +128 -0
  108. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +61 -0
  109. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +40 -0
  110. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +12 -0
  111. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +80 -0
  112. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +21 -0
  113. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +11884 -0
  114. package/skills/wix-headless-fast/references/events/seed/SEED.md +86 -0
  115. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +276 -0
  116. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +150 -0
  117. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +317 -0
  118. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +269 -0
  119. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +231 -0
  120. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +135 -0
  121. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +10593 -0
  122. package/skills/wix-headless-fast/references/forms/seed/SEED.md +108 -0
  123. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +320 -0
  124. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +63 -0
  125. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +60 -0
  126. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +155 -0
  127. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +78 -0
  128. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +47 -0
  129. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +66 -0
  130. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +88 -0
  131. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +53 -0
  132. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +122 -0
  133. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +50 -0
  134. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +21 -0
  135. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +42 -0
  136. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +10 -0
  137. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +11 -0
  138. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +10329 -0
  139. package/skills/wix-headless-fast/references/members/seed/SEED.md +39 -0
  140. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +94 -0
  141. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +134 -0
  142. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +110 -0
  143. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +90 -0
  144. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +115 -0
  145. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +59 -0
  146. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +39 -0
  147. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +58 -0
  148. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +165 -0
  149. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +55 -0
  150. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +40 -0
  151. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +30 -0
  152. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +21 -0
  153. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +29 -0
  154. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +10197 -0
  155. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +78 -0
  156. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +258 -0
  157. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +133 -0
  158. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +58 -0
  159. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +126 -0
  160. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +37 -0
  161. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +39 -0
  162. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +75 -0
  163. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +45 -0
  164. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +30 -0
  165. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +41 -0
  166. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +40 -0
  167. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +21 -0
  168. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +11226 -0
  169. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +71 -0
  170. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +279 -0
  171. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +165 -0
  172. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +142 -0
  173. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +26 -0
  174. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +121 -0
  175. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +155 -0
  176. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +55 -0
  177. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +43 -0
  178. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +177 -0
  179. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +165 -0
  180. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +103 -0
  181. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +254 -0
  182. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +146 -0
  183. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +168 -0
  184. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +47 -0
  185. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +22 -0
  186. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +12 -0
  187. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +12560 -0
  188. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +81 -0
  189. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +479 -0
  190. package/skills/wix-headless-fast/references/shared/CONTENT.md +22 -0
  191. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +73 -0
  192. package/skills/wix-headless-fast/references/shared/DESIGN.md +26 -0
  193. package/skills/wix-headless-fast/references/shared/app/styles/global.css +52 -0
  194. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +15 -0
  195. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +27 -0
  196. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +24 -0
  197. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +76 -0
  198. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +46 -0
  199. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +46 -0
  200. package/skills/wix-headless-fast/references/shared/seed/images.mjs +145 -0
  201. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +149 -0
  202. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +26 -0
  203. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +121 -0
  204. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductCard.tsx +100 -0
  205. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductDetailView.tsx +130 -0
  206. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductGrid.tsx +48 -0
  207. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ShopView.tsx +66 -0
  208. package/skills/wix-headless-fast/references/storefront/app/components/storefront/VariantPicker.tsx +103 -0
  209. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +48 -0
  210. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +140 -0
  211. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +80 -0
  212. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +101 -0
  213. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +221 -0
  214. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +215 -0
  215. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +109 -0
  216. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +46 -0
  217. package/skills/wix-headless-fast/references/storefront/app-astro/pages/products/[slug].astro +56 -0
  218. package/skills/wix-headless-fast/references/storefront/app-astro/pages/shop.astro +23 -0
  219. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +12247 -0
  220. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +85 -0
  221. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +415 -0
  222. package/skills/wix-manage/SKILL.md +28 -2
  223. package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +20 -13
  224. package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +24 -11
  225. package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +5 -5
  226. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +141 -0
  227. package/skills/wix-manage/references/google-business-profile/connect-google-business-profile.md +134 -0
  228. package/skills/wix-manage/references/google-business-profile/manage-google-business-profile-locations.md +182 -0
  229. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +3 -0
  230. package/skills/wix-manage/references/seo/manage-seo-tags.md +315 -0
  231. package/skills/wix-manage/references/seo/manage-url-redirects.md +250 -0
  232. package/skills/wix-manage/references/sites/query-sites.md +72 -161
  233. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +21 -6
  234. package/skills/wix-manage/references/stores/update-product-with-options.md +83 -0
  235. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +5 -6
  236. package/skills/wix-vibe-headless/SKILL.md +18 -4
  237. package/skills/wix-vibe-headless/install/deploy.cjs +12 -4
  238. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +2 -1
  239. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +16 -10
  240. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +13 -8
  241. package/skills/wix-vibe-headless/platforms/base44.md +27 -62
  242. package/skills/wix-vibe-headless/platforms/generic.md +6 -3
  243. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +45 -0
  244. package/skills/wix-vibe-headless/references/bookings/app/components/RentalDurationPicker.jsx +67 -0
  245. package/skills/wix-vibe-headless/references/bookings/app/hooks/useRentalDuration.js +128 -0
  246. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +5 -3
  247. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +9 -8
  248. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-rentals.js +250 -0
  249. package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-services.js +12 -5
  250. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +41 -0
  251. package/skills/wix-vibe-headless/references/bookings/seed/seed-rentals.js +267 -0
  252. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +6 -3
  253. package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +470 -0
  254. package/skills/wix-vibe-headless/references/forms/app/hooks/useWixForm.js +425 -0
  255. package/skills/wix-vibe-headless/references/forms/app/lib/wix-form-schema-utils.js +187 -0
  256. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms-submissions.js +238 -0
  257. package/skills/wix-vibe-headless/references/forms/app/rest/wix-forms.js +108 -0
  258. package/skills/wix-vibe-headless/references/forms/seed/SEED.md +1762 -0
  259. package/skills/wix-vibe-headless/references/rentals/INSTRUCTIONS.md +13 -0
  260. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +4 -1
  261. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +23 -11
  262. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +1 -1
  263. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +29 -31
  264. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +152 -92
  265. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +37 -38
  266. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +2 -2
  267. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +15 -8
  268. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +37 -0
  269. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +35 -35
  270. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +18 -6
  271. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +30 -7
  272. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +46 -10
  273. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +0 -172
  274. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +0 -143
  275. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +0 -516
  276. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +0 -225
  277. package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +0 -6
  278. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +0 -95
  279. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +0 -110
  280. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +0 -51
  281. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +0 -49
  282. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +0 -92
  283. package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +0 -139
@@ -0,0 +1,155 @@
1
+ // Shipped custom login form. The member stays on this site: credential calls exchange
2
+ // directly into member tokens; only logout leaves the app.
3
+ import { FormEvent, useState } from "react";
4
+ import { useMember } from "../../hooks/members/useMember";
5
+
6
+ export interface LoginFormProps {
7
+ onSuccess?: () => void;
8
+ }
9
+
10
+ export default function LoginForm({ onSuccess }: LoginFormProps) {
11
+ const { login, register, verifyEmail, error } = useMember();
12
+ const [mode, setMode] = useState<"login" | "register">("login");
13
+ const [email, setEmail] = useState("");
14
+ const [password, setPassword] = useState("");
15
+ const [firstName, setFirstName] = useState("");
16
+ const [lastName, setLastName] = useState("");
17
+ const [code, setCode] = useState("");
18
+ const [verification, setVerification] = useState(false);
19
+ const [pending, setPending] = useState(false);
20
+ const [busy, setBusy] = useState(false);
21
+
22
+ function done() {
23
+ if (onSuccess) return onSuccess();
24
+ const returnTo = new URLSearchParams(window.location.search).get(
25
+ "returnTo",
26
+ );
27
+ window.location.assign(returnTo?.startsWith("/") ? returnTo : "/account");
28
+ }
29
+
30
+ async function submit(event: FormEvent) {
31
+ event.preventDefault();
32
+ setBusy(true);
33
+ try {
34
+ const result =
35
+ mode === "login"
36
+ ? await login(email, password)
37
+ : await register(email, password, { firstName, lastName });
38
+ if (result.state === "SUCCESS") done();
39
+ if (result.state === "EMAIL_VERIFICATION_REQUIRED") setVerification(true);
40
+ if (result.state === "OWNER_APPROVAL_REQUIRED") setPending(true);
41
+ } finally {
42
+ setBusy(false);
43
+ }
44
+ }
45
+
46
+ async function submitCode(event: FormEvent) {
47
+ event.preventDefault();
48
+ setBusy(true);
49
+ try {
50
+ const result = await verifyEmail(code);
51
+ if (result.state === "SUCCESS") done();
52
+ if (result.state === "OWNER_APPROVAL_REQUIRED") setPending(true);
53
+ } finally {
54
+ setBusy(false);
55
+ }
56
+ }
57
+
58
+ if (pending)
59
+ return (
60
+ <p className="rounded-lg border border-border p-4 text-sm">
61
+ Your account is awaiting approval.
62
+ </p>
63
+ );
64
+ if (verification) {
65
+ return (
66
+ <form onSubmit={submitCode} className="space-y-4">
67
+ <label className="block text-sm">
68
+ Verification code
69
+ <input
70
+ required
71
+ value={code}
72
+ onChange={(event) => setCode(event.target.value)}
73
+ className="mt-1 w-full rounded border border-border bg-background p-2"
74
+ />
75
+ </label>
76
+ {error && <p className="text-sm text-red-600">{error}</p>}
77
+ <button
78
+ disabled={busy}
79
+ className="rounded bg-primary px-4 py-2 text-primary-foreground"
80
+ >
81
+ {busy ? "Verifying…" : "Verify"}
82
+ </button>
83
+ </form>
84
+ );
85
+ }
86
+ return (
87
+ <form onSubmit={submit} className="space-y-4">
88
+ <div className="flex gap-2">
89
+ <button
90
+ type="button"
91
+ onClick={() => setMode("login")}
92
+ className="text-sm underline"
93
+ >
94
+ Sign in
95
+ </button>
96
+ <button
97
+ type="button"
98
+ onClick={() => setMode("register")}
99
+ className="text-sm underline"
100
+ >
101
+ Sign up
102
+ </button>
103
+ </div>
104
+ {mode === "register" && (
105
+ <div className="grid gap-3 sm:grid-cols-2">
106
+ <label className="text-sm">
107
+ First name
108
+ <input
109
+ value={firstName}
110
+ onChange={(event) => setFirstName(event.target.value)}
111
+ className="mt-1 w-full rounded border border-border bg-background p-2"
112
+ />
113
+ </label>
114
+ <label className="text-sm">
115
+ Last name
116
+ <input
117
+ value={lastName}
118
+ onChange={(event) => setLastName(event.target.value)}
119
+ className="mt-1 w-full rounded border border-border bg-background p-2"
120
+ />
121
+ </label>
122
+ </div>
123
+ )}
124
+ <label className="block text-sm">
125
+ Email
126
+ <input
127
+ required
128
+ type="email"
129
+ autoComplete="email"
130
+ value={email}
131
+ onChange={(event) => setEmail(event.target.value)}
132
+ className="mt-1 w-full rounded border border-border bg-background p-2"
133
+ />
134
+ </label>
135
+ <label className="block text-sm">
136
+ Password
137
+ <input
138
+ required
139
+ type="password"
140
+ autoComplete={mode === "login" ? "current-password" : "new-password"}
141
+ value={password}
142
+ onChange={(event) => setPassword(event.target.value)}
143
+ className="mt-1 w-full rounded border border-border bg-background p-2"
144
+ />
145
+ </label>
146
+ {error && <p className="text-sm text-red-600">{error}</p>}
147
+ <button
148
+ disabled={busy}
149
+ className="rounded bg-primary px-4 py-2 text-primary-foreground"
150
+ >
151
+ {busy ? "Working…" : mode === "login" ? "Sign in" : "Create account"}
152
+ </button>
153
+ </form>
154
+ );
155
+ }
@@ -0,0 +1,78 @@
1
+ // REFERENCE header account control on the @theme tokens: "Log in" for a visitor; account
2
+ // link + log-out for a member. Correct and complete; per the skill's model you design your
3
+ // own on useMember. Mount client:only="react" — it reads browser session state.
4
+ import type { ComponentType, ReactNode } from "react";
5
+ import { useMember } from "../../hooks/members/useMember";
6
+
7
+ export interface LinkLikeProps {
8
+ href: string;
9
+ className?: string;
10
+ children?: ReactNode;
11
+ }
12
+
13
+ const PlainLink = ({ href, className, children }: LinkLikeProps) => (
14
+ <a href={href} className={className}>
15
+ {children}
16
+ </a>
17
+ );
18
+
19
+ export interface MemberMenuProps {
20
+ accountHref?: string;
21
+ LinkComponent?: ComponentType<LinkLikeProps>;
22
+ }
23
+
24
+ export default function MemberMenu({
25
+ accountHref = "/account",
26
+ LinkComponent = PlainLink,
27
+ }: MemberMenuProps) {
28
+ const { member, loggedIn, loading, logout } = useMember();
29
+
30
+ if (loading) {
31
+ return (
32
+ <span
33
+ className="inline-block h-8 w-16 animate-pulse rounded-full bg-secondary"
34
+ aria-hidden="true"
35
+ />
36
+ );
37
+ }
38
+
39
+ if (!loggedIn) {
40
+ return (
41
+ <a
42
+ href="/login"
43
+ className="rounded-full bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90"
44
+ >
45
+ Log in
46
+ </a>
47
+ );
48
+ }
49
+
50
+ return (
51
+ <span className="flex items-center gap-3">
52
+ <LinkComponent
53
+ href={accountHref}
54
+ className="flex items-center gap-2 text-sm font-medium text-foreground no-underline transition-colors hover:text-muted-foreground"
55
+ >
56
+ {member?.photoUrl ? (
57
+ <img
58
+ src={member.photoUrl}
59
+ alt=""
60
+ className="h-7 w-7 rounded-full object-cover"
61
+ />
62
+ ) : (
63
+ <span className="flex h-7 w-7 items-center justify-center rounded-full bg-secondary text-xs font-semibold">
64
+ {(member?.displayName ?? "M").slice(0, 1).toUpperCase()}
65
+ </span>
66
+ )}
67
+ {member?.displayName ?? "My account"}
68
+ </LinkComponent>
69
+ <button
70
+ type="button"
71
+ onClick={() => void logout()}
72
+ className="text-sm text-muted-foreground transition-colors hover:text-foreground"
73
+ >
74
+ Log out
75
+ </button>
76
+ </span>
77
+ );
78
+ }
@@ -0,0 +1,47 @@
1
+ // REFERENCE gate for member-only surfaces on the REACT stack — on Astro, gate server-side
2
+ // in frontmatter instead (pages/account.astro shows the shape); a client-side check there
3
+ // flashes gated UI. Renders children only for a logged-in member; a visitor gets a login
4
+ // prompt in place (routing-free — no router or redirect assumptions).
5
+ import type { ReactNode } from "react";
6
+ import { useMember } from "../../hooks/members/useMember";
7
+
8
+ export interface RequireAuthProps {
9
+ children: ReactNode;
10
+ /** Rendered for an anonymous visitor instead of the default login prompt. */
11
+ fallback?: ReactNode;
12
+ }
13
+
14
+ export default function RequireAuth({ children, fallback }: RequireAuthProps) {
15
+ const { loggedIn, loading } = useMember();
16
+
17
+ // Wait for the initial session read — deciding early bounces a logged-in member on first paint.
18
+ if (loading) {
19
+ return (
20
+ <div className="py-16 text-center text-muted-foreground" aria-busy="true">
21
+ Loading…
22
+ </div>
23
+ );
24
+ }
25
+
26
+ if (!loggedIn) {
27
+ return (
28
+ <>
29
+ {fallback ?? (
30
+ <div className="mx-auto max-w-md rounded-lg border border-border p-8 text-center">
31
+ <p className="text-sm text-muted-foreground">
32
+ This page is for members.
33
+ </p>
34
+ <a
35
+ href={`/login?returnTo=${encodeURIComponent(window.location.pathname)}`}
36
+ className="mt-4 rounded-full bg-primary px-5 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90"
37
+ >
38
+ Log in / Sign up
39
+ </a>
40
+ </div>
41
+ )}
42
+ </>
43
+ );
44
+ }
45
+
46
+ return <>{children}</>;
47
+ }
@@ -0,0 +1,66 @@
1
+ // React binding for the member store. Works in any React root — Astro islands (several on
2
+ // one page share the same session) and SPAs alike. SSR-friendly: pass a server-resolved
3
+ // member as `initialMember` (Astro island props) and no client re-fetch happens.
4
+ import { useRef, useSyncExternalStore } from "react";
5
+ import {
6
+ getMemberState,
7
+ hydrateMember,
8
+ login,
9
+ register,
10
+ logout,
11
+ refreshMember,
12
+ subscribeMember,
13
+ verifyEmail,
14
+ type MemberState,
15
+ } from "../../wix/members/member-store";
16
+ import type { LoginResult } from "../../wix/members/auth";
17
+ import type { CurrentMember } from "../../wix/members/types";
18
+
19
+ export interface UseMemberOptions {
20
+ /** Server-resolved member (null = a known-anonymous visitor); omit to resolve client-side. */
21
+ initialMember?: CurrentMember | null;
22
+ }
23
+
24
+ export interface UseMember extends MemberState {
25
+ /** Submit the shipped in-app credential form. */
26
+ login: (email: string, password: string) => Promise<LoginResult>;
27
+ register: (
28
+ email: string,
29
+ password: string,
30
+ profile?: { firstName?: string; lastName?: string },
31
+ ) => Promise<LoginResult>;
32
+ verifyEmail: (code: string) => Promise<LoginResult>;
33
+ /** Log out through the Wix logout flow; navigates away. */
34
+ logout: (returnTo?: string) => Promise<void>;
35
+ refresh: () => Promise<void>;
36
+ }
37
+
38
+ export function useMember({ initialMember }: UseMemberOptions = {}): UseMember {
39
+ // Adopt SSR props into the shared store before the first subscription (a no-op once any
40
+ // island has settled the session).
41
+ if (typeof window !== "undefined" && initialMember !== undefined)
42
+ hydrateMember(initialMember);
43
+ const server = useRef<MemberState | null>(null);
44
+ server.current ??=
45
+ initialMember !== undefined
46
+ ? {
47
+ member: initialMember,
48
+ loggedIn: initialMember !== null,
49
+ loading: false,
50
+ error: null,
51
+ }
52
+ : getMemberState();
53
+ const state = useSyncExternalStore(
54
+ subscribeMember,
55
+ getMemberState,
56
+ () => server.current as MemberState,
57
+ );
58
+ return {
59
+ ...state,
60
+ login,
61
+ register,
62
+ verifyEmail,
63
+ logout,
64
+ refresh: refreshMember,
65
+ };
66
+ }
@@ -0,0 +1,88 @@
1
+ // Custom, in-app member authentication. Credentials are submitted from the branded
2
+ // LoginForm; there is no Wix-hosted login-page redirect or callback route.
3
+ import { membersAuth } from "./client";
4
+
5
+ export type LoginState =
6
+ | "SUCCESS"
7
+ | "EMAIL_VERIFICATION_REQUIRED"
8
+ | "OWNER_APPROVAL_REQUIRED"
9
+ | "FAILURE";
10
+
11
+ export interface LoginResult {
12
+ state: LoginState;
13
+ stateToken?: string;
14
+ errorCode?: string;
15
+ error?: string;
16
+ }
17
+
18
+ type AuthResponse = {
19
+ loginState?: LoginState;
20
+ data?: { sessionToken?: string };
21
+ stateToken?: string;
22
+ errorCode?: string;
23
+ error?: string;
24
+ };
25
+
26
+ export function loggedInHint(): boolean {
27
+ return membersAuth.loggedIn();
28
+ }
29
+
30
+ async function finish(response: AuthResponse): Promise<LoginResult> {
31
+ const state = response.loginState ?? "FAILURE";
32
+ if (state === "SUCCESS") {
33
+ const sessionToken = response.data?.sessionToken;
34
+ if (!sessionToken)
35
+ return {
36
+ state: "FAILURE",
37
+ error: "Wix did not return a member session.",
38
+ };
39
+ const tokens =
40
+ await membersAuth.getMemberTokensForDirectLogin(sessionToken);
41
+ membersAuth.setTokens(tokens);
42
+ return { state };
43
+ }
44
+ return {
45
+ state,
46
+ ...(response.stateToken ? { stateToken: response.stateToken } : {}),
47
+ ...(response.errorCode ? { errorCode: response.errorCode } : {}),
48
+ ...(response.error ? { error: response.error } : {}),
49
+ };
50
+ }
51
+
52
+ export async function loginMember(
53
+ email: string,
54
+ password: string,
55
+ ): Promise<LoginResult> {
56
+ return finish((await membersAuth.login({ email, password })) as AuthResponse);
57
+ }
58
+
59
+ export async function registerMember(
60
+ email: string,
61
+ password: string,
62
+ profile?: { firstName?: string; lastName?: string },
63
+ ): Promise<LoginResult> {
64
+ return finish(
65
+ (await membersAuth.register({
66
+ email,
67
+ password,
68
+ ...(profile ? { profile } : {}),
69
+ })) as AuthResponse,
70
+ );
71
+ }
72
+
73
+ export async function verifyMemberEmail(
74
+ verificationCode: string,
75
+ ): Promise<LoginResult> {
76
+ return finish(
77
+ (await membersAuth.processVerification({
78
+ verificationCode,
79
+ })) as AuthResponse,
80
+ );
81
+ }
82
+
83
+ export async function logoutMember(returnTo = "/"): Promise<void> {
84
+ const { logoutUrl } = await membersAuth.logout(
85
+ new URL(returnTo, window.location.origin).href,
86
+ );
87
+ window.location.assign(logoutUrl);
88
+ }
@@ -0,0 +1,53 @@
1
+ // Explicit custom-login client for the Members vertical. Unlike the shared SDK seam,
2
+ // this client is used in a browser island even on managed Astro: direct credential login
3
+ // cannot use the Wix-hosted /api/auth redirect flow.
4
+ import { createClient, EMPTY_TOKENS, OAuthStrategy } from "@wix/sdk";
5
+ import type { TokenStorage, Tokens } from "@wix/sdk";
6
+ import { members } from "@wix/members";
7
+ import { WIX_MEMBERS_CLIENT_ID } from "../../config";
8
+
9
+ // `@wix/astro` uses this cookie as the session source for both browser islands
10
+ // and the next server render. Direct login must write the exact same contract,
11
+ // so the member identity becomes the managed Astro identity too.
12
+ const SESSION_COOKIE_NAME = "wixSession";
13
+
14
+ const tokenStorage: TokenStorage = {
15
+ getTokens(): Tokens {
16
+ try {
17
+ const raw = document.cookie
18
+ .split("; ")
19
+ .find((cookie) => cookie.startsWith(`${SESSION_COOKIE_NAME}=`));
20
+ if (!raw) return EMPTY_TOKENS;
21
+ const session = JSON.parse(
22
+ decodeURIComponent(raw.slice(SESSION_COOKIE_NAME.length + 1)),
23
+ ) as { clientId?: string; tokens?: Tokens };
24
+ return session.clientId === WIX_MEMBERS_CLIENT_ID && session.tokens
25
+ ? session.tokens
26
+ : EMPTY_TOKENS;
27
+ } catch {
28
+ return EMPTY_TOKENS;
29
+ }
30
+ },
31
+ setTokens(tokens: Tokens): void {
32
+ try {
33
+ const value = encodeURIComponent(
34
+ JSON.stringify({ clientId: WIX_MEMBERS_CLIENT_ID, tokens }),
35
+ );
36
+ document.cookie = `${SESSION_COOKIE_NAME}=${value}; path=/; secure; samesite=none`;
37
+ } catch {
38
+ // A blocked cookie only prevents the member session from surviving navigation.
39
+ }
40
+ },
41
+ };
42
+
43
+ if (!WIX_MEMBERS_CLIENT_ID) {
44
+ throw new Error("Custom member login needs WIX_MEMBERS_CLIENT_ID.");
45
+ }
46
+
47
+ const client = createClient({
48
+ modules: { members },
49
+ auth: OAuthStrategy({ clientId: WIX_MEMBERS_CLIENT_ID, tokenStorage }),
50
+ });
51
+
52
+ export const membersAuth = client.auth;
53
+ export const membersApi = client.members;
@@ -0,0 +1,122 @@
1
+ // Member session state — a module-scope store, deliberately NOT a React context.
2
+ // A context can't span Astro islands (each island is its own React root); a module
3
+ // singleton is shared by every island in the page bundle, and works identically in a
4
+ // single-root SPA. Consume it through useMember() (hooks/), or subscribe directly.
5
+ import { fetchCurrentMember } from "./members";
6
+ import {
7
+ loggedInHint,
8
+ loginMember,
9
+ logoutMember,
10
+ registerMember,
11
+ verifyMemberEmail,
12
+ type LoginResult,
13
+ } from "./auth";
14
+ import type { CurrentMember } from "./types";
15
+
16
+ export interface MemberState {
17
+ member: CurrentMember | null;
18
+ /** True for a logged-in member — can be true with `member` null when the Members Area app is absent. */
19
+ loggedIn: boolean;
20
+ /** True until the first session read settles — render skeletons, not the logged-out state. */
21
+ loading: boolean;
22
+ /** Last failed operation's message — render it; a new operation clears it. */
23
+ error: string | null;
24
+ }
25
+
26
+ const EMPTY: MemberState = {
27
+ member: null,
28
+ loggedIn: false,
29
+ loading: true,
30
+ error: null,
31
+ };
32
+
33
+ let state: MemberState = EMPTY;
34
+ const listeners = new Set<() => void>();
35
+ let started = false;
36
+
37
+ function setState(patch: Partial<MemberState>): void {
38
+ state = { ...state, ...patch };
39
+ for (const l of listeners) l();
40
+ }
41
+
42
+ export function getMemberState(): MemberState {
43
+ return state;
44
+ }
45
+
46
+ /** Adopt an SSR-resolved member (Astro island props) so no client re-fetch happens. */
47
+ export function hydrateMember(member: CurrentMember | null): void {
48
+ if (started) return;
49
+ started = true;
50
+ state = { member, loggedIn: member !== null, loading: false, error: null };
51
+ }
52
+
53
+ export function subscribeMember(listener: () => void): () => void {
54
+ listeners.add(listener);
55
+ // First subscriber triggers the initial session read (browser only — SSR renders `loading`).
56
+ if (!started && typeof window !== "undefined") {
57
+ started = true;
58
+ void refreshMember();
59
+ }
60
+ return () => listeners.delete(listener);
61
+ }
62
+
63
+ /** Re-read the session — call after anything that may have changed it. */
64
+ export async function refreshMember(): Promise<void> {
65
+ setState({ loading: true, error: null });
66
+ const hint = loggedInHint();
67
+ if (hint === false) {
68
+ setState({ member: null, loggedIn: false, loading: false });
69
+ return;
70
+ }
71
+ // hint true → read the profile (null = profile data missing, still logged in).
72
+ // hint null (ambient) → the member read IS the session check: null = anonymous.
73
+ const member = await fetchCurrentMember();
74
+ setState({ member, loggedIn: hint ?? member !== null, loading: false });
75
+ }
76
+
77
+ async function runLogin(
78
+ action: () => Promise<LoginResult>,
79
+ ): Promise<LoginResult> {
80
+ try {
81
+ const result = await action();
82
+ if (result.state === "SUCCESS") await refreshMember();
83
+ if (result.state === "FAILURE")
84
+ setState({
85
+ error: result.error ?? result.errorCode ?? "Could not log in.",
86
+ });
87
+ return result;
88
+ } catch (e) {
89
+ setState({ error: e instanceof Error ? e.message : String(e) });
90
+ throw e;
91
+ }
92
+ }
93
+
94
+ /** Submit the branded in-app sign-in form. No Wix-hosted login redirect is used. */
95
+ export function login(email: string, password: string): Promise<LoginResult> {
96
+ return runLogin(() => loginMember(email, password));
97
+ }
98
+
99
+ /** Submit the branded in-app sign-up form. */
100
+ export function register(
101
+ email: string,
102
+ password: string,
103
+ profile?: { firstName?: string; lastName?: string },
104
+ ): Promise<LoginResult> {
105
+ return runLogin(() => registerMember(email, password, profile));
106
+ }
107
+
108
+ /** Finish an email-verification branch from the same in-app form. */
109
+ export function verifyEmail(code: string): Promise<LoginResult> {
110
+ return runLogin(() => verifyMemberEmail(code));
111
+ }
112
+
113
+ /** Log out (navigates away); local state resets for the instant before the redirect lands. */
114
+ export async function logout(returnTo?: string): Promise<void> {
115
+ setState({ member: null, loggedIn: false });
116
+ try {
117
+ await logoutMember(returnTo);
118
+ } catch (e) {
119
+ setState({ error: e instanceof Error ? e.message : String(e) });
120
+ throw e;
121
+ }
122
+ }
@@ -0,0 +1,50 @@
1
+ // Current-member read (Wix Members) — the only file that touches raw member entities.
2
+ // Identity vs. profile are different layers: "is this caller logged in?" needs no app
3
+ // install, but getCurrentMember returns profile DATA only once the Wix Members Area app is
4
+ // installed (the seed installs it). Copy as-is; extend by adding functions, not by editing
5
+ // these.
6
+ // docs: https://dev.wix.com/docs/api-reference/crm/members-contacts/members/members/get-my-member.md
7
+ import { membersApi } from "./client";
8
+ import { imgSrc } from "../media";
9
+ import type { CurrentMember } from "./types";
10
+
11
+ type Raw = Record<string, any>;
12
+
13
+ function toCurrentMember(raw: Raw): CurrentMember {
14
+ const nickname = raw.profile?.nickname ?? "";
15
+ const firstName = raw.contact?.firstName ?? "";
16
+ const lastName = raw.contact?.lastName ?? "";
17
+ const loginEmail = raw.loginEmail ?? "";
18
+ const fullName = [firstName, lastName].filter(Boolean).join(" ");
19
+ return {
20
+ id: raw._id ?? "",
21
+ loginEmail,
22
+ displayName: nickname || fullName || loginEmail.split("@")[0] || "Member",
23
+ firstName,
24
+ lastName,
25
+ nickname,
26
+ photoUrl: imgSrc(raw.profile?.photo, 200, 200),
27
+ contactId: raw.contactId ?? "",
28
+ memberSince: raw._createdDate
29
+ ? new Date(raw._createdDate).toISOString().slice(0, 10)
30
+ : "",
31
+ };
32
+ }
33
+
34
+ /**
35
+ * The current member, or null for an anonymous visitor — and null for a LOGGED-IN member
36
+ * when the Members Area app isn't installed (setup, not a code bug; the seed installs it).
37
+ * Never throws: anonymous is a normal state for the client-side custom-login gate.
38
+ * ⚠️ The SDK export is getCurrentMember — the REST name "Get My Member" does not exist on
39
+ * the module; getMyMember(...) throws `is not a function`, and only once a real member
40
+ * loads the page.
41
+ */
42
+ export async function fetchCurrentMember(): Promise<CurrentMember | null> {
43
+ try {
44
+ const res = await membersApi.getCurrentMember({ fieldsets: ["FULL"] });
45
+ const raw = res.member as Raw | undefined;
46
+ return raw?._id ? toCurrentMember(raw) : null;
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
@@ -0,0 +1,21 @@
1
+ // Members DTOs — the serializable shapes every hook, component, and page consumes.
2
+ // Plain JSON: safe as Astro island props or across server/client boundaries. The photo is a
3
+ // resolved https URL.
4
+
5
+ /** The logged-in member as the header/account surfaces need it. */
6
+ export interface CurrentMember {
7
+ id: string;
8
+ /** Email the member logs in with ("" when the fieldset hides it). */
9
+ loginEmail: string;
10
+ /** Best display name: nickname → first+last → the login email's local part. */
11
+ displayName: string;
12
+ firstName: string;
13
+ lastName: string;
14
+ nickname: string;
15
+ /** Resolved https URL ("" when the member has no photo). */
16
+ photoUrl: string;
17
+ /** Contact-list id — the key for member-owned CMS/content lookups. */
18
+ contactId: string;
19
+ /** "YYYY-MM-DD" the membership was created ("" when unknown). */
20
+ memberSince: string;
21
+ }