@wix/agent-skills 1.15.1 → 1.16.1

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 (332) hide show
  1. package/README.md +3 -7
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +4 -1
  4. package/skills/wix-app/references/APP_TOOLS.md +134 -0
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +1 -1
  6. package/skills/wix-app/references/DASHBOARD_PAGE.md +0 -10
  7. package/skills/wix-app/references/DATA_COLLECTION.md +1 -1
  8. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +42 -8
  9. package/skills/wix-app/references/SERVICE_PLUGIN.md +12 -10
  10. package/skills/wix-app/references/app-tools/TOOLS.md +75 -0
  11. package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +2 -2
  12. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +172 -0
  13. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +143 -0
  14. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +23 -2
  15. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +29 -0
  16. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +1 -1
  17. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +60 -0
  18. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +27 -2
  19. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +5 -3
  20. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +24 -7
  21. package/skills/wix-app/references/editor-react-component/PARTS.md +15 -2
  22. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +2 -3
  23. package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +187 -0
  24. package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +13 -9
  25. package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +4 -0
  26. package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +4 -0
  27. package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +3 -1
  28. package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +4 -0
  29. package/skills/wix-app/references/service-plugin/TOOLS_PROVIDER.md +54 -0
  30. package/skills/wix-app/references/stores/QUERY.md +32 -0
  31. package/skills/wix-app/scripts/scan-a11y-code.cjs +777 -0
  32. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +201 -0
  33. package/skills/wix-docs/SKILL.md +35 -3
  34. package/skills/wix-headless/SKILL.md +3 -1
  35. package/skills/wix-headless/references/CAPABILITIES.md +16 -3
  36. package/skills/wix-headless/references/CONTENT.md +36 -0
  37. package/skills/wix-headless/references/DESIGN.md +54 -0
  38. package/skills/wix-headless/references/DISCOVERY.md +24 -0
  39. package/skills/wix-headless/references/IMAGE_GENERATION.md +10 -0
  40. package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
  41. package/skills/wix-headless/references/SEED.md +1 -1
  42. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +3 -2
  43. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +560 -102
  44. package/skills/wix-headless/references/inline-recipes/setup-forms.md +210 -143
  45. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +32 -23
  46. package/skills/wix-headless/references/managed/CONNECT.md +1 -1
  47. package/skills/wix-headless/references/managed/CREATE.md +14 -0
  48. package/skills/wix-headless/references/managed/DEPLOYMENT.md +25 -0
  49. package/skills/wix-manage/SKILL.md +130 -7
  50. package/skills/wix-manage/references/accessibility/scan-site-accessibility.md +98 -0
  51. package/skills/wix-manage/references/analytics/analytics-dashboard-navigation.md +40 -0
  52. package/skills/wix-manage/references/app-installation/app-installation-dashboard-navigation.md +28 -0
  53. package/skills/wix-manage/references/blog/blog-dashboard-navigation.md +56 -0
  54. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +31 -6
  55. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +3 -1
  56. package/skills/wix-manage/references/bookings/bookings-dashboard-navigation.md +63 -0
  57. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +10 -1
  58. package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +44 -0
  59. package/skills/wix-manage/references/cms/cms-data-items-crud.md +31 -3
  60. package/skills/wix-manage/references/cms/cms-publishing-flow.md +287 -0
  61. package/skills/wix-manage/references/cms/cms-schema-management.md +27 -1
  62. package/skills/wix-manage/references/contacts/contacts-dashboard-navigation.md +46 -0
  63. package/skills/wix-manage/references/contacts/create-a-contact.md +82 -0
  64. package/skills/wix-manage/references/contacts/update-a-contact.md +119 -0
  65. package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +82 -0
  66. package/skills/wix-manage/references/dashboard-navigation/routes.json +1733 -0
  67. package/skills/wix-manage/references/domains/domains-dashboard-navigation.md +32 -0
  68. package/skills/wix-manage/references/ecommerce/ecom-pricing.md +4 -4
  69. package/skills/wix-manage/references/ecommerce/ecom-shipping.md +1 -1
  70. package/skills/wix-manage/references/ecommerce/gift-cards/ecom-gift-cards-goal-sell-gift-cards.md +338 -0
  71. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-discount-rule.md +42 -78
  72. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-bundle-and-save.md +1 -1
  73. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-stock-mover.md +1 -1
  74. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-upsell-boost.md +1 -1
  75. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +90 -92
  76. package/skills/wix-manage/references/events/create-wix-event.md +176 -0
  77. package/skills/wix-manage/references/events/manage-wix-events.md +174 -0
  78. package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +44 -0
  79. package/skills/wix-manage/references/get-paid/get-paid-dashboard-navigation.md +52 -0
  80. package/skills/wix-manage/references/google-ads/billing-and-payment.md +80 -0
  81. package/skills/wix-manage/references/google-ads/create-performance-max-campaign.md +212 -0
  82. package/skills/wix-manage/references/google-ads/get-campaign-suggestions.md +110 -0
  83. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +25 -0
  84. package/skills/wix-manage/references/google-ads/install-and-create-account.md +155 -0
  85. package/skills/wix-manage/references/google-ads/manage-campaign-lifecycle.md +63 -0
  86. package/skills/wix-manage/references/google-ads/query-campaign-analytics.md +155 -0
  87. package/skills/wix-manage/references/marketing/marketing-dashboard-navigation.md +52 -0
  88. package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +99 -1
  89. package/skills/wix-manage/references/pricing-plans/pricing-plans-dashboard-navigation.md +45 -0
  90. package/skills/wix-manage/references/restaurants/restaurants-dashboard-navigation.md +68 -0
  91. package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +94 -125
  92. package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +48 -9
  93. package/skills/wix-manage/references/site-properties/site-properties-dashboard-navigation.md +31 -0
  94. package/skills/wix-manage/references/sites/create-headless-site.md +52 -0
  95. package/skills/wix-manage/references/sites/create-site-from-template.md +2 -25
  96. package/skills/wix-manage/references/sites/site-import.md +217 -192
  97. package/skills/wix-manage/references/sites/sites-dashboard-navigation.md +29 -0
  98. package/skills/wix-manage/references/stores/add-store-pages-to-site.md +17 -1
  99. package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +26 -8
  100. package/skills/wix-manage/references/stores/stores-dashboard-navigation.md +65 -0
  101. package/skills/wix-manage/references/stores/update-product-with-options.md +39 -7
  102. package/skills/wix-replatform/.publish-manifest.json +8 -0
  103. package/skills/wix-replatform/SKILL.md +693 -0
  104. package/skills/wix-replatform/lib/artifact-freshness.js +215 -0
  105. package/skills/wix-replatform/lib/completion-report.js +200 -0
  106. package/skills/wix-replatform/lib/config-env.js +59 -0
  107. package/skills/wix-replatform/lib/execution-manifest.js +185 -0
  108. package/skills/wix-replatform/lib/execution-state.js +173 -0
  109. package/skills/wix-replatform/lib/import-recovery.js +313 -0
  110. package/skills/wix-replatform/lib/local-state.js +642 -0
  111. package/skills/wix-replatform/lib/orchestration-preflight.js +143 -0
  112. package/skills/wix-replatform/lib/orchestration-router.js +122 -0
  113. package/skills/wix-replatform/lib/orchestration-state.js +455 -0
  114. package/skills/wix-replatform/lib/progress-log.js +224 -0
  115. package/skills/wix-replatform/lib/progress-log.sh +140 -0
  116. package/skills/wix-replatform/lib/url-preservation-state.js +391 -0
  117. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +184 -0
  118. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +529 -0
  119. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +316 -0
  120. package/skills/wix-replatform/resources/rp-execute-setup/scripts/mint-token.sh +64 -0
  121. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +1114 -0
  122. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +430 -0
  123. package/skills/wix-replatform/resources/rp-mapper/lib/mapping-resolve.js +217 -0
  124. package/skills/wix-replatform/resources/rp-mapper/scripts/resolve-mapping.js +148 -0
  125. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +378 -0
  126. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +183 -0
  127. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +478 -0
  128. package/skills/wix-replatform/resources/rp-source-csv/lib/canonical-record.js +136 -0
  129. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  130. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fingerprint.js +310 -0
  131. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-layout.js +1081 -0
  132. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-parse.js +618 -0
  133. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +949 -0
  134. package/skills/wix-replatform/resources/rp-source-csv/source-schema.example.json +196 -0
  135. package/skills/wix-replatform/resources/rp-source-csv/vendors/bigcommerce.json +66 -0
  136. package/skills/wix-replatform/resources/rp-source-csv/vendors/magento.json +60 -0
  137. package/skills/wix-replatform/resources/rp-source-csv/vendors/shopify.json +95 -0
  138. package/skills/wix-replatform/resources/rp-source-csv/vendors/woocommerce.json +82 -0
  139. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +256 -0
  140. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +249 -0
  141. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +444 -0
  142. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +774 -0
  143. package/skills/wix-replatform/resources/rp-source-wordpress/source-schema.example.json +71 -0
  144. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +632 -0
  145. package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +330 -0
  146. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +21 -0
  147. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -0
  148. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +37 -0
  149. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +37 -0
  150. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +39 -0
  151. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +35 -0
  152. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +14 -0
  153. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +35 -0
  154. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +36 -0
  155. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +35 -0
  156. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +14 -0
  157. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +131 -0
  158. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +37 -0
  159. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +37 -0
  160. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +21 -0
  161. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +37 -0
  162. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +37 -0
  163. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +97 -0
  164. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +528 -0
  165. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -0
  166. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +38 -0
  167. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +37 -0
  168. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -0
  169. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +37 -0
  170. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +53 -0
  171. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +84 -0
  172. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +25 -0
  173. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +37 -0
  174. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +37 -0
  175. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +38 -0
  176. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +37 -0
  177. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +90 -0
  178. package/skills/wix-replatform/resources/rp-target-wix/lib/audit-summary.js +64 -0
  179. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +141 -0
  180. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +384 -0
  181. package/skills/wix-replatform/resources/rp-target-wix/lib/ndjson.js +260 -0
  182. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +238 -0
  183. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +237 -0
  184. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +238 -0
  185. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +2219 -0
  186. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +31 -0
  187. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge.js +100 -0
  188. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +107 -0
  189. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +344 -0
  190. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +250 -0
  191. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1927 -0
  192. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +83 -0
  193. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +141 -0
  194. package/skills/wix-replatform/scripts/artifact-freshness.js +76 -0
  195. package/skills/wix-replatform/scripts/execution-manifest-validate.js +43 -0
  196. package/skills/wix-replatform/scripts/execution-state-prepare.js +128 -0
  197. package/skills/wix-replatform/scripts/orchestration-preflight.js +48 -0
  198. package/skills/wix-replatform/scripts/orchestration-route.js +46 -0
  199. package/skills/wix-replatform/scripts/orchestration-state.js +245 -0
  200. package/skills/wix-vibe-headless/SKILL.md +49 -25
  201. package/skills/wix-vibe-headless/install/deploy.cjs +156 -0
  202. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +34 -0
  203. package/skills/wix-vibe-headless/platforms/README.md +8 -4
  204. package/skills/wix-vibe-headless/platforms/base44.md +111 -101
  205. package/skills/wix-vibe-headless/platforms/generic.md +99 -64
  206. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +226 -119
  207. package/skills/wix-vibe-headless/references/blog/app/components/PostCard.jsx +43 -0
  208. package/skills/wix-vibe-headless/references/blog/app/components/PostChips.jsx +25 -0
  209. package/skills/wix-vibe-headless/references/blog/app/components/PostGrid.jsx +15 -0
  210. package/skills/wix-vibe-headless/references/blog/app/context/TaxonomyContext.jsx +35 -0
  211. package/skills/wix-vibe-headless/references/blog/app/hooks/usePostDetail.js +38 -0
  212. package/skills/wix-vibe-headless/references/blog/app/pages/Blog.jsx +40 -0
  213. package/skills/wix-vibe-headless/references/blog/app/pages/CategoryPage.jsx +54 -0
  214. package/skills/wix-vibe-headless/references/blog/app/pages/PostDetail.jsx +65 -0
  215. package/skills/wix-vibe-headless/references/blog/app/pages/TagPage.jsx +50 -0
  216. package/skills/wix-vibe-headless/references/blog/seed/SEED.md +103 -0
  217. package/skills/wix-vibe-headless/references/blog/seed/seed-blog.js +270 -0
  218. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +256 -149
  219. package/skills/wix-vibe-headless/references/bookings/app/components/BookingForm.jsx +65 -0
  220. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceCard.jsx +47 -0
  221. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceGrid.jsx +13 -0
  222. package/skills/wix-vibe-headless/references/bookings/app/components/SlotPicker.jsx +126 -0
  223. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +108 -0
  224. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServices.js +58 -0
  225. package/skills/wix-vibe-headless/references/bookings/app/lib/serviceFacts.js +95 -0
  226. package/skills/wix-vibe-headless/references/bookings/app/pages/ServiceDetail.jsx +94 -0
  227. package/skills/wix-vibe-headless/references/bookings/app/pages/Services.jsx +89 -0
  228. package/skills/wix-vibe-headless/references/bookings/{wix-bookings-checkout.js → app/rest/wix-bookings-checkout.js} +1 -1
  229. package/skills/wix-vibe-headless/references/bookings/{wix-bookings-services.js → app/rest/wix-bookings-services.js} +87 -11
  230. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +117 -0
  231. package/skills/wix-vibe-headless/references/bookings/seed/seed-bookings.js +333 -0
  232. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +168 -147
  233. package/skills/wix-vibe-headless/references/cms/app/collection.config.js +31 -0
  234. package/skills/wix-vibe-headless/references/cms/app/lib/wixImage.js +18 -0
  235. package/skills/wix-vibe-headless/references/cms/{wix-cms.js → app/rest/wix-cms.js} +47 -2
  236. package/skills/wix-vibe-headless/references/cms/seed/SEED.md +145 -0
  237. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +223 -131
  238. package/skills/wix-vibe-headless/references/events/app/components/CategoryFilter.jsx +23 -0
  239. package/skills/wix-vibe-headless/references/events/app/components/EventCard.jsx +43 -0
  240. package/skills/wix-vibe-headless/references/events/app/components/EventGrid.jsx +13 -0
  241. package/skills/wix-vibe-headless/references/events/app/components/EventRegistration.jsx +29 -0
  242. package/skills/wix-vibe-headless/references/events/app/components/RsvpForm.jsx +57 -0
  243. package/skills/wix-vibe-headless/references/events/app/components/TicketPicker.jsx +78 -0
  244. package/skills/wix-vibe-headless/references/events/app/hooks/useEventDetail.js +27 -0
  245. package/skills/wix-vibe-headless/references/events/app/hooks/useEventsList.js +54 -0
  246. package/skills/wix-vibe-headless/references/events/app/hooks/useRsvpForm.js +40 -0
  247. package/skills/wix-vibe-headless/references/events/app/hooks/useTicketing.js +81 -0
  248. package/skills/wix-vibe-headless/references/events/app/pages/EventDetail.jsx +48 -0
  249. package/skills/wix-vibe-headless/references/events/app/pages/Events.jsx +36 -0
  250. package/skills/wix-vibe-headless/references/events/{wix-events-browse.js → app/rest/wix-events-browse.js} +1 -1
  251. package/skills/wix-vibe-headless/references/events/seed/SEED.md +107 -0
  252. package/skills/wix-vibe-headless/references/events/seed/seed-events.js +251 -0
  253. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +272 -188
  254. package/skills/wix-vibe-headless/references/members/app/components/LoginForm.jsx +101 -0
  255. package/skills/wix-vibe-headless/references/members/app/components/MemberMenu.jsx +33 -0
  256. package/skills/wix-vibe-headless/references/members/app/components/RequireAuth.jsx +21 -0
  257. package/skills/wix-vibe-headless/references/members/app/components/SocialButtons.jsx +29 -0
  258. package/skills/wix-vibe-headless/references/members/app/context/MemberContext.jsx +54 -0
  259. package/skills/wix-vibe-headless/references/members/app/hooks/useLoginForm.js +77 -0
  260. package/skills/wix-vibe-headless/references/members/app/pages/Account.jsx +36 -0
  261. package/skills/wix-vibe-headless/references/members/app/pages/Callback.jsx +32 -0
  262. package/skills/wix-vibe-headless/references/members/app/pages/Login.jsx +35 -0
  263. package/skills/wix-vibe-headless/references/members/{wix-members-auth.js → app/rest/wix-members-auth.js} +6 -3
  264. package/skills/wix-vibe-headless/references/members/install/Register.jsx +22 -0
  265. package/skills/wix-vibe-headless/references/members/seed/SEED.md +22 -0
  266. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +229 -104
  267. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionCard.jsx +31 -0
  268. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionGrid.jsx +15 -0
  269. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectCard.jsx +39 -0
  270. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectGrid.jsx +15 -0
  271. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +29 -0
  272. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useCollectionProjects.js +35 -0
  273. package/skills/wix-vibe-headless/references/portfolio/app/hooks/usePortfolioGallery.js +27 -0
  274. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useProjectDetail.js +25 -0
  275. package/skills/wix-vibe-headless/references/portfolio/app/pages/CollectionPage.jsx +39 -0
  276. package/skills/wix-vibe-headless/references/portfolio/app/pages/Portfolio.jsx +27 -0
  277. package/skills/wix-vibe-headless/references/portfolio/app/pages/ProjectDetail.jsx +60 -0
  278. package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +94 -0
  279. package/skills/wix-vibe-headless/references/portfolio/seed/seed-portfolio.js +236 -0
  280. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +236 -117
  281. package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +35 -0
  282. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanCard.jsx +48 -0
  283. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanGrid.jsx +16 -0
  284. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanPrice.jsx +35 -0
  285. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/useMyPlans.js +25 -0
  286. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlanDetail.js +28 -0
  287. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlans.js +30 -0
  288. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/MyPlans.jsx +30 -0
  289. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/PlanDetail.jsx +53 -0
  290. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/Plans.jsx +28 -0
  291. package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +86 -0
  292. package/skills/wix-vibe-headless/references/pricing-plans/seed/seed-pricing-plans.js +251 -0
  293. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +244 -124
  294. package/skills/wix-vibe-headless/references/restaurants/app/components/ItemDialog.jsx +81 -0
  295. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuItemCard.jsx +71 -0
  296. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuList.jsx +43 -0
  297. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartButton.jsx +21 -0
  298. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +60 -0
  299. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +63 -0
  300. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useItemOrder.js +32 -0
  301. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useReservation.js +73 -0
  302. package/skills/wix-vibe-headless/references/restaurants/app/pages/Menu.jsx +28 -0
  303. package/skills/wix-vibe-headless/references/restaurants/app/pages/Reservations.jsx +102 -0
  304. package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +180 -0
  305. package/skills/wix-vibe-headless/references/restaurants/seed/seed-restaurants.js +452 -0
  306. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +56 -0
  307. package/skills/wix-vibe-headless/references/shared/{wix-client.js → app/rest/wix-client.js} +6 -8
  308. package/skills/wix-vibe-headless/references/shared/app/rest/wix-config.js +8 -0
  309. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +259 -157
  310. package/skills/wix-vibe-headless/references/storefront/app/components/CartButton.jsx +20 -0
  311. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +150 -0
  312. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +167 -0
  313. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +51 -0
  314. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +54 -0
  315. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +119 -0
  316. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +71 -0
  317. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +109 -0
  318. package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +98 -0
  319. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +27 -0
  320. package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +139 -0
  321. package/skills/wix-vibe-headless/references/storefront/app/pages/Shop.jsx +75 -0
  322. package/skills/wix-vibe-headless/references/storefront/{wix-store-cart.js → app/rest/wix-store-cart.js} +1 -1
  323. package/skills/wix-vibe-headless/references/storefront/{wix-store-catalog.js → app/rest/wix-store-catalog.js} +20 -1
  324. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +111 -0
  325. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +338 -0
  326. /package/skills/wix-vibe-headless/references/blog/{wix-blog.js → app/rest/wix-blog.js} +0 -0
  327. /package/skills/wix-vibe-headless/references/events/{wix-events-registration.js → app/rest/wix-events-registration.js} +0 -0
  328. /package/skills/wix-vibe-headless/references/portfolio/{wix-portfolio.js → app/rest/wix-portfolio.js} +0 -0
  329. /package/skills/wix-vibe-headless/references/pricing-plans/{wix-pricing-plans.js → app/rest/wix-pricing-plans.js} +0 -0
  330. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-menu.js → app/rest/wix-restaurants-menu.js} +0 -0
  331. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-ordering.js → app/rest/wix-restaurants-ordering.js} +0 -0
  332. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-reservations.js → app/rest/wix-restaurants-reservations.js} +0 -0
@@ -1,157 +1,264 @@
1
+ # Wix Bookings — ready-made client
1
2
 
2
- # Wix Bookings Skill
3
+ The bookings client is **shipped as real files**, not snippets to regenerate. It's a complete
4
+ service catalog + detail page + slot picker + booking flow (create booking → hosted checkout),
5
+ styled with your app's design tokens (base44's `src/index.css` — the shadcn palette the design phase
6
+ already set). Copy it into the app and wire the routes —
7
+ you generate almost none of the booking code (the `{ services }` / `{ slots }` destructuring, the
8
+ local wall-clock date args, the null-slot re-validate guard, the participant cap, the eCom
9
+ redirect-session all ship and are correct).
3
10
 
4
- > **Source files (in this skill):** the shared transport `references/shared/wix-client.js` and both bookings helpers from `references/bookings/`. All helpers import from `"./wix-client.js"`, so copy them into the same folder (e.g. `src/rest/`). Copy **both** for the full booking flow:
5
- >
6
- > | File | What it covers |
7
- > |---|---|
8
- > | `wix-bookings-services.js` | Service listing, slot availability, media URL helper |
9
- > | `wix-bookings-checkout.js` | Create booking, hosted checkout, bookAndCheckout convenience |
11
+ Talks to Wix directly over the public `WIX_CLIENT_ID` (anonymous visitor tokens). Never mock
12
+ services or slots; never hand-build a `/checkout` URL — the shipped flow creates the booking through
13
+ the API and completes it via the eCom redirect-session.
10
14
 
11
- Builds a real, client-only Wix Bookings front end. The browser talks to Wix directly over a
12
- public `WIX_CLIENT_ID`. Never mock services or slots; never hand-build a `/checkout` URL —
13
- always create the booking through the API and complete it via the eCom checkout + redirect-session.
15
+ ## Prerequisites
16
+ - The site's **Wix Bookings** setup is the read/book target. It's installed and seeded separately
17
+ (see **Seeding** below), in parallel with this build — so it may have no services at build time;
18
+ the client renders the shipped empty state until services (and staff/working hours, so slots are
19
+ bookable) land. This client is read-only over services — it does not provision them.
20
+ - The public headless **`WIX_CLIENT_ID`** from your prompt (buyer-facing, safe to hardcode/commit).
21
+ - For **paid** services, the site must accept payments and the deployed app domain must be
22
+ allow-listed on the OAuth client for the hosted checkout to return. Those are separate Wix setup
23
+ flows the user completes later — out of scope here; if checkout return fails before that, it's
24
+ expected, flag it and continue.
14
25
 
15
- This skill ships the single-service booking flow for **APPOINTMENT and CLASS** services: browse
16
- services → pick a service → pick an available slot → enter details → book → hosted checkout.
17
- Appointments and classes differ only in the availability call (`listAvailableSlots` vs
18
- `listEventTimeSlots`); `listSlotsForService` routes by `service.type`, and `createBooking` handles
19
- either slot. **COURSE (whole-course enrollment) is not covered** — see "Beyond the snippets".
26
+ ## STEP 1 — The client is already in `src/`
27
+ The install step (base44.md STEP 1) deployed the whole bookings UI client + REST scaffolds into
28
+ `src/` (imports use the `@/` alias → `src/`). Here's every file and what it is — **this is your map,
29
+ so you don't need to open them:**
20
30
 
21
- ## When to use
22
- - User wants a Wix Bookings appointment site or asks to "connect Wix Bookings".
23
- - Replacing placeholder/mock services or fake calendars with live Wix data.
24
- - Adding service listings, a slot picker, booking creation, or checkout over an existing
25
- Wix Bookings setup.
31
+ | file | what it is |
32
+ |---|---|
33
+ | `hooks/useServices.js` | services-list data — one page + `loadMore` paging, plus the category menu (`categories` / `activeCategory` / `setActiveCategory`); `total === 0` → empty state |
34
+ | `hooks/useServiceDetail.js` | detail + booking flow — load service, list slots, hold slot/contact/participants, re-validate + book + checkout |
35
+ | `lib/serviceFacts.js` | price / duration / capacity / where / reschedule labels, derived from a service — rateType-aware, so VARIED and NO_FEE services still show a price |
36
+ | `components/ServiceCard.jsx`, `ServiceGrid.jsx` | service listing UI (grid + card, with empty state); the card shows price, tagline and a `60 min · 1-to-1` meta row |
37
+ | `components/SlotPicker.jsx` | bookable-slot chips + paging (pure UI, driven by `useServiceDetail`) |
38
+ | `components/BookingForm.jsx` | contact + participant form (pure UI, driven by `useServiceDetail`) |
39
+ | `components/WixManageBanner.jsx` | preview-only manage banner — drop it into your Layout (STEP 3) |
40
+ | `pages/Services.jsx`, `pages/ServiceDetail.jsx` | the two shipped routes (`/services`, `/service/:serviceId`); the detail page is two-column — service + a duration/price/where strip on the left, the sticky booking panel on the right |
41
+ | `rest/wix-config.js` | the two ids, written by the install step |
42
+ | `rest/wix-client.js` | REST transport — mints/persists the anonymous visitor token |
43
+ | `rest/wix-bookings-services.js` | services + availability: `queryServices`, `queryServicesByCategory`, `categoriesOf`, `getService`, `countServices`, `listSlotsForService`, `listAvailableSlots`, `listEventTimeSlots`, `getAvailableSlot`, `mediaUrl` |
44
+ | `rest/wix-bookings-checkout.js` | booking + checkout: `createBooking`, `checkoutBooking`, `bookAndCheckout` |
26
45
 
27
- ## Prerequisites
28
- 1. A Wix site with **Wix Bookings installed and at least one appointment service created**
29
- (this skill does NOT provision — it's read-only over services). Staff/resources and a
30
- booking policy should be configured so slots are bookable.
31
- 2. The site's public headless **`WIX_CLIENT_ID`**, provided in the handoff prompt (the Wix
32
- Business Manager surfaces a copyable prompt with the id filled in — see the router `SKILL.md`). Paste
33
- it into `src/rest/wix-client.js` in place of the placeholder. It is a buyer-facing credential
34
- (it only mints anonymous visitor tokens), **not** a secret, so hardcoding/committing it is fine.
35
- 3. The site must **accept payments** for paid services, and the deployed app domain must be
36
- allow-listed on the OAuth client for Wix-hosted checkout to return. These are **separate Wix
37
- setup flows the user completes later** — out of this skill's scope. If checkout return fails
38
- before that setup is done, that's expected; flag it and continue.
39
-
40
- ## The API (copy as-is; do not re-derive it)
41
- This skill ships only the REST layer — no UI components. Build the booking UI however the
42
- project wants; wire it to these two snippets. Copy them into the app (e.g. `src/api/`) and only
43
- adjust import paths:
44
- - `src/rest/wix-client.js` — visitor-token mint/refresh + transport. Set `WIX_CLIENT_ID` to the
45
- id from the prompt (replace the `<YOUR-CLIENT-ID>` placeholder). The visitor refresh token IS
46
- the booking visitor identity; it is persisted to localStorage. Do not re-mint anonymously per
47
- load.
48
- - `src/rest/wix-bookings-services.js` — **Services & availability:**
49
- `queryServices`, `getService`, `countServices`, `listAvailableSlots`, `getAvailableSlot`,
50
- `mediaUrl` (resolve a service image to an absolute URL)
51
- - `src/rest/wix-bookings-checkout.js` — **Booking & checkout:**
52
- `createBooking`, `checkoutBooking`, `bookAndCheckout`
53
-
54
- The `Service`, `TimeSlot`, and `Booking` shapes are documented as JSDoc comments at the top of
55
- each helper file. Read them before building the UI — they describe the key fields and link to
56
- the full API reference for anything not shown.
57
-
58
- ## How to wire it (UI is the project's choice)
59
- - **Service list** — `queryServices()` for the listing (visitor-visible services only). Render
60
- `name`, `tagLine`, the image via `mediaUrl(service.media?.items?.[0]?.image)`, and the price
61
- from `payment.fixed.price`. `value` + `currency` are always present; `formattedValue` is
62
- **optional** (it may be missing), so don't depend on it — build the price from `value`+`currency`
63
- and use `formattedValue` only when present. e.g. `new Intl.NumberFormat(undefined, { style:
64
- 'currency', currency }).format(Number(value))`. (Rendering `formattedValue` alone leaves the price
65
- blank — or your "Varies" fallback — whenever it's absent.) Pass the returned
66
- `nextOffset` back as `offset` to load the next page. Books **APPOINTMENT and CLASS** services
67
- (see the slot picker below); COURSE is whole-course enrollment and out of scope.
68
- - **Service detail** — `getService(serviceId)` keyed off the URL/route; returns null on miss —
69
- show a not-found state, never invent a service. Render `description`, price, and `locations`.
70
- - **Slot picker** — use **`listSlotsForService(service, { fromLocalDate, toLocalDate, timeZone? })`**:
71
- it routes by `service.type` — APPOINTMENT → `listAvailableSlots` (staff working hours), CLASS/COURSE
72
- → `listEventTimeSlots` (scheduled sessions). Both return the same slot shape. (Call the specific
73
- function directly if you already know the type.) Dates are **local** wall-clock strings
74
- `"YYYY-MM-DDThh:mm:ss"` (no zone), interpreted in `timeZone` (defaults to the visitor's IANA zone).
75
- Only `bookable: true` slots come back. Render each `slot.localStartDate`/`localEndDate`; group by
76
- day for a calendar. Pass `nextCursor` back
77
- as `cursor` to page.
78
- - **Booking form** — collect the buyer's `firstName`, `lastName`, `email`, `phone`. Keep it
79
- minimal; richer per-service form fields live in the service's `form.id` (see "Beyond the snippets").
80
- - **Participant count** — cap it by the service policy, not just slot capacity. The most a single
81
- booking may reserve is `service.bookingPolicy.participantsPolicy.maxParticipantsPerBooking`. Only
82
- render a participant selector when that value is `> 1`, and bound its max at
83
- `min(maxParticipantsPerBooking, slot.remainingCapacity)` for a class; when it is `1` (the common
84
- case) show no selector and book exactly one. Never offer a fixed range like 1–4 — the slot's
85
- `remainingCapacity` tells you the class's open spots, not how many one buyer may take, so relying
86
- on it alone lets the buyer pick a count that `createBooking` then rejects. Pass the chosen count
87
- as `createBooking`'s `totalParticipants`.
88
- - **Re-validate + book** — right before submitting, call
89
- `getAvailableSlot(serviceId, { localStartDate, localEndDate, timeZone? })` to confirm the slot
90
- is still open (and to pick up the staff resource). Then create + check out in one step:
91
- `window.location.href = (await bookAndCheckout(slot, { email, firstName, lastName, phone })).checkoutUrl;`
92
- Or split it: `const booking = await createBooking(slot, contact); const url = await checkoutBooking(booking.id);`
93
- - **Confirmation / return** — after the buyer returns from hosted checkout, the order is placed
94
- and Wix Bookings confirms the booking automatically (status becomes `CONFIRMED`, or `PENDING`
95
- if the service needs manual approval). Show a confirmation screen on return.
96
- - **Empty state** — if `countServices()` is 0, show an empty state telling the user to add a
97
- service in their Wix dashboard. Never invent services.
98
-
99
- ## Hard rules (do not violate)
100
- - ✅ Book ONLY via `createBooking()` → `checkoutBooking()` (or `bookAndCheckout()`), then redirect
101
- to the returned `fullUrl`.
102
- - ❌ Never hand-build a `/checkout`, booking, or calendar URL.
103
- - ❌ Never mock services, time slots, or availability — render live Wix data or the empty state.
104
- - ❌ Never invent reviews, ratings, staff, or testimonials. Empty review UI only.
105
- - ✅ Set `WIX_CLIENT_ID` from the prompt's value (public client id — safe to hardcode).
106
- - ✅ Send availability/booking dates as **local** `"YYYY-MM-DDThh:mm:ss"` strings plus a
107
- `timeZone` — do not send UTC `Z` timestamps to the slot APIs.
108
- - ✅ Re-validate the slot with `getAvailableSlot()` before `createBooking()` — slots get taken.
109
- - ✅ Cap participant count at `service.bookingPolicy.participantsPolicy.maxParticipantsPerBooking`
110
- (render no selector when it is 1); never offer a fixed range and never use slot capacity as the
111
- per-buyer limit — a count above the policy makes `createBooking` fail.
112
- - The client fails loudly on purpose: `createBooking`/`checkoutBooking` throw on an unbookable
113
- slot, a missing booking id, or a missing redirect URL. A green path means it's really bookable —
114
- don't swallow these.
115
-
116
- ## Beyond the snippets
117
- The snippets cover **APPOINTMENT and CLASS** bookings (the slot picker routes by `service.type`).
118
- For anything beyond that, extend the client: add a new helper on `wixApiRequest`, looking up the
119
- exact endpoint, method, and body in the **official Wix API reference** first (never guess):
120
- - Official Wix API reference: https://dev.wix.com/docs/api-reference.md
121
- - Single-service booking flow (the full picture): https://dev.wix.com/docs/api-reference/business-solutions/bookings/flow-single-service-booking.md
122
- - **Courses are NOT covered — a course is enrolled as a *whole*, not booked per session.**
123
- `listEventTimeSlots` returns **no** per-session slots for a COURSE (verified — empty even for admin),
124
- so the slot-picker flow doesn't apply. Enrolling in a course uses a course-specific flow (whole-course
125
- capacity computed from bookings) that these snippets don't implement —
126
- https://dev.wix.com/docs/api-reference/business-solutions/bookings/bookings/bookings-reader-v2/query-extended-bookings.md
127
- - **Service variants / participants** (duration- or person-based pricing):
128
- https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/service-options-and-variants/get-service-options-and-variants-by-service-id.md
129
- - **Add-ons:** https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/list-add-on-groups-by-service-id.md
130
- - **Custom booking form fields** (render `service.form.id`): Get Form Summary —
131
- https://dev.wix.com/docs/rest/crm/forms/form-schemas/get-form-summary.md
132
- - **Member login + a "my bookings" account view** → the **members** vertical
133
- (`references/members/INSTRUCTIONS.md`): booking itself works anonymously, but signing a member in
134
- (custom login on your own UI) lets them see their own appointments/history.
135
-
136
- Keep the snippets as the default for everything they already do; reach for the API reference
137
- only for the gap.
46
+ They're already in place — go **straight to theming + wiring**, nothing to verify first. **Don't
47
+ `read_file` the shipped page/component/hook source to inspect it** — the table above says what each
48
+ is, and every field shape you need is in the snippets below. Read a shipped file's source **only**
49
+ on a real fallback — a runtime error, or a field the snippets don't cover (see "Fallback only" at
50
+ the end). (Files missing? the install's `deploy` result lists what it wrote; re-run install, or copy
51
+ `references/bookings/app/` → `src/`.)
52
+
53
+
54
+ ## STEP 2 — Theme (nothing to style on the shipped components)
55
+ The shipped components carry **no palette of their own** — they render from base44's design tokens
56
+ in `src/index.css` (`:root`/`.dark`: `--background`, `--foreground`, `--card`, `--primary`,
57
+ `--muted`, `--border`, `--radius`, `--font-*`) via shadcn Tailwind classes (`bg-card`,
58
+ `text-foreground`, `bg-primary`, `text-muted-foreground`, `border-border`, `rounded-lg`,
59
+ `font-display`). Those tokens are **already set to the brand by the design phase**, so the shipped
60
+ pages are themed with zero work here. To adjust the palette, edit `index.css` (`:root` **and**
61
+ `.dark`) — the base44 way; **never add a parallel theme file (e.g. a `theme.css`) or restyle the
62
+ shipped JSX.** Build the Home/Header you add (STEP 3) from the **same** base44 tokens/classes so it
63
+ matches automatically. A dark brand is just base44's dark palette in `index.css` — no per-component work.
64
+
65
+ ## STEP 3 — Wire routes (surgical `find_replace` on `src/App.jsx`, never a rewrite)
66
+ **No file reads needed to wire this.** Every shipped page and `WixManageBanner` is a default export that takes **no props** — wire them exactly as the snippet shows; nothing in those files needs looking up.
67
+ `App.jsx` carries required platform auth scaffolding (`AuthProvider`/`useAuth`) — edit it in, don't
68
+ replace it. Bookings needs **no cross-page provider** (there's no cart — each booking completes on
69
+ its own detail page), so there's nothing to wrap the tree in.
70
+ - Put your **header + footer in a `Layout`** that renders `<Outlet/>` between them, and nest every
71
+ route under one pathless `<Route element={<Layout/>}>`. Your brand chrome then wraps **every** page
72
+ — including the shipped `Services` / `ServiceDetail` — so you **never edit the shipped pages to add
73
+ a header/footer** (they render inside `<Outlet/>` as-is).
74
+ - **Pin the top chrome as one fixed block.** Put `<WixManageBanner/>` (shipped, preview-only) **above**
75
+ your `<Header/>` inside a single `position:fixed` top region — the header itself is plain in-flow
76
+ markup, the region owns the fixing — so banner + header ride together (no scroll drift/gap). Pad
77
+ the content by the region's **ResizeObserver-measured** height so it clears the chrome and
78
+ self-corrects when the banner is dismissed.
79
+ - Routes under the Layout: `/services` → `Services`, `/service/:serviceId` → `ServiceDetail` (both
80
+ shipped, as-is). **You add `/` → your own Home** page.
81
+
82
+ ```jsx
83
+ import { useRef, useState, useEffect } from "react";
84
+ import { Routes, Route, Outlet } from "react-router-dom";
85
+ import WixManageBanner from "@/components/WixManageBanner"; // shipped, preview-only · default export, no props
86
+ import Services from "@/pages/Services"; // shipped · default export, no props
87
+ import ServiceDetail from "@/pages/ServiceDetail"; // shipped · default export, no props
88
+ import Home from "@/pages/Home"; // YOU build
89
+ import Header from "@/components/Header"; // YOU build — plain in-flow markup, NOT position:fixed
90
+ import Footer from "@/components/Footer"; // YOU build
91
+
92
+ function Layout() {
93
+ const topRef = useRef(null);
94
+ const [offset, setOffset] = useState(0);
95
+ useEffect(() => { // measure the fixed region → pad content below it
96
+ const ro = new ResizeObserver(() => setOffset(topRef.current?.offsetHeight ?? 0));
97
+ if (topRef.current) ro.observe(topRef.current);
98
+ return () => ro.disconnect();
99
+ }, []);
100
+ return (<>
101
+ <div ref={topRef} style={{ position: "fixed", top: 0, left: 0, right: 0, zIndex: 50 }}>
102
+ <WixManageBanner /> {/* null on the published site / when dismissed */}
103
+ <Header /> {/* your brand header, in-flow inside this fixed block */}
104
+ </div>
105
+ <div style={{ paddingTop: offset }}> {/* clears the chrome; shrinks when the banner is dismissed */}
106
+ <Outlet /> {/* shipped Services/ServiceDetail render here, untouched */}
107
+ <Footer />
108
+ </div>
109
+ </>);
110
+ }
111
+
112
+ <Routes>
113
+ <Route element={<Layout />}> {/* chrome wraps all */}
114
+ <Route path="/" element={<Home />} /> {/* yours */}
115
+ <Route path="/services" element={<Services />} /> {/* shipped, as-is */}
116
+ <Route path="/service/:serviceId" element={<ServiceDetail />} /> {/* shipped, as-is */}
117
+ </Route>
118
+ </Routes>
119
+ ```
120
+
121
+ ## What you build (not shipped)
122
+ The **home / landing page**, the **`Header`** and a **`Footer`** — the two you drop into the
123
+ `Layout` (STEP 3) so they wrap every route — plus the overall brand story, styled with the same
124
+ base44 tokens/classes. **Compose the shipped pieces** — a "featured services" strip is just
125
+ `queryServices` + the shipped `ServiceGrid`; the nav is a link to `/services`:
126
+
127
+ ```jsx
128
+ import { useState, useEffect } from "react";
129
+ import { Link } from "react-router-dom";
130
+ import { queryServices } from "@/rest/wix-bookings-services";
131
+ import ServiceGrid from "@/components/ServiceGrid";
132
+
133
+ // Responsive header: choose ONE branch with a state flag (copy this pattern). Do NOT render a
134
+ // desktop nav AND a mobile nav toggled by Tailwind `hidden md:flex` / `md:hidden`: these navs are
135
+ // inline-styled, and an inline `display` beats a Tailwind class, so `hidden` never applies — BOTH
136
+ // branches render. One branch = one nav.
137
+ export function Header() {
138
+ const [mobile, setMobile] = useState(() => window.innerWidth < 768);
139
+ useEffect(() => {
140
+ const onResize = () => setMobile(window.innerWidth < 768);
141
+ window.addEventListener("resize", onResize); // keep it reactive to viewport changes
142
+ return () => window.removeEventListener("resize", onResize);
143
+ }, []);
144
+ return (
145
+ <nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
146
+ {/* brand/logo */}
147
+ {mobile ? <YourMenu /> : <Link to="/services">Services</Link>}
148
+ </nav>
149
+ );
150
+ }
151
+ export function Featured() { // on your home page
152
+ const [services, setServices] = useState([]);
153
+ // NB: queryServices returns { services, total, nextOffset } — destructure the array.
154
+ useEffect(() => { queryServices({ limit: 6 }).then(({ services }) => setServices(services)); }, []);
155
+ return <ServiceGrid services={services} empty="Services coming soon." />;
156
+ }
157
+ ```
158
+ Everything reads base44's design tokens (`index.css`), so your home/nav match the shipped pages automatically.
159
+
160
+ **Editing a component and the change doesn't show? It's the preview, not your code.** The dev
161
+ preview can serve a stale module after a write. Before diagnosing a visual bug you just "fixed", do a
162
+ fresh full navigate/reload of the preview and re-check — don't keep rewriting correct code against a
163
+ stale render.
164
+
165
+ ## Using the client from your own UI
166
+ The two shipped hooks are the whole flow. If you build a custom surface, drive it the same way:
167
+
168
+ ```jsx
169
+ // LIST — every list helper returns an OBJECT, not a bare array. Destructure it:
170
+ const { services, total, nextOffset } = await queryServices({ limit: 24 }); // total 0 → empty state
171
+ if ((await countServices()) === 0) { /* show the empty state — never invent services */ }
172
+
173
+ // DETAIL — getService(id) is keyed off the route param; returns null on a miss (not-found, never invent):
174
+ const service = await getService(serviceId);
175
+
176
+ // FACTS (price / duration / capacity / where / reschedule note) — lib/serviceFacts.js branches on
177
+ // payment.rateType and on APPOINTMENT-vs-CLASS for you. Reading payment.fixed.price yourself renders
178
+ // NOTHING for a VARIED or NO_FEE service, and duration is empty on a class:
179
+ const price = servicePriceLabel(service); // "€95.00" · "From €85.00" · "Free" · "" for CUSTOM
180
+ const minutes = serviceDuration(service); // 60 for an appointment; null for a class/course
181
+ const where = serviceLocationLabel(service); // from payment.options — service.locations has no name
182
+
183
+ // IMAGE — the primary image is media.mainMedia; resolve through mediaUrl (Wix media can be a bare
184
+ // handle, not a full URL). Fall back to the gallery/cover:
185
+ const img = mediaUrl(service.media?.mainMedia?.image ?? service.media?.items?.[0]?.image ?? service.media?.coverMedia?.image);
186
+
187
+ // SLOTS — listSlotsForService routes by service.type and returns { slots, nextCursor }; iterate .slots.
188
+ // Dates are LOCAL wall-clock "YYYY-MM-DDThh:mm:ss" (NO zone / Z). The LIST call takes
189
+ // fromLocalDate/toLocalDate — the single-slot re-validate (getAvailableSlot) takes
190
+ // localStartDate/localEndDate. They are NOT interchangeable.
191
+ // It also returns `timeZone` — the zone those localStartDate strings are in. Label the picker with
192
+ // that value rather than a locally guessed zone, so the times and the label can't disagree.
193
+ const { slots, nextCursor, timeZone } = await listSlotsForService(service, { fromLocalDate, toLocalDate });
194
+
195
+ // BOOK — re-validate the picked slot (getAvailableSlot returns the slot or NULL — guard it), then
196
+ // book + check out and redirect. Participants: cap at
197
+ // service.bookingPolicy.participantsPolicy.maxParticipantsPerBooking (commonly 1 → no selector);
198
+ // never use slot.remainingCapacity as the per-buyer limit.
199
+ const fresh = await getAvailableSlot(service.id, { localStartDate, localEndDate });
200
+ if (!fresh) { /* "that time was just taken — pick another" */ }
201
+ const { checkoutUrl } = await bookAndCheckout(fresh, { email, firstName, lastName, phone }, { totalParticipants });
202
+ window.location.href = checkoutUrl; // hosted checkout; on return the booking is CONFIRMED/PENDING
203
+ ```
204
+
205
+ ## Extending the client
206
+ The shipped flow covers **APPOINTMENT and CLASS** services (`listSlotsForService` routes by
207
+ `service.type`). For anything beyond that, add a helper on `wixApiRequest`, looking the endpoint up
208
+ in the **`wix-docs`** skill first (never guess):
209
+ - **COURSE** enrollment — a course is enrolled as a *whole*, not per session; `listEventTimeSlots`
210
+ returns no slots for it, so the slot-picker flow doesn't apply (course-specific flow).
211
+ - **Service variants / participants** (duration- or person-based pricing), **add-ons**, and
212
+ **custom booking form fields** (render `service.form.id`).
213
+ - **Member login + a "my bookings" view** → the **members** vertical
214
+ (`references/members/INSTRUCTIONS.md`): booking works anonymously, but signing a member in lets
215
+ them see their own appointments.
216
+
217
+ Fallback only — when you hit an error or need something not shown here: read the relevant shipped
218
+ file under `src/`, or look it up via the **`wix-docs`** skill. Each helper in
219
+ `wix-bookings-services.js` / `wix-bookings-checkout.js` links its own reference page inline; these are
220
+ the areas they sit in:
221
+ - Bookings (services, categories, bookings): https://dev.wix.com/docs/api-reference/business-solutions/bookings.md
222
+ - Availability time slots: https://dev.wix.com/docs/api-reference/business-solutions/bookings/time-slots.md
223
+ - eCommerce checkout (paid bookings): https://dev.wix.com/docs/api-reference/business-solutions/e-commerce.md
224
+ - Headless redirect session (hosted checkout): https://dev.wix.com/docs/api-reference/business-management/headless/redirects.md
225
+
226
+ ## Hard rules
227
+ - Style via base44 design tokens (`index.css` / shadcn Tailwind classes), never by rewriting the shipped components or adding a parallel theme file.
228
+ - Header/footer live in a `Layout` around `<Outlet/>` (STEP 3) — never edit the shipped
229
+ `Services`/`ServiceDetail` to add chrome.
230
+ - The Layout's fixed top region owns positioning: `<WixManageBanner/>` above `<Header/>`; your
231
+ `Header` is plain in-flow markup (not `position:fixed`).
232
+ - Send availability/booking dates as **local** `"YYYY-MM-DDThh:mm:ss"` strings + a `timeZone` — never
233
+ UTC `Z` timestamps to the slot APIs.
234
+ - Re-validate the slot with `getAvailableSlot()` before booking; guard the `null` — slots get taken.
235
+ - Cap participants at `maxParticipantsPerBooking` (no selector when 1); never offer a fixed range and
236
+ never use slot capacity as the per-buyer limit.
237
+ - Book only through the shipped flow (`bookAndCheckout` / `createBooking`→`checkoutBooking`) and
238
+ redirect to the returned URL — never a hand-built `/checkout` or calendar URL.
239
+ - Render live Wix data or the shipped empty state — never mock services, slots, or availability, and
240
+ never invent reviews, ratings, staff, or testimonials.
138
241
 
139
242
  ## Point the user to their dashboard
140
- In some cases, users need to access the Wix dashboard in order to edit the bookings content for their site. To facilitate this, provide the user with deep links directly to the relevant dashboard pages. For bookings data those pages are:
141
- - **Booking Services** — `https://manage.wix.com/dashboard/{metaSiteId}/bookings/services` (`Dashboard → Bookings → Booking Services`; add services and service categories)
142
- - **Staff** — `https://manage.wix.com/dashboard/{metaSiteId}/bookings/staff` (`Dashboard → Bookings → Staff`; add staff and set working hours, so slots are actually bookable)
143
-
144
- Substitute the site's `metaSiteId` to complete the links (you have it from the handoff / `ListWixSites`). Include the in-dashboard navigation as a fallback.
145
-
146
- ## Verification checklist (before declaring done)
147
- - [ ] `WIX_CLIENT_ID` set to the prompt's value (not the `<YOUR-CLIENT-ID>` placeholder)
148
- - [ ] Visitor token persists across reload (same visitor identity across reloads)
149
- - [ ] `queryServices()` renders live services; `countServices()` 0 → empty state (no mock services)
150
- - [ ] `listAvailableSlots()` returns real bookable slots for a chosen service and date range
151
- - [ ] Slot is re-validated with `getAvailableSlot()` immediately before booking
152
- - [ ] Participant selector capped by `maxParticipantsPerBooking` (hidden when 1) — a count above the policy is not offerable
153
- - [ ] `createBooking()` returns a booking with `status: "CREATED"` and a real id
154
- - [ ] Checkout redirects via redirect-session `fullUrl` (no hand-built URL)
155
- - [ ] On return from checkout the booking is confirmed (status `CONFIRMED`/`PENDING`)
156
- - [ ] No mock services, slots, or availability anywhere
157
- - [ ] Told the user at least once that they can continue setting up their bookings in the dashboard and provided deep links.
243
+ Provide deep links so the owner can manage bookings content (substitute the site's `metaSiteId`):
244
+ - **Booking Services** — `https://manage.wix.com/dashboard/{metaSiteId}/bookings/services` (add
245
+ services and service categories)
246
+ - **Staff** — `https://manage.wix.com/dashboard/{metaSiteId}/bookings/staff` (add staff and set
247
+ working hours, so slots are actually bookable)
248
+
249
+ ## Seeding
250
+ Seed the services per `seed/SEED.md` (the build-time setup module) — separate from this client
251
+ build; run in parallel.
252
+
253
+ ## Verify (before declaring done)
254
+ - [ ] Client files copied into `src/`; `WIX_CLIENT_ID` set (not the placeholder).
255
+ - [ ] Brand palette lives in `index.css` (`:root`/`.dark`); no parallel theme file; shipped components/pages not restyled or rewritten.
256
+ - [ ] **Opened `/services` and a service detail page** (not just the home page) and confirmed the shipped cards render themed (surface, text, brand color) with images.
257
+ - [ ] `Layout` (fixed `<WixManageBanner/>` + `<Header/>` region, then `<Outlet/>` + Footer) wraps all
258
+ routes; shipped `Services`/`ServiceDetail` untouched; content clears the fixed chrome.
259
+ - [ ] Visitor token persists across reload (same visitor identity across reloads).
260
+ - [ ] `queryServices()` renders live services; empty catalog shows the shipped empty state (no mock services).
261
+ - [ ] Slot picker shows real bookable slots; the slot is re-validated with `getAvailableSlot()` right before booking.
262
+ - [ ] Participant selector capped by `maxParticipantsPerBooking` (hidden when 1).
263
+ - [ ] Booking redirects to the hosted checkout URL the client returns; on return the booking is CONFIRMED/PENDING.
264
+ - [ ] No mock services, slots, or availability anywhere.
@@ -0,0 +1,65 @@
1
+ // Contact + participants form — pure UI. All state/handlers (field setters, participant cap,
2
+ // submit, submitting, error) come from useServiceDetail; this only renders them. The participant
3
+ // selector shows ONLY when maxParticipants > 1 (commonly 1 → no selector, book exactly one).
4
+ // Styled with base44 design tokens (shadcn Tailwind classes).
5
+ const fieldCls =
6
+ "w-full px-3 py-2.5 box-border font-body border border-input rounded-sm bg-background text-foreground";
7
+ const labelCls = "block mb-1.5 text-[11px] uppercase tracking-wide text-muted-foreground";
8
+
9
+ export default function BookingForm({
10
+ contact, setContactField, maxParticipants, participants, setParticipants,
11
+ onSubmit, submitting, canSubmit, error, needsApproval, timeLabel, priceLabel,
12
+ }) {
13
+ // Naming the time and price on the button is the last confirmation before payment, so what the
14
+ // buyer clicks states exactly what they're committing to.
15
+ const what = [timeLabel, priceLabel].filter(Boolean).join(" · ");
16
+ return (
17
+ <form onSubmit={(e) => { e.preventDefault(); onSubmit(); }} className="flex flex-col gap-4">
18
+ <div className="flex gap-3">
19
+ <div className="flex-1">
20
+ <label className={labelCls} htmlFor="bk-first">First name</label>
21
+ <input id="bk-first" className={fieldCls} value={contact.firstName} onChange={setContactField("firstName")} />
22
+ </div>
23
+ <div className="flex-1">
24
+ <label className={labelCls} htmlFor="bk-last">Last name</label>
25
+ <input id="bk-last" className={fieldCls} value={contact.lastName} onChange={setContactField("lastName")} />
26
+ </div>
27
+ </div>
28
+
29
+ <div>
30
+ <label className={labelCls} htmlFor="bk-email">Email</label>
31
+ <input id="bk-email" required type="email" autoComplete="email" placeholder="you@example.com"
32
+ className={fieldCls} value={contact.email} onChange={setContactField("email")} />
33
+ </div>
34
+
35
+ <div>
36
+ <label className={labelCls} htmlFor="bk-phone">
37
+ Phone <span className="normal-case tracking-normal">optional</span>
38
+ </label>
39
+ <input id="bk-phone" type="tel" autoComplete="tel" className={fieldCls}
40
+ value={contact.phone} onChange={setContactField("phone")} />
41
+ </div>
42
+
43
+ {maxParticipants > 1 && (
44
+ <div>
45
+ <label className={labelCls} htmlFor="bk-participants">Participants</label>
46
+ <input id="bk-participants" type="number" min={1} max={maxParticipants} value={participants}
47
+ onChange={(e) => setParticipants(Math.max(1, Math.min(maxParticipants, Number(e.target.value) || 1)))}
48
+ className={`${fieldCls} w-[100px]`} />
49
+ </div>
50
+ )}
51
+
52
+ {error && <p role="alert" className="m-0 text-destructive text-sm">{error}</p>}
53
+
54
+ {/* The business confirms a manual-approval service after the fact, so this asks rather than books. */}
55
+ <button type="submit" disabled={!canSubmit}
56
+ className="px-6 py-3 cursor-pointer bg-primary text-primary-foreground border-none rounded-sm text-[15px] font-semibold disabled:opacity-50 disabled:cursor-not-allowed">
57
+ {submitting
58
+ ? (needsApproval ? "Requesting…" : "Booking…")
59
+ : needsApproval
60
+ ? (what ? `Request ${what}` : "Request appointment")
61
+ : (what ? `Book ${what}` : "Book appointment")}
62
+ </button>
63
+ </form>
64
+ );
65
+ }
@@ -0,0 +1,47 @@
1
+ // Grid tile for one bookable service. Styled with base44 design tokens (shadcn Tailwind classes:
2
+ // bg-card / text-foreground / border-border / text-primary) — re-skin via the app's design tokens
3
+ // (src/index.css :root/.dark), not this JSX. Load-bearing: the image goes through mediaUrl() (Wix
4
+ // media can be a bare handle), the link uses `service.id`, and every price/duration/capacity label
5
+ // comes from lib/serviceFacts.js so the card and the detail page can't disagree.
6
+ import { Link } from "react-router-dom";
7
+ import { mediaUrl } from "@/rest/wix-bookings-services";
8
+ import { serviceCapacityLabel, serviceDuration, servicePriceLabel } from "@/lib/serviceFacts";
9
+
10
+ export default function ServiceCard({ service }) {
11
+ const image = mediaUrl(service.media?.mainMedia?.image ?? service.media?.items?.[0]?.image ?? service.media?.coverMedia?.image);
12
+ const price = servicePriceLabel(service);
13
+ const minutes = serviceDuration(service);
14
+ // A class has no duration on the service, so its meta row carries capacity alone rather than a gap.
15
+ const facts = [minutes && `${minutes} min`, serviceCapacityLabel(service)].filter(Boolean);
16
+
17
+ return (
18
+ <Link to={`/service/${service.id}`}
19
+ className="group flex flex-col no-underline text-foreground bg-card border border-border rounded-lg overflow-hidden shadow-sm">
20
+ <div className="relative aspect-[4/3] bg-background overflow-hidden">
21
+ {image
22
+ ? <img src={image} alt={service.name} loading="lazy"
23
+ className="w-full h-full object-cover transition-transform duration-300 md:group-hover:scale-[1.03]" />
24
+ : <div className="w-full h-full bg-muted flex items-center justify-center" aria-hidden="true"><svg viewBox="0 0 24 24" className="w-8 h-8 text-muted-foreground/40" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="3" width="18" height="18" rx="2" /><circle cx="8.5" cy="8.5" r="1.5" /><path d="m21 15-5-5L5 21" /></svg></div>}
25
+ </div>
26
+
27
+ <div className="p-3 flex flex-col gap-1">
28
+ {/* Name and price share a row on a wide tile and stack on a phone's narrow one, where a long
29
+ name against a top-right price wraps into a ragged block. */}
30
+ <div className="flex flex-col gap-1 md:flex-row md:items-baseline md:justify-between md:gap-3">
31
+ <h3 className="m-0 font-display text-[15px] font-semibold line-clamp-2">{service.name}</h3>
32
+ {price && <span className="font-semibold whitespace-nowrap">{price}</span>}
33
+ </div>
34
+
35
+ {service.tagLine && (
36
+ <p className="m-0 text-muted-foreground text-[13px] line-clamp-1">{service.tagLine}</p>
37
+ )}
38
+
39
+ {facts.length > 0 && (
40
+ <p className="m-0 mt-0.5 text-[11px] uppercase tracking-wide text-muted-foreground">
41
+ {facts.join(" · ")}
42
+ </p>
43
+ )}
44
+ </div>
45
+ </Link>
46
+ );
47
+ }
@@ -0,0 +1,13 @@
1
+ // Responsive service grid + empty state. Styled with base44 design tokens (shadcn Tailwind classes).
2
+ import ServiceCard from "./ServiceCard";
3
+
4
+ export default function ServiceGrid({ services, empty = "No services yet." }) {
5
+ if (!services?.length) {
6
+ return <p className="text-muted-foreground p-4 text-center">{empty}</p>;
7
+ }
8
+ return (
9
+ <div className="grid gap-4 grid-cols-2 md:[grid-template-columns:repeat(auto-fill,minmax(240px,1fr))]">
10
+ {services.map((s) => <ServiceCard key={s.id} service={s} />)}
11
+ </div>
12
+ );
13
+ }