@wix/agent-skills 1.15.0 → 1.16.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 (355) hide show
  1. package/README.md +5 -1
  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 +6 -4
  8. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +28 -7
  9. package/skills/wix-app/references/SERVICE_PLUGIN.md +12 -10
  10. package/skills/wix-app/references/STORES_VERSIONING.md +9 -211
  11. package/skills/wix-app/references/app-tools/TOOLS.md +75 -0
  12. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +5 -0
  13. package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +2 -2
  14. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +172 -0
  15. package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +138 -0
  16. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +172 -0
  17. package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +29 -0
  18. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +1 -1
  19. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +57 -0
  20. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +33 -2
  21. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +5 -3
  22. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +18 -1
  23. package/skills/wix-app/references/editor-react-component/PARTS.md +15 -2
  24. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +4 -3
  25. package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +13 -9
  26. package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +4 -0
  27. package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +4 -0
  28. package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +3 -1
  29. package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +4 -0
  30. package/skills/wix-app/references/service-plugin/TOOLS_PROVIDER.md +54 -0
  31. package/skills/wix-app/references/stores/CATEGORIES.md +22 -0
  32. package/skills/wix-app/references/stores/GET_PRODUCT.md +99 -0
  33. package/skills/wix-app/references/stores/INVENTORY.md +37 -0
  34. package/skills/wix-app/references/stores/QUERY.md +119 -0
  35. package/skills/wix-app/references/stores/WRITE.md +55 -0
  36. package/skills/wix-docs/SKILL.md +35 -3
  37. package/skills/wix-headless/SKILL.md +9 -2
  38. package/skills/wix-headless/entry/bootstrap.mjs +2 -2
  39. package/skills/wix-headless/entry/skill.md +0 -2
  40. package/skills/wix-headless/references/CAPABILITIES.md +6 -4
  41. package/skills/wix-headless/references/CONTENT.md +36 -0
  42. package/skills/wix-headless/references/DESIGN.md +54 -0
  43. package/skills/wix-headless/references/DISCOVERY.md +25 -1
  44. package/skills/wix-headless/references/FEEDBACK.md +16 -5
  45. package/skills/wix-headless/references/IMAGE_GENERATION.md +10 -0
  46. package/skills/wix-headless/references/SDK_HANDOFF.md +2 -0
  47. package/skills/wix-headless/references/SEED.md +3 -1
  48. package/skills/wix-headless/references/SETUP.md +1 -1
  49. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +3 -2
  50. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +42 -2
  51. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +5 -1
  52. package/skills/wix-headless/references/inline-recipes/setup-forms.md +1 -1
  53. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +33 -8
  54. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +3 -1
  55. package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +73 -0
  56. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +38 -2
  57. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +20 -1
  58. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +1 -1
  59. package/skills/wix-headless/references/managed/CONNECT.md +2 -2
  60. package/skills/wix-headless/references/managed/CREATE.md +15 -1
  61. package/skills/wix-headless/references/managed/DEPLOYMENT.md +47 -0
  62. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +8 -0
  63. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +8 -0
  64. package/skills/wix-manage/SKILL.md +131 -12
  65. package/skills/wix-manage/references/analytics/analytics-dashboard-navigation.md +41 -0
  66. package/skills/wix-manage/references/analytics/query-site-analytics.md +66 -9
  67. package/skills/wix-manage/references/app-installation/app-installation-dashboard-navigation.md +28 -0
  68. package/skills/wix-manage/references/app-installation/install-wix-apps.md +3 -0
  69. package/skills/wix-manage/references/blog/blog-dashboard-navigation.md +56 -0
  70. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +31 -6
  71. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +3 -1
  72. package/skills/wix-manage/references/bookings/bookings-dashboard-navigation.md +63 -0
  73. package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +6 -5
  74. package/skills/wix-manage/references/bookings/create-course-service.md +30 -5
  75. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +85 -42
  76. package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +44 -0
  77. package/skills/wix-manage/references/cms/cms-data-items-crud.md +31 -3
  78. package/skills/wix-manage/references/cms/cms-publishing-flow.md +287 -0
  79. package/skills/wix-manage/references/cms/cms-schema-management.md +33 -1
  80. package/skills/wix-manage/references/contacts/contacts-dashboard-navigation.md +46 -0
  81. package/skills/wix-manage/references/contacts/create-a-contact.md +82 -0
  82. package/skills/wix-manage/references/contacts/update-a-contact.md +119 -0
  83. package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +82 -0
  84. package/skills/wix-manage/references/dashboard-navigation/routes.json +1733 -0
  85. package/skills/wix-manage/references/domains/domains-dashboard-navigation.md +32 -0
  86. package/skills/wix-manage/references/ecommerce/ecom-pricing.md +4 -4
  87. package/skills/wix-manage/references/ecommerce/ecom-shipping.md +1 -1
  88. package/skills/wix-manage/references/ecommerce/gift-cards/ecom-gift-cards-goal-sell-gift-cards.md +338 -0
  89. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-discount-rule.md +42 -78
  90. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-bundle-and-save.md +1 -1
  91. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-stock-mover.md +1 -1
  92. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-upsell-boost.md +1 -1
  93. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +90 -92
  94. package/skills/wix-manage/references/events/create-wix-event.md +176 -0
  95. package/skills/wix-manage/references/events/manage-wix-events.md +174 -0
  96. package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +44 -0
  97. package/skills/wix-manage/references/get-paid/get-paid-dashboard-navigation.md +52 -0
  98. package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +30 -7
  99. package/skills/wix-manage/references/google-ads/billing-and-payment.md +80 -0
  100. package/skills/wix-manage/references/google-ads/create-performance-max-campaign.md +212 -0
  101. package/skills/wix-manage/references/google-ads/get-campaign-suggestions.md +110 -0
  102. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +25 -0
  103. package/skills/wix-manage/references/google-ads/install-and-create-account.md +155 -0
  104. package/skills/wix-manage/references/google-ads/manage-campaign-lifecycle.md +63 -0
  105. package/skills/wix-manage/references/google-ads/query-campaign-analytics.md +155 -0
  106. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +225 -144
  107. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +19 -10
  108. package/skills/wix-manage/references/marketing/marketing-dashboard-navigation.md +52 -0
  109. package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +99 -1
  110. package/skills/wix-manage/references/pricing-plans/pricing-plans-dashboard-navigation.md +45 -0
  111. package/skills/wix-manage/references/restaurants/restaurants-dashboard-navigation.md +68 -0
  112. package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +94 -125
  113. package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +48 -9
  114. package/skills/wix-manage/references/site-properties/site-properties-dashboard-navigation.md +31 -0
  115. package/skills/wix-manage/references/sites/create-headless-site.md +52 -0
  116. package/skills/wix-manage/references/sites/create-site-from-template.md +2 -25
  117. package/skills/wix-manage/references/sites/site-import.md +243 -0
  118. package/skills/wix-manage/references/sites/sites-dashboard-navigation.md +29 -0
  119. package/skills/wix-manage/references/stores/add-store-pages-to-site.md +17 -1
  120. package/skills/wix-manage/references/stores/create-product-from-image.md +8 -6
  121. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +16 -10
  122. package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +26 -8
  123. package/skills/wix-manage/references/stores/stores-dashboard-navigation.md +65 -0
  124. package/skills/wix-manage/references/stores/update-product-with-options.md +39 -7
  125. package/skills/wix-replatform/.publish-manifest.json +8 -0
  126. package/skills/wix-replatform/SKILL.md +693 -0
  127. package/skills/wix-replatform/lib/artifact-freshness.js +215 -0
  128. package/skills/wix-replatform/lib/completion-report.js +200 -0
  129. package/skills/wix-replatform/lib/config-env.js +59 -0
  130. package/skills/wix-replatform/lib/execution-manifest.js +185 -0
  131. package/skills/wix-replatform/lib/execution-state.js +173 -0
  132. package/skills/wix-replatform/lib/import-recovery.js +313 -0
  133. package/skills/wix-replatform/lib/local-state.js +642 -0
  134. package/skills/wix-replatform/lib/orchestration-preflight.js +143 -0
  135. package/skills/wix-replatform/lib/orchestration-router.js +122 -0
  136. package/skills/wix-replatform/lib/orchestration-state.js +455 -0
  137. package/skills/wix-replatform/lib/progress-log.js +224 -0
  138. package/skills/wix-replatform/lib/progress-log.sh +140 -0
  139. package/skills/wix-replatform/lib/url-preservation-state.js +391 -0
  140. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +184 -0
  141. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +529 -0
  142. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +316 -0
  143. package/skills/wix-replatform/resources/rp-execute-setup/scripts/mint-token.sh +64 -0
  144. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +1114 -0
  145. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +430 -0
  146. package/skills/wix-replatform/resources/rp-mapper/lib/mapping-resolve.js +217 -0
  147. package/skills/wix-replatform/resources/rp-mapper/scripts/resolve-mapping.js +148 -0
  148. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +378 -0
  149. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +183 -0
  150. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +478 -0
  151. package/skills/wix-replatform/resources/rp-source-csv/lib/canonical-record.js +136 -0
  152. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  153. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fingerprint.js +310 -0
  154. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-layout.js +1081 -0
  155. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-parse.js +618 -0
  156. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +949 -0
  157. package/skills/wix-replatform/resources/rp-source-csv/source-schema.example.json +196 -0
  158. package/skills/wix-replatform/resources/rp-source-csv/vendors/bigcommerce.json +66 -0
  159. package/skills/wix-replatform/resources/rp-source-csv/vendors/magento.json +60 -0
  160. package/skills/wix-replatform/resources/rp-source-csv/vendors/shopify.json +95 -0
  161. package/skills/wix-replatform/resources/rp-source-csv/vendors/woocommerce.json +82 -0
  162. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +256 -0
  163. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +249 -0
  164. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +444 -0
  165. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +774 -0
  166. package/skills/wix-replatform/resources/rp-source-wordpress/source-schema.example.json +71 -0
  167. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +632 -0
  168. package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +330 -0
  169. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +21 -0
  170. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -0
  171. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +37 -0
  172. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +37 -0
  173. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +39 -0
  174. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +35 -0
  175. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +14 -0
  176. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +35 -0
  177. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +36 -0
  178. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +35 -0
  179. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +14 -0
  180. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +131 -0
  181. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +37 -0
  182. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +37 -0
  183. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +21 -0
  184. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +37 -0
  185. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +37 -0
  186. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +97 -0
  187. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +528 -0
  188. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -0
  189. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +38 -0
  190. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +37 -0
  191. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -0
  192. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +37 -0
  193. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +53 -0
  194. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +84 -0
  195. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +25 -0
  196. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +37 -0
  197. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +37 -0
  198. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +38 -0
  199. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +37 -0
  200. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +90 -0
  201. package/skills/wix-replatform/resources/rp-target-wix/lib/audit-summary.js +64 -0
  202. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +141 -0
  203. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +384 -0
  204. package/skills/wix-replatform/resources/rp-target-wix/lib/ndjson.js +260 -0
  205. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +238 -0
  206. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +237 -0
  207. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +238 -0
  208. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +2219 -0
  209. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +31 -0
  210. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge.js +100 -0
  211. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +107 -0
  212. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +344 -0
  213. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +250 -0
  214. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1927 -0
  215. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +83 -0
  216. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +141 -0
  217. package/skills/wix-replatform/scripts/artifact-freshness.js +76 -0
  218. package/skills/wix-replatform/scripts/execution-manifest-validate.js +43 -0
  219. package/skills/wix-replatform/scripts/execution-state-prepare.js +128 -0
  220. package/skills/wix-replatform/scripts/orchestration-preflight.js +48 -0
  221. package/skills/wix-replatform/scripts/orchestration-route.js +46 -0
  222. package/skills/wix-replatform/scripts/orchestration-state.js +245 -0
  223. package/skills/wix-vibe-headless/SKILL.md +54 -25
  224. package/skills/wix-vibe-headless/install/deploy.cjs +95 -0
  225. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +34 -0
  226. package/skills/wix-vibe-headless/platforms/README.md +26 -0
  227. package/skills/wix-vibe-headless/platforms/base44.md +177 -0
  228. package/skills/wix-vibe-headless/platforms/generic.md +122 -0
  229. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +230 -119
  230. package/skills/wix-vibe-headless/references/blog/app/components/PostCard.jsx +43 -0
  231. package/skills/wix-vibe-headless/references/blog/app/components/PostChips.jsx +25 -0
  232. package/skills/wix-vibe-headless/references/blog/app/components/PostGrid.jsx +15 -0
  233. package/skills/wix-vibe-headless/references/blog/app/context/TaxonomyContext.jsx +35 -0
  234. package/skills/wix-vibe-headless/references/blog/app/hooks/usePostDetail.js +38 -0
  235. package/skills/wix-vibe-headless/references/blog/app/pages/Blog.jsx +40 -0
  236. package/skills/wix-vibe-headless/references/blog/app/pages/CategoryPage.jsx +54 -0
  237. package/skills/wix-vibe-headless/references/blog/app/pages/PostDetail.jsx +65 -0
  238. package/skills/wix-vibe-headless/references/blog/app/pages/TagPage.jsx +50 -0
  239. package/skills/wix-vibe-headless/references/blog/seed/SEED.md +103 -0
  240. package/skills/wix-vibe-headless/references/blog/seed/seed-blog.js +270 -0
  241. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +260 -145
  242. package/skills/wix-vibe-headless/references/bookings/app/components/BookingForm.jsx +65 -0
  243. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceCard.jsx +47 -0
  244. package/skills/wix-vibe-headless/references/bookings/app/components/ServiceGrid.jsx +13 -0
  245. package/skills/wix-vibe-headless/references/bookings/app/components/SlotPicker.jsx +126 -0
  246. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +108 -0
  247. package/skills/wix-vibe-headless/references/bookings/app/hooks/useServices.js +58 -0
  248. package/skills/wix-vibe-headless/references/bookings/app/lib/serviceFacts.js +95 -0
  249. package/skills/wix-vibe-headless/references/bookings/app/pages/ServiceDetail.jsx +94 -0
  250. package/skills/wix-vibe-headless/references/bookings/app/pages/Services.jsx +89 -0
  251. package/skills/wix-vibe-headless/references/bookings/{wix-bookings-checkout.js → app/rest/wix-bookings-checkout.js} +1 -1
  252. package/skills/wix-vibe-headless/references/bookings/{wix-bookings-services.js → app/rest/wix-bookings-services.js} +90 -12
  253. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +117 -0
  254. package/skills/wix-vibe-headless/references/bookings/seed/seed-bookings.js +333 -0
  255. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +169 -147
  256. package/skills/wix-vibe-headless/references/cms/app/collection.config.js +31 -0
  257. package/skills/wix-vibe-headless/references/cms/app/lib/wixImage.js +18 -0
  258. package/skills/wix-vibe-headless/references/cms/{wix-cms.js → app/rest/wix-cms.js} +47 -2
  259. package/skills/wix-vibe-headless/references/cms/seed/SEED.md +145 -0
  260. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +228 -131
  261. package/skills/wix-vibe-headless/references/events/app/components/CategoryFilter.jsx +23 -0
  262. package/skills/wix-vibe-headless/references/events/app/components/EventCard.jsx +43 -0
  263. package/skills/wix-vibe-headless/references/events/app/components/EventGrid.jsx +13 -0
  264. package/skills/wix-vibe-headless/references/events/app/components/EventRegistration.jsx +29 -0
  265. package/skills/wix-vibe-headless/references/events/app/components/RsvpForm.jsx +57 -0
  266. package/skills/wix-vibe-headless/references/events/app/components/TicketPicker.jsx +78 -0
  267. package/skills/wix-vibe-headless/references/events/app/hooks/useEventDetail.js +27 -0
  268. package/skills/wix-vibe-headless/references/events/app/hooks/useEventsList.js +54 -0
  269. package/skills/wix-vibe-headless/references/events/app/hooks/useRsvpForm.js +40 -0
  270. package/skills/wix-vibe-headless/references/events/app/hooks/useTicketing.js +81 -0
  271. package/skills/wix-vibe-headless/references/events/app/pages/EventDetail.jsx +48 -0
  272. package/skills/wix-vibe-headless/references/events/app/pages/Events.jsx +36 -0
  273. package/skills/wix-vibe-headless/references/events/{wix-events-browse.js → app/rest/wix-events-browse.js} +3 -2
  274. package/skills/wix-vibe-headless/references/events/seed/SEED.md +107 -0
  275. package/skills/wix-vibe-headless/references/events/seed/seed-events.js +251 -0
  276. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +276 -188
  277. package/skills/wix-vibe-headless/references/members/app/components/LoginForm.jsx +101 -0
  278. package/skills/wix-vibe-headless/references/members/app/components/MemberMenu.jsx +33 -0
  279. package/skills/wix-vibe-headless/references/members/app/components/RequireAuth.jsx +21 -0
  280. package/skills/wix-vibe-headless/references/members/app/components/SocialButtons.jsx +29 -0
  281. package/skills/wix-vibe-headless/references/members/app/context/MemberContext.jsx +54 -0
  282. package/skills/wix-vibe-headless/references/members/app/hooks/useLoginForm.js +77 -0
  283. package/skills/wix-vibe-headless/references/members/app/pages/Account.jsx +36 -0
  284. package/skills/wix-vibe-headless/references/members/app/pages/Callback.jsx +32 -0
  285. package/skills/wix-vibe-headless/references/members/app/pages/Login.jsx +35 -0
  286. package/skills/wix-vibe-headless/references/members/{wix-members-auth.js → app/rest/wix-members-auth.js} +6 -3
  287. package/skills/wix-vibe-headless/references/members/install/Register.jsx +22 -0
  288. package/skills/wix-vibe-headless/references/members/seed/SEED.md +22 -0
  289. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +233 -104
  290. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionCard.jsx +31 -0
  291. package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionGrid.jsx +15 -0
  292. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectCard.jsx +39 -0
  293. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectGrid.jsx +15 -0
  294. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +29 -0
  295. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useCollectionProjects.js +35 -0
  296. package/skills/wix-vibe-headless/references/portfolio/app/hooks/usePortfolioGallery.js +27 -0
  297. package/skills/wix-vibe-headless/references/portfolio/app/hooks/useProjectDetail.js +25 -0
  298. package/skills/wix-vibe-headless/references/portfolio/app/pages/CollectionPage.jsx +39 -0
  299. package/skills/wix-vibe-headless/references/portfolio/app/pages/Portfolio.jsx +27 -0
  300. package/skills/wix-vibe-headless/references/portfolio/app/pages/ProjectDetail.jsx +60 -0
  301. package/skills/wix-vibe-headless/references/portfolio/{wix-portfolio.js → app/rest/wix-portfolio.js} +84 -55
  302. package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +94 -0
  303. package/skills/wix-vibe-headless/references/portfolio/seed/seed-portfolio.js +236 -0
  304. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +240 -117
  305. package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +35 -0
  306. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanCard.jsx +48 -0
  307. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanGrid.jsx +16 -0
  308. package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanPrice.jsx +35 -0
  309. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/useMyPlans.js +25 -0
  310. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlanDetail.js +28 -0
  311. package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlans.js +30 -0
  312. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/MyPlans.jsx +30 -0
  313. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/PlanDetail.jsx +53 -0
  314. package/skills/wix-vibe-headless/references/pricing-plans/app/pages/Plans.jsx +28 -0
  315. package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +86 -0
  316. package/skills/wix-vibe-headless/references/pricing-plans/seed/seed-pricing-plans.js +251 -0
  317. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +248 -124
  318. package/skills/wix-vibe-headless/references/restaurants/app/components/ItemDialog.jsx +81 -0
  319. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuItemCard.jsx +71 -0
  320. package/skills/wix-vibe-headless/references/restaurants/app/components/MenuList.jsx +43 -0
  321. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartButton.jsx +21 -0
  322. package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +60 -0
  323. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +63 -0
  324. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useItemOrder.js +32 -0
  325. package/skills/wix-vibe-headless/references/restaurants/app/hooks/useReservation.js +73 -0
  326. package/skills/wix-vibe-headless/references/restaurants/app/pages/Menu.jsx +28 -0
  327. package/skills/wix-vibe-headless/references/restaurants/app/pages/Reservations.jsx +102 -0
  328. package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +180 -0
  329. package/skills/wix-vibe-headless/references/restaurants/seed/seed-restaurants.js +452 -0
  330. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +56 -0
  331. package/skills/wix-vibe-headless/references/shared/{wix-client.js → app/rest/wix-client.js} +6 -8
  332. package/skills/wix-vibe-headless/references/shared/app/rest/wix-config.js +6 -0
  333. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +263 -148
  334. package/skills/wix-vibe-headless/references/storefront/app/components/CartButton.jsx +20 -0
  335. package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +150 -0
  336. package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +167 -0
  337. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +51 -0
  338. package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +54 -0
  339. package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +119 -0
  340. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +71 -0
  341. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +109 -0
  342. package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +98 -0
  343. package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +27 -0
  344. package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +139 -0
  345. package/skills/wix-vibe-headless/references/storefront/app/pages/Shop.jsx +75 -0
  346. package/skills/wix-vibe-headless/references/storefront/{wix-store-cart.js → app/rest/wix-store-cart.js} +1 -1
  347. package/skills/wix-vibe-headless/references/storefront/{wix-store-catalog.js → app/rest/wix-store-catalog.js} +25 -2
  348. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +111 -0
  349. package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +299 -0
  350. /package/skills/wix-vibe-headless/references/blog/{wix-blog.js → app/rest/wix-blog.js} +0 -0
  351. /package/skills/wix-vibe-headless/references/events/{wix-events-registration.js → app/rest/wix-events-registration.js} +0 -0
  352. /package/skills/wix-vibe-headless/references/pricing-plans/{wix-pricing-plans.js → app/rest/wix-pricing-plans.js} +0 -0
  353. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-menu.js → app/rest/wix-restaurants-menu.js} +0 -0
  354. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-ordering.js → app/rest/wix-restaurants-ordering.js} +0 -0
  355. /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-reservations.js → app/rest/wix-restaurants-reservations.js} +0 -0
@@ -1,138 +1,262 @@
1
+ # Wix Restaurants — ready-made client
1
2
 
2
- # Wix Restaurants Skill
3
+ The restaurant client is **shipped as real files**, not snippets to regenerate. It's a complete
4
+ menu + item ordering + server-cart + checkout, plus a table-reservation flow, styled with your app's
5
+ design tokens (base44's `src/index.css` — the shadcn palette the design phase already set). Copy it
6
+ into the app and wire the routes — you generate almost none of the restaurant code (the menu tree
7
+ join, the order cart, the reservation hold→reserve flow all ship and are correct).
3
8
 
4
- > **Source files (in this skill):** the shared transport `references/shared/wix-client.js` and the helper file(s) you need from `references/restaurants/`. All helpers import from `"./wix-client.js"`, so copy them into the same folder (e.g. `src/rest/`).
5
- >
6
- > | Need | Copy |
7
- > |---|---|
8
- > | Menu display (always) | `wix-restaurants-menu.js` |
9
- > | Online ordering (cart + checkout) | `wix-restaurants-ordering.js` |
10
- > | Table reservations | `wix-restaurants-reservations.js` |
9
+ Talks to Wix directly over the public `WIX_CLIENT_ID` (anonymous visitor tokens). Never mock the
10
+ menu; never hand-build `/checkout` or reservation URLs — the shipped cart goes through the eCom
11
+ redirect-session and reservations go through the hold/reserve flow.
11
12
 
12
- Builds a real, client-only Wix restaurant experience. The browser talks to Wix directly over a
13
- public `WIX_CLIENT_ID`. Never mock the menu; never hand-build `/checkout` or reservation URLs —
14
- always go through the official cart + redirect-session and the reservations hold/reserve flow.
13
+ ## Prerequisites
14
+ - The site's **Wix Restaurants Menus** app is the read target for the menu; **Restaurant Orders**
15
+ backs online ordering; **Table Reservations** backs the booking page. They're installed and seeded
16
+ separately (see **Seeding** below), in parallel with this build — so the menu may be empty and
17
+ ordering / reservations may be unconfigured at build time. The client renders the shipped empty /
18
+ "unavailable" states until content and operations land.
19
+ - The public headless **`WIX_CLIENT_ID`** from your prompt (buyer-facing, safe to hardcode/commit).
20
+ - For Wix-hosted checkout to return, the deployed app domain must be allow-listed on the OAuth
21
+ client — a **separate Wix setup the user completes later**, out of scope here. If checkout return
22
+ fails before that, it's expected; flag it and continue.
15
23
 
16
- ## When to use
17
- - User wants a Wix restaurant site, an online food-ordering page, or a table-reservation page.
18
- - User asks to "connect Wix Restaurants" or replace placeholder menu/ordering/booking UI with live data.
19
- - Adding a menu, cart + checkout, or reservations over an existing Wix Restaurants setup.
24
+ ## STEP 1 — The client is already in `src/`
25
+ The install step (base44.md STEP 1) deployed the whole restaurant UI client + REST scaffolds into
26
+ `src/` (imports use the `@/` alias → `src/`). Here's every file and what it is — **this is your map,
27
+ so you don't need to open them:**
20
28
 
21
- ## Prerequisites
22
- 1. A Wix site with the **Wix Restaurants Menus** app installed and **menu content already added**
23
- (this skill is read-only over the menu — it does NOT create menus/items).
24
- 2. For **online ordering**: at least one online-ordering **Operation** configured (Wix Restaurants
25
- Orders). For **reservations**: the **Table Reservations** app installed with at least one location
26
- and online reservations enabled. If a flow's backing app/config isn't set up, that flow returns
27
- empty — flag it and continue; don't fabricate data.
28
- 3. The site's public headless **`WIX_CLIENT_ID`**, provided in the handoff prompt (see the router `SKILL.md`).
29
- Paste it into `src/rest/wix-client.js` in place of the placeholder. It is a buyer-facing
30
- credential (it only mints anonymous visitor tokens), **not** a secret — hardcoding/committing
31
- it is fine.
32
- 4. The deployed app domain must be allow-listed on the OAuth client for Wix-hosted checkout to
33
- return. This is a **separate Wix setup flow the user completes later** — out of this skill's
34
- scope. If checkout return fails before that setup is done, that's expected; flag it and continue.
35
-
36
- ## The API (copy as-is; do not re-derive it)
37
- This skill ships only the REST layer — no UI components. Build the restaurant UI however the
38
- project wants; wire it to these two snippets. Copy them into the app (e.g. `src/api/`) and only
39
- adjust import paths:
40
- - `src/rest/wix-client.js` — visitor-token mint/refresh + transport. Set `WIX_CLIENT_ID` to the id
41
- from the prompt (replace the `<YOUR-CLIENT-ID>` placeholder). The visitor refresh token IS the
42
- cart identity; it is persisted to localStorage. Do not re-mint anonymously per load or the cart
43
- silently empties.
44
- - `src/rest/wix-restaurants-menu.js` — **Menu (read-only):**
45
- `getFullMenu` (the assembled tree — start here), `listMenus`, `listSections`, `listItems`,
46
- `listVariants`, `listModifierGroups`, `listModifiers`, `listLabels`
47
- - `src/rest/wix-restaurants-ordering.js` — **Online ordering:**
48
- `listOperations`, `getDefaultOperation`, `addItemToCart`, `getCurrentCart`,
49
- `updateCartItemQuantity`, `removeFromCart`, `checkout`
50
- - `src/rest/wix-restaurants-reservations.js` — **Reservations:**
51
- `listReservationLocations`, `getTimeSlots`, `createHeldReservation`, `reserveReservation`
52
-
53
- The Menu, Item, ModifierGroup, Operation, Cart, ReservationLocation, TimeSlot, and Reservation
54
- shapes are documented as JSDoc at the top of each helper file. Read the relevant file(s) before
55
- building the UI — they describe the key fields and link to the full reference for anything not shown.
56
-
57
- ## How to wire it (UI is the project's choice)
58
- - **Menu page** — call `getFullMenu()` once. It returns `{ menus: [{ ...menu, sections: [{ ...section,
59
- items: [assembledItem] }] }] }`, already ordered by `sectionIds` / `itemIds`. Render each item's
60
- `name`, `description`, `image`, `labels` (`name` + `icon`), and `featured` flag. For price, show
61
- `item.price` (single) or the `item.variants[]` (each `{ name, price }`). **Restaurants prices are
62
- plain decimal strings with NO currency symbol** — format with the site's currency in the UI.
63
- - **Item detail** — render `item.modifierGroups[]`: each group's `name`, its `rule`
64
- (`required`, `minSelections`, `maxSelections`), and `modifiers[]` (`name`, `additionalCharge`,
65
- `preSelected`, `inStock`). If `orderSettings.acceptSpecialRequests`, offer a free-text field.
66
- - **Online ordering** — resolve an operation with `getDefaultOperation()` (or let the user pick from
67
- `listOperations()`); if it's `null`, show an "ordering unavailable" state. Add a dish with
68
- `addItemToCart(item.id, { operationId, menuId, sectionId, quantity })` — `menuId`/`sectionId` are
69
- the menu and section the item was shown under. Read the cart back with `getCurrentCart()`; mutate
70
- with `updateCartItemQuantity(lineItemId, qty)` / `removeFromCart(lineItemId)` using
71
- `cart.lineItems[].id` (not the item id).
72
- - **Checkout** — `window.location.href = await checkout()`. After the visitor returns, the order is
73
- placed and the cart is empty — re-fetch with `getCurrentCart()` on return (e.g. on mount +
74
- `visibilitychange`) to clear the UI.
75
- - **Reservations** — `listReservationLocations()` for the picker (use `location` details for the
76
- label; if a location's `configuration.onlineReservations.onlineReservationsEnabled` is false, hide
77
- it). Then `getTimeSlots(locationId, dateISO, partySize)` — render `availableTimeSlots` (already
78
- filtered to `AVAILABLE`). On slot pick, `createHeldReservation(locationId, slot.startDate,
79
- partySize)` → keep the returned `id` + `revision`. Collect the visitor's details, then
80
- `reserveReservation(id, revision, { firstName, phone, lastName?, email? })`. A `RESERVED` status is
81
- confirmed; `REQUESTED` means the location requires manual approval — tell the user it's pending.
82
- - **Empty state** — if `getFullMenu()` returns no menus, show an empty state telling the user to add
83
- a menu in their Wix dashboard. Never invent menu items.
84
-
85
- ## Hard rules (do not violate)
86
- - ✅ Order ONLY through the cart: `addItemToCart()` → `checkout()` (`create-checkout` →
87
- `/headless/v1/redirect-session` `fullUrl`), then redirect.
88
- - ❌ Never hand-build `/checkout`, ordering, or reservation URLs.
89
- - ❌ Never mock menus, items, prices, operations, locations, or time slots — render live Wix data or
90
- the empty state.
91
- - ❌ Never generate fake reviews, ratings, or testimonials. Empty review UI only.
92
- - ✅ Set `WIX_CLIENT_ID` from the prompt's value (public client id — safe to hardcode).
93
- - ✅ `addItemToCart` requires `operationId`, `menuId`, and `sectionId` — it throws if any is missing.
94
- - ✅ `lineItemId` for cart mutations is `cart.lineItems[].id`, not the item id.
95
- - ✅ Reservations: offer only `AVAILABLE` slots; a HELD reservation expires in 10 minutes — pass the
96
- `revision` from the hold into `reserveReservation`, and restart the flow if it expired.
97
- - ✅ Reservee `firstName` + `phone` (E.164, e.g. `+15551234567`) are mandatory to confirm.
98
- - The engine fails loudly on purpose: `addItemToCart`/`checkout` throw on out-of-stock or empty
99
- carts; reservation helpers throw on unavailable slots or expired holds. A green path means it is
100
- really orderable/bookable — don't swallow these.
101
-
102
- ## Beyond the snippets
103
- The snippets cover the common menu / ordering / reservation paths. For the "20%" they don't cover,
104
- make the call yourself with `wixApiRequest` — but look up the exact endpoint, HTTP method, and
105
- request body in the **official Wix API reference** first; never guess:
29
+ | file | what it is |
30
+ |---|---|
31
+ | `context/OrderCartContext.jsx` | `useOrderCart()` provider: resolves the ordering Operation, server cart, add/update/remove, checkout, `ordering` flag |
32
+ | `hooks/useItemOrder.js` | item-dialog add-to-order logic (stock + ordering-available gating, quantity) |
33
+ | `hooks/useReservation.js` | reservation flow (locations → date/party → AVAILABLE slots → hold → reserve) |
34
+ | `components/MenuItemCard.jsx`, `MenuList.jsx` | menu render UI (dish card + the menus→sections→items tree, with empty state) |
35
+ | `components/ItemDialog.jsx` | dish detail modal — description, price/variants, modifier groups (display), quantity, add-to-order |
36
+ | `components/OrderCartButton.jsx` | header order **icon** button with a live-count badge |
37
+ | `components/OrderCartDrawer.jsx` | slide-over order cart (mount once; opens from `useOrderCart`) |
38
+ | `components/WixManageBanner.jsx` | preview-only manage banner — drop it into your Layout (STEP 4) |
39
+ | `pages/Menu.jsx`, `pages/Reservations.jsx` | the two shipped routes (`/menu`, `/reservations`) |
40
+ | `rest/wix-config.js` | **you set the ids here** (STEP 2) |
41
+ | `rest/wix-client.js` | REST transport + visitor-token mint/refresh (the refresh token IS the cart identity) |
42
+ | `rest/wix-restaurants-menu.js` | menu read helpers — `getFullMenu` (the assembled tree; start here) + raw `list*` |
43
+ | `rest/wix-restaurants-ordering.js` | ordering — operations, add/update/remove, `checkout` |
44
+ | `rest/wix-restaurants-reservations.js` | reservations — locations, time slots, hold, reserve |
45
+
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 is
48
+ and every field shape you need is in the snippets below. Read a shipped file's source **only** on a
49
+ real fallback — a runtime error, or a field the snippets don't cover (see "Fallback only" at the
50
+ end). (Files missing? the install's `deploy` result lists what it wrote; re-run install, or copy
51
+ `references/restaurants/app/` → `src/`.)
52
+
53
+ ## STEP 2 — Credentials
54
+ Write `src/rest/wix-config.js` with your `WIX_CLIENT_ID` and `WIX_METASITE_ID` from the prompt — the
55
+ one place both ids live.
56
+
57
+ ## STEP 3 — Theme (nothing to style on the shipped components)
58
+ The shipped components (menu, item dialog, order cart, reservations) carry **no palette of their
59
+ own** — they render from base44's design tokens in `src/index.css` (`:root`/`.dark`: `--background`,
60
+ `--foreground`, `--card`, `--primary`, `--muted`, `--border`, `--radius`, `--font-*`) via shadcn
61
+ Tailwind classes (`bg-card`, `text-foreground`, `bg-primary`, `text-muted-foreground`,
62
+ `border-border`, `rounded-lg`, `font-display`). Those tokens are **already set to the brand by the
63
+ design phase**, so the shipped pages are themed with zero work here. To adjust the palette, edit
64
+ `index.css` (`:root` **and** `.dark`) — the base44 way; **never add a parallel theme file (e.g. a
65
+ `theme.css`) or restyle the shipped JSX.** Build the Home/Header you add (STEP 4) from the **same**
66
+ base44 tokens/classes so it matches automatically. A dark brand is just base44's dark palette in
67
+ `index.css` — no per-component work.
68
+
69
+ ## STEP 4 — Wire routes + provider (surgical `find_replace` on `src/App.jsx`, never a rewrite)
70
+ **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.
71
+ `App.jsx` carries required platform auth scaffolding (`AuthProvider`/`useAuth`) — edit it in, don't
72
+ replace it.
73
+ - Wrap the routed tree in `<OrderCartProvider>` (from `@/context/OrderCartContext`).
74
+ - Put your **header + footer in a `Layout`** that renders `<Outlet/>` between them, and nest every
75
+ route under one pathless `<Route element={<Layout/>}>`. Your brand chrome then wraps **every** page
76
+ — including the shipped `Menu` / `Reservations` — so you **never edit the shipped pages to add a
77
+ header/footer** (they render inside `<Outlet/>` as-is). Mount `<OrderCartDrawer/>` once in the Layout.
78
+ - **Pin the top chrome as one fixed block.** Put `<WixManageBanner/>` (shipped, preview-only) **above**
79
+ your `<Header/>` inside a single `position:fixed` top region — the header itself is plain in-flow
80
+ markup, the region owns the fixing — so banner + header ride together (no scroll drift/gap). Pad
81
+ the content by the region's measured height so it clears the chrome and self-corrects when the
82
+ banner is dismissed.
83
+ - Routes under the Layout: `/menu` → `Menu`, `/reservations` → `Reservations` (both shipped, as-is).
84
+ **You add `/` → your own Home** page.
85
+
86
+ ```jsx
87
+ import { useRef, useState, useEffect } from "react";
88
+ import { Routes, Route, Outlet } from "react-router-dom";
89
+ import { OrderCartProvider } from "@/context/OrderCartContext";
90
+ import OrderCartDrawer from "@/components/OrderCartDrawer";
91
+ import WixManageBanner from "@/components/WixManageBanner"; // shipped, preview-only · default export, no props
92
+ import Menu from "@/pages/Menu"; // shipped · default export, no props
93
+ import Reservations from "@/pages/Reservations"; // shipped · default export, no props
94
+ import Home from "@/pages/Home"; // YOU build
95
+ import Header from "@/components/Header"; // YOU build — plain in-flow markup, NOT position:fixed
96
+ import Footer from "@/components/Footer"; // YOU build
97
+
98
+ function Layout() {
99
+ const topRef = useRef(null);
100
+ const [offset, setOffset] = useState(0);
101
+ useEffect(() => { // measure the fixed region → pad content below it
102
+ const ro = new ResizeObserver(() => setOffset(topRef.current?.offsetHeight ?? 0));
103
+ if (topRef.current) ro.observe(topRef.current);
104
+ return () => ro.disconnect();
105
+ }, []);
106
+ return (<>
107
+ <div ref={topRef} style={{ position: "fixed", top: 0, left: 0, right: 0, zIndex: 50 }}>
108
+ <WixManageBanner /> {/* null on the published site / when dismissed */}
109
+ <Header /> {/* your brand header, in-flow inside this fixed block */}
110
+ </div>
111
+ <div style={{ paddingTop: offset }}> {/* clears the chrome; shrinks when the banner is dismissed */}
112
+ <Outlet /> {/* shipped Menu/Reservations render here, untouched */}
113
+ <Footer />
114
+ </div>
115
+ <OrderCartDrawer /> {/* overlays every page */}
116
+ </>);
117
+ }
118
+
119
+ <OrderCartProvider>
120
+ <Routes>
121
+ <Route element={<Layout />}> {/* chrome wraps all */}
122
+ <Route path="/" element={<Home />} /> {/* yours */}
123
+ <Route path="/menu" element={<Menu />} /> {/* shipped, as-is */}
124
+ <Route path="/reservations" element={<Reservations />} /> {/* shipped, as-is */}
125
+ </Route>
126
+ </Routes>
127
+ </OrderCartProvider>
128
+ ```
129
+
130
+ ## What you build (not shipped)
131
+ The **home / landing page**, the **`Header`** (mount `<OrderCartButton/>` in it) and a **`Footer`** —
132
+ the two you drop into the `Layout` (STEP 4) so they wrap every route — plus the overall brand story,
133
+ styled with the same base44 tokens/classes. The nav is an `<OrderCartButton/>` (a clean order-**icon**
134
+ button with a live-count badge — render it as-is, don't wrap it in your own text button) + links to
135
+ `/menu` and `/reservations`:
136
+
137
+ ```jsx
138
+ import { useState, useEffect } from "react";
139
+ import { Link } from "react-router-dom";
140
+ import OrderCartButton from "@/components/OrderCartButton";
141
+
142
+ // Responsive header: choose ONE branch with a state flag, so <OrderCartButton/> mounts once.
143
+ // Do NOT render a desktop nav AND a mobile nav toggled by `hidden md:flex` / `md:hidden`:
144
+ // these navs are inline-styled, and an inline `display` beats a Tailwind class, so `hidden`
145
+ // never applies — BOTH branches render and you get two order buttons. One branch = one button.
146
+ export function Header() {
147
+ const [mobile, setMobile] = useState(() => window.innerWidth < 768);
148
+ useEffect(() => {
149
+ const onResize = () => setMobile(window.innerWidth < 768);
150
+ window.addEventListener("resize", onResize); // keep it reactive to viewport changes
151
+ return () => window.removeEventListener("resize", onResize);
152
+ }, []);
153
+ return (
154
+ <nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
155
+ {/* brand/logo */}
156
+ {mobile
157
+ ? <YourMenu /> // your hamburger + <OrderCartButton/> here
158
+ : <div style={{ display: "flex", gap: 24, alignItems: "center" }}>
159
+ <Link to="/menu">Menu</Link><Link to="/reservations">Reserve</Link><OrderCartButton />
160
+ </div>}
161
+ </nav>
162
+ );
163
+ }
164
+ ```
165
+
166
+ Everything visual reads base44's design tokens (`index.css`), so your home/nav match the shipped pages automatically.
167
+ `<OrderCartButton/>` is an icon button (live-count badge) — drop it in as-is, it inherits `currentColor`.
168
+
169
+ **Editing a component and the change doesn't show? It's the preview, not your code.** The dev preview
170
+ can serve a stale module after a write. Before diagnosing a visual bug you just "fixed", do a fresh
171
+ full navigate/reload of the preview and re-check — don't keep rewriting correct code against a stale
172
+ render.
173
+
174
+ ## Using the client from your own UI (menu, order cart)
175
+
176
+ ```jsx
177
+ import { getFullMenu } from "@/rest/wix-restaurants-menu";
178
+ import { useOrderCart } from "@/context/OrderCartContext";
179
+
180
+ // getFullMenu() is the ONLY pre-joined shape and the entry point for any menu surface. It returns
181
+ // { menus: [{ ...menu, sections: [{ ...section, items: [assembledItem] }] }] }, already ordered.
182
+ // Each item is enriched with a resolved price / variants, modifierGroups, and labels.
183
+ const { menus } = await getFullMenu(); // [] when no menus → show the shipped empty state
184
+
185
+ // useOrderCart() gives:
186
+ // { cart, operation, ordering, itemCount, isOpen, setIsOpen, loading,
187
+ // addItem(item, { menuId, sectionId }, qty=1), // needs the menu/section the item was shown under
188
+ // removeItem(lineItemId), updateQuantity(lineItemId, qty), checkout(), refreshCart() }
189
+ // `ordering` is false when no ordering Operation is configured — show an "ordering unavailable" state.
190
+
191
+ // Load-bearing field paths (the shipped components already do these):
192
+ // - item.image / section.image / label.icon are OBJECTS → render `.url`, never the object; //-urls → https:
193
+ // - MENU prices are plain decimal strings with NO currency symbol ("12.50") — format in the UI.
194
+ // The eCom cart line price (line.price.formattedAmount) DOES include the symbol.
195
+ // - an item is priced by EITHER item.price (single) OR item.variants[] (one-of, each { name, price }).
196
+ // - a cart mutation uses cart.lineItems[].id (the lineItemId), NOT the menu item id.
197
+ ```
198
+
199
+ Buying happens in the shipped `ItemDialog` (opened from `MenuList`) — it owns quantity + add-to-order
200
+ and surfaces out-of-stock / ordering-unavailable errors. Compose a featured strip on your Home from
201
+ `getFullMenu()` + the shipped `MenuItemCard` if you want.
202
+
203
+ ## Extending the client
204
+ Building something beyond the shipped pages, or need a path these snippets don't cover?
205
+
206
+ ```jsx
207
+ // The raw list* helpers return UNRESOLVED refs and INCONSISTENT shapes (listMenus → { menus,
208
+ // nextCursor }; listSections/listItems/listVariants/listModifierGroups/listModifiers → bare arrays).
209
+ // Don't re-join them by hand — build on getFullMenu(). If you truly need a partial fetch, note they
210
+ // take an array of GUIDs: listSections(sectionIds), listItems(itemIds).
211
+
212
+ // Reservation status after reserve: RESERVED = confirmed, REQUESTED = manual approval pending
213
+ // (tell the user). firstName + phone (E.164, e.g. "+15551234567") are mandatory; a HELD reservation
214
+ // expires in 10 minutes — the hook passes the hold's { id, revision } into reserve for you.
215
+ ```
216
+
217
+ Modifier up-charges / price-variant selection / special requests on the **cart line** are **not**
218
+ wired into `addItemToCart` — the restaurants `catalogReference.options` shape for these isn't
219
+ documented for client add-to-cart, so `ItemDialog` displays modifier groups for the diner but sends
220
+ only quantity. To wire them, confirm the shape via the **`wix-docs`** skill / the reference first,
221
+ never guess:
106
222
  - Restaurants API reference: https://dev.wix.com/docs/api-reference/business-solutions/restaurants.md
107
- - Selecting a specific **price variant** or applying **modifier up-charges** on the cart line: the
108
- restaurants `catalogReference.options` shape for these is not documented for client add-to-cart.
109
- The menu UI still displays them; confirm the shape before wiring them into `addItemToCart`:
110
- https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/sample-flows.md
111
- - Fulfillment methods, delivery-address validation, scheduled (preorder) time slots, service fees:
112
- see the Online Orders section of the reference.
223
+ - Sample flows (cart options): https://dev.wix.com/docs/api-reference/business-solutions/restaurants/online-orders/sample-flows.md
113
224
  - **Member login + a "my orders" account view** → the **members** vertical
114
225
  (`references/members/INSTRUCTIONS.md`): ordering/reserving works anonymously, but signing a member
115
- in (custom login on your own UI) lets them see their own order/reservation history.
226
+ in lets them see their own order/reservation history.
116
227
 
117
- Keep the snippets as the default for everything they already do; reach for the API reference only
118
- for the gap.
228
+ Fallback only — when you hit an error or need something not shown here: read the relevant shipped
229
+ file under `src/`, or look it up via the **`wix-docs`** skill.
230
+
231
+ ## Hard rules
232
+ - Set `WIX_CLIENT_ID` (STEP 2) — not the placeholder.
233
+ - Style via base44 design tokens (`index.css` / shadcn Tailwind classes), never by rewriting the shipped components or adding a parallel theme file.
234
+ - Header/footer live in a `Layout` around `<Outlet/>` (STEP 4) — never edit the shipped `Menu`/`Reservations` to add chrome.
235
+ - The Layout's fixed top region owns positioning: `<WixManageBanner/>` above `<Header/>`; your `Header` is plain in-flow markup (not `position:fixed`).
236
+ - Order through the shipped cart: `addItem()` → `checkout()` (redirect-session) — never a hand-built `/checkout`, ordering, or reservation URL.
237
+ - Reservations: offer only `AVAILABLE` slots; pass the hold's `revision` into reserve; `firstName` + `phone` (E.164) are mandatory.
238
+ - Render live Wix data or the shipped empty / "unavailable" state — never mock menus, items, prices, operations, locations, slots, or reviews.
119
239
 
120
240
  ## Point the user to their dashboard
121
- In some cases, users need to access the Wix dashboard in order to edit the restaurant content for their site — across up to three apps. To facilitate this, provide the user with deep links directly to the relevant dashboard pages; only mention the apps the project actually uses. Those pages are:
241
+ Provide deep links so the owner can edit content across the apps they actually use (substitute the
242
+ site's `metaSiteId` from the handoff / `ListWixSites`):
122
243
  - **Menu** (always) — `https://manage.wix.com/dashboard/{metaSiteId}/wix-restaurants-menus-new` (`Dashboard → Restaurant Menus`; click **Manage Items** to add dishes; only visible menus appear in the app)
123
- - **Online ordering** (if wired) — `https://manage.wix.com/dashboard/{metaSiteId}/wix-restaurants-orders-new/settings` (`Dashboard → Restaurant Orders → Settings`). Enable at least one fulfillment method before the site accepts orders — each has its own page: pickup `https://manage.wix.com/dashboard/{metaSiteId}/wix-restaurants-orders-new/settings/pickup`, delivery `.../wix-restaurants-orders-new/settings/delivery`, dine-in `.../wix-restaurants-orders-new/settings/dine-in`.
244
+ - **Online ordering** (if wired) — `https://manage.wix.com/dashboard/{metaSiteId}/wix-restaurants-orders-new/settings` (`Dashboard → Restaurant Orders → Settings`). Enable at least one fulfillment method before the site accepts orders: pickup `.../wix-restaurants-orders-new/settings/pickup`, delivery `.../settings/delivery`, dine-in `.../settings/dine-in`.
124
245
  - **Table reservations** (if wired) — `https://manage.wix.com/dashboard/{metaSiteId}/wix-table-reservations/table-reservations` (`Dashboard → Table Reservations` → **Settings**; configure tables, availability, and enable online reservations)
125
246
 
126
- Substitute the site's `metaSiteId` to complete the links (you have it from the handoff / `ListWixSites`). Include the in-dashboard navigation as a fallback.
127
-
128
- ## Verification checklist (before declaring done)
129
- - [ ] `WIX_CLIENT_ID` set to the prompt's value (not the `<YOUR-CLIENT-ID>` placeholder)
130
- - [ ] Visitor token persists across reload (cart survives reload, same visitor)
131
- - [ ] `getFullMenu()` renders real sections/items with prices, variants, modifiers, and labels
132
- - [ ] Empty state shown when there are no menus (never invented items)
133
- - [ ] Add to cart works with a real `operationId`/`menuId`/`sectionId`; out-of-stock items throw
134
- - [ ] Quantity update / remove reflect in `getCurrentCart()`
135
- - [ ] Checkout redirects via redirect-session `fullUrl` (no hand-built URL); cart re-fetched on return
136
- - [ ] Reservations: only `AVAILABLE` slots offered; hold → reserve produces `RESERVED`/`REQUESTED`
137
- - [ ] No mock data anywhere
138
- - [ ] Told the user at least once that they can continue setting up their restaurant (menu / ordering / reservations) in the dashboard and provided deep links.
247
+ Tell the user at least once that they can keep setting up their restaurant (menu / ordering /
248
+ reservations) in the dashboard, and include the in-dashboard navigation as a fallback.
249
+
250
+ ## Seeding
251
+ Seed the menu (and ordering/reservation setup) per `seed/SEED.md` — separate from this client build;
252
+ run in parallel.
253
+
254
+ ## Verify (before declaring done)
255
+ - [ ] Client files copied into `src/`; `WIX_CLIENT_ID` set (not the placeholder).
256
+ - [ ] Brand palette lives in `index.css` (`:root`/`.dark`); no parallel theme file; shipped components/pages not restyled or rewritten.
257
+ - [ ] Opened `/menu` and `/reservations` (not just the home page) and confirmed the shipped components render themed (surface, text, brand) with images.
258
+ - [ ] `Layout` (fixed `<WixManageBanner/>` + `<Header/>` region, then `<Outlet/>` + Footer) wraps all routes; shipped `Menu`/`Reservations` untouched; content clears the fixed chrome; `<OrderCartProvider>` wraps the tree; `<OrderCartDrawer/>` mounted; `<OrderCartButton/>` in the header.
259
+ - [ ] `getFullMenu()` renders real sections/items with prices, variants, modifiers, and labels; empty catalog shows the shipped empty state (no mock items).
260
+ - [ ] Add to order works with a real operation (or shows "ordering unavailable"); order survives reload (same visitor); update-qty / remove work; checkout redirects and re-fetches on return.
261
+ - [ ] Reservations: only `AVAILABLE` slots offered; hold → reserve produces `RESERVED`/`REQUESTED`; no locations shows the shipped empty state.
262
+ - [ ] Told the user they can continue setting up in the dashboard, with deep links.
@@ -0,0 +1,81 @@
1
+ // Item detail modal — thin view over useItemOrder (all add-to-cart logic lives in the hook). Shows
2
+ // the dish's image, description, price/variants, and modifier groups (name + rule + each modifier's
3
+ // up-charge / stock), a quantity stepper, and an add-to-cart button. Modifier groups are shown for
4
+ // the diner's information only — the shipped addItemToCart does not send selections (see the hook).
5
+ // Styled with base44 design tokens (shadcn Tailwind classes). Pass the item plus the { menuId, sectionId } it was shown under.
6
+ import { useItemOrder } from "@/hooks/useItemOrder";
7
+
8
+ function imageUrl(img) {
9
+ const url = img?.url;
10
+ return url ? (url.startsWith("//") ? `https:${url}` : url) : null;
11
+ }
12
+ function formatPrice(price) {
13
+ return price == null ? "" : `$${price}`; // swap "$" for the site's currency
14
+ }
15
+
16
+ export default function ItemDialog({ item, menuId, sectionId, onClose }) {
17
+ const d = useItemOrder(item, { menuId, sectionId });
18
+ if (!item) return null;
19
+ const image = imageUrl(item.image);
20
+
21
+ return (
22
+ <div onClick={onClose} className="fixed inset-0 z-[60] bg-black/45 flex items-end justify-center">
23
+ <div onClick={(e) => e.stopPropagation()}
24
+ className="w-[min(560px,100%)] max-h-[92vh] overflow-y-auto bg-background text-foreground rounded-t-lg font-body">
25
+ {image && (
26
+ <div className="aspect-[16/9] bg-card">
27
+ <img src={image} alt={item.name} className="w-full h-full object-cover" />
28
+ </div>
29
+ )}
30
+ <div className="p-4 flex flex-col gap-4">
31
+ <div className="flex justify-between items-start gap-3">
32
+ <h2 className="m-0 font-display">{item.name}</h2>
33
+ <button onClick={onClose} aria-label="Close"
34
+ className="border-none bg-transparent cursor-pointer text-[22px] leading-none text-muted-foreground">×</button>
35
+ </div>
36
+ {item.description && <p className="m-0 text-muted-foreground leading-[1.55]">{item.description}</p>}
37
+
38
+ {/* price: single string OR one-of variants — neither carries a currency symbol */}
39
+ {item.price != null
40
+ ? <p className="m-0 text-xl font-semibold">{formatPrice(item.price)}</p>
41
+ : item.variants?.length > 0 && (
42
+ <div className="flex flex-wrap gap-3">
43
+ {item.variants.map((v) => (
44
+ <span key={v.variantId}>{v.name}: <strong>{formatPrice(v.price)}</strong></span>
45
+ ))}
46
+ </div>
47
+ )}
48
+
49
+ {/* modifier groups — displayed for the diner; selections are not sent by the shipped add-to-cart */}
50
+ {item.modifierGroups?.map((group) => (
51
+ <div key={group.id} className="border-t border-border pt-4">
52
+ <h4 className="m-0 mb-2 font-display">
53
+ {group.name}
54
+ {group.rule?.required && <span className="text-primary text-[13px]"> · required</span>}
55
+ </h4>
56
+ <div className="flex flex-col gap-1">
57
+ {group.modifiers.map((m) => (
58
+ <div key={m.id} className={`flex justify-between ${m.inStock ? "text-foreground" : "text-muted-foreground"}`}>
59
+ <span>{m.name}{!m.inStock && " (sold out)"}</span>
60
+ {m.additionalCharge && m.additionalCharge !== "0" && <span>+{formatPrice(m.additionalCharge)}</span>}
61
+ </div>
62
+ ))}
63
+ </div>
64
+ </div>
65
+ ))}
66
+
67
+ <div className="flex items-center gap-3 mt-1">
68
+ <input type="number" min={1} value={d.quantity}
69
+ onChange={(e) => d.setQuantity(Math.max(1, Number(e.target.value) || 1))}
70
+ className="w-[72px] p-2.5 text-center border border-input rounded-sm bg-background text-foreground" />
71
+ <button disabled={!d.canAdd} onClick={d.submit}
72
+ className="flex-1 py-3 px-6 cursor-pointer bg-primary text-primary-foreground border-none rounded-sm text-[15px] font-semibold disabled:opacity-50 disabled:cursor-not-allowed">
73
+ {!d.ordering ? "Ordering unavailable" : d.inStock ? (d.adding ? "Adding…" : "Add to order") : "Sold out"}
74
+ </button>
75
+ </div>
76
+ {d.error && <p className="m-0 text-destructive text-sm">{d.error}</p>}
77
+ </div>
78
+ </div>
79
+ </div>
80
+ );
81
+ }
@@ -0,0 +1,71 @@
1
+ // One dish/drink tile. Styled with base44 design tokens (shadcn Tailwind classes) — re-skin via the
2
+ // app's design tokens (src/index.css :root/.dark), not this JSX. The load-bearing bits: item.image is
3
+ // an OBJECT (render .url, never the object) with a `//`-protocol fix; price is EITHER item.price
4
+ // (single) OR item.variants[] (one-of, each { name, price }); MENU prices carry NO currency symbol
5
+ // (formatPrice adds one — swap it for the site's currency). Clicking the card opens the item dialog
6
+ // (add-to-cart lives there).
7
+ function imageUrl(img) {
8
+ const url = img?.url;
9
+ return url ? (url.startsWith("//") ? `https:${url}` : url) : null;
10
+ }
11
+
12
+ // Restaurants MENU prices are plain decimal strings with NO currency symbol ("12.50").
13
+ function formatPrice(price) {
14
+ return price == null ? "" : `$${price}`; // swap "$" for the site's currency
15
+ }
16
+
17
+ export default function MenuItemCard({ item, onOpen }) {
18
+ const image = imageUrl(item.image);
19
+ const soldOut = item.orderSettings?.inStock === false;
20
+
21
+ return (
22
+ <article
23
+ onClick={() => onOpen?.(item)}
24
+ className={`flex flex-col text-foreground bg-card border border-border rounded-lg overflow-hidden shadow-sm ${onOpen ? "cursor-pointer" : "cursor-default"}`}>
25
+ {image && (
26
+ <div className="relative aspect-[4/3] bg-background">
27
+ <img src={image} alt={item.name} loading="lazy"
28
+ className="w-full h-full object-cover" />
29
+ {soldOut && (
30
+ <span className="absolute top-2 left-2 py-0.5 px-2 text-xs bg-destructive text-destructive-foreground rounded-sm">Sold out</span>
31
+ )}
32
+ </div>
33
+ )}
34
+ <div className="p-3 flex flex-col gap-1.5">
35
+ <div className="flex justify-between items-baseline gap-2">
36
+ {/* Clamped like the storefront tile: the same title-beside-price row turns a long name
37
+ into three ragged lines. */}
38
+ <h3 className="m-0 font-display text-base font-semibold line-clamp-2">
39
+ {item.name}{item.featured && <span className="text-primary"> ★</span>}
40
+ </h3>
41
+ {/* price: single string, OR one-of variants — render one label per variant */}
42
+ {item.price != null
43
+ ? <span className="font-semibold whitespace-nowrap">{formatPrice(item.price)}</span>
44
+ : null}
45
+ </div>
46
+ {item.description && (
47
+ <p className="m-0 text-muted-foreground text-sm leading-[1.45]">{item.description}</p>
48
+ )}
49
+ {item.price == null && item.variants?.length > 0 && (
50
+ <div className="flex flex-wrap gap-2">
51
+ {item.variants.map((v) => (
52
+ <span key={v.variantId} className="text-[13px] text-foreground">
53
+ {v.name}: <strong>{formatPrice(v.price)}</strong>
54
+ </span>
55
+ ))}
56
+ </div>
57
+ )}
58
+ {item.labels?.length > 0 && (
59
+ <div className="flex flex-wrap gap-2 mt-0.5">
60
+ {item.labels.map((label) => (
61
+ <span key={label.id} className="inline-flex items-center gap-1 text-xs text-muted-foreground border border-border rounded-full py-0.5 px-2">
62
+ {imageUrl(label.icon) && <img src={imageUrl(label.icon)} alt="" className="w-3 h-3" />}
63
+ {label.name}
64
+ </span>
65
+ ))}
66
+ </div>
67
+ )}
68
+ </div>
69
+ </article>
70
+ );
71
+ }
@@ -0,0 +1,43 @@
1
+ // Renders the assembled getFullMenu() tree: menus → sections → item cards, with the empty state.
2
+ // This is the menu render surface's body (the Menu page is a thin wrapper). Ordered already by
3
+ // the helper (sectionIds / itemIds). Styled with base44 design tokens (shadcn Tailwind classes). Each
4
+ // card's onOpen gets the item plus the menuId/sectionId it was shown under — ordering needs both.
5
+ import MenuItemCard from "./MenuItemCard";
6
+
7
+ function imageUrl(img) {
8
+ const url = img?.url;
9
+ return url ? (url.startsWith("//") ? `https:${url}` : url) : null;
10
+ }
11
+
12
+ export default function MenuList({ menus, onOpenItem, empty = "No menu yet — add one from your Wix dashboard." }) {
13
+ if (!menus?.length) {
14
+ return <p className="text-muted-foreground p-4 text-center">{empty}</p>;
15
+ }
16
+ return (
17
+ <div className="flex flex-col gap-8">
18
+ {menus.map((menu) => (
19
+ <section key={menu.id}>
20
+ <h2 className="font-display mb-1">{menu.name}</h2>
21
+ {menu.description && (
22
+ <p className="text-muted-foreground mb-4">{menu.description}</p>
23
+ )}
24
+ {menu.sections.map((section) => (
25
+ <div key={section.id} className="mb-6">
26
+ <h3 className="font-display mb-4">{section.name}</h3>
27
+ {imageUrl(section.image) && (
28
+ <img src={imageUrl(section.image)} alt={section.name} loading="lazy"
29
+ className="w-full max-h-[220px] object-cover rounded-lg mb-4" />
30
+ )}
31
+ <div className="grid gap-4 [grid-template-columns:repeat(auto-fill,minmax(260px,1fr))]">
32
+ {section.items.map((item) => (
33
+ <MenuItemCard key={item.id} item={item}
34
+ onOpen={() => onOpenItem?.(item, { menuId: menu.id, sectionId: section.id })} />
35
+ ))}
36
+ </div>
37
+ </div>
38
+ ))}
39
+ </section>
40
+ ))}
41
+ </div>
42
+ );
43
+ }