@wix/agent-skills 1.19.2 → 1.20.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.
- package/package.json +1 -1
- package/skills/wix-app/references/SERVICE_PLUGIN.md +14 -1
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +7 -6
- package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +4 -0
- package/skills/wix-app/references/service-plugin/AVAILABILITY-TIME-SLOTS-CONFIGURATION.md +118 -0
- package/skills/wix-app/references/service-plugin/BOOKING-POLICY.md +65 -0
- package/skills/wix-app/references/service-plugin/BOOKINGS-PRICING.md +71 -0
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +11 -3
- package/skills/wix-app/references/service-plugin/BOOKINGS-VALIDATION.md +137 -0
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +23 -16
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +4 -0
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +4 -2
- package/skills/wix-app/references/service-plugin/REALTIME-PERMISSIONS.md +45 -0
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +15 -0
- package/skills/wix-app/references/service-plugin/TOOLS_PROVIDER.md +4 -0
- package/skills/wix-app/references/service-plugin/VALIDATIONS.md +4 -0
- package/skills/wix-headless/references/CAPABILITIES.md +2 -2
- package/skills/wix-headless/references/inline-recipes/experience-store.md +4 -3
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +98 -18
- package/skills/wix-headless/references/managed/DEPLOYMENT.md +8 -8
- package/skills/wix-headless-fast/SKILL.md +200 -34
- package/skills/wix-headless-fast/entry/skill.md +10 -2
- package/skills/wix-headless-fast/install/attach.mjs +253 -0
- package/skills/wix-headless-fast/install/deploy.mjs +109 -9
- package/skills/wix-headless-fast/install/fast-path.mjs +28 -31
- package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +224 -60
- package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +2 -3
- package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +2 -3
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +24 -116
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +16 -64
- package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +137 -0
- package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +78 -0
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +117 -0
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +13 -60
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +47 -0
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +10 -28
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +2 -4
- package/skills/wix-headless-fast/references/blog/rest/posts.ts +42 -0
- package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +62 -0
- package/skills/wix-headless-fast/references/blog/seed/SEED.md +9 -0
- package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +179 -33
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +2 -1
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +26 -132
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +18 -49
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +218 -0
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +169 -0
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +57 -142
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +92 -0
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +90 -0
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +22 -61
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +3 -1
- package/skills/wix-headless-fast/references/bookings/rest/booking.ts +113 -0
- package/skills/wix-headless-fast/references/bookings/rest/services.ts +55 -0
- package/skills/wix-headless-fast/references/bookings/seed/SEED.md +10 -0
- package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +236 -62
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +19 -52
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +16 -36
- package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +158 -0
- package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +93 -0
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +177 -0
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +13 -41
- package/skills/wix-headless-fast/references/cms/rest/items.ts +125 -0
- package/skills/wix-headless-fast/references/cms/seed/SEED.md +9 -0
- package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +239 -83
- package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +1 -1
- package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +7 -5
- package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +2 -2
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +28 -110
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +19 -54
- package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +130 -0
- package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +97 -0
- package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +13 -94
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +113 -0
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +156 -0
- package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +38 -69
- package/skills/wix-headless-fast/references/events/rest/events.ts +57 -0
- package/skills/wix-headless-fast/references/events/rest/registration.ts +83 -0
- package/skills/wix-headless-fast/references/events/seed/SEED.md +9 -0
- package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +214 -26
- package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +35 -267
- package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +332 -0
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +238 -0
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +28 -243
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +216 -0
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +32 -204
- package/skills/wix-headless-fast/references/forms/rest/forms.ts +34 -0
- package/skills/wix-headless-fast/references/forms/rest/submissions.ts +56 -0
- package/skills/wix-headless-fast/references/forms/seed/SEED.md +8 -0
- package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +15 -8
- package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +314 -63
- package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +1 -1
- package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +105 -0
- package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +36 -65
- package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +1 -1
- package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +43 -0
- package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +11 -32
- package/skills/wix-headless-fast/references/members/rest/auth.ts +215 -0
- package/skills/wix-headless-fast/references/members/rest/members.ts +26 -0
- package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +238 -59
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +2 -2
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +2 -2
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +35 -0
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +8 -38
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +23 -50
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +16 -34
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +22 -49
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +82 -0
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +58 -0
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +177 -0
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +31 -118
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +81 -0
- package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +75 -0
- package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +8 -0
- package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +212 -51
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +9 -20
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +7 -32
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +41 -0
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +12 -33
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +17 -34
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +54 -0
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +106 -0
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +64 -0
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +7 -55
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +43 -0
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +11 -34
- package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +31 -0
- package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +20 -0
- package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +8 -0
- package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +240 -47
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +2 -2
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +2 -2
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +14 -35
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +28 -171
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +155 -0
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +89 -0
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +23 -117
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +124 -0
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +45 -114
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +193 -0
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +94 -0
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +15 -87
- package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +60 -0
- package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +169 -0
- package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +68 -0
- package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +8 -0
- package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +23 -0
- package/skills/wix-headless-fast/references/shared/app/wix/media.ts +55 -1
- package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +13 -0
- package/skills/wix-headless-fast/references/shared/rest/client.ts +155 -0
- package/skills/wix-headless-fast/references/shared/rest/config.ts +3 -0
- package/skills/wix-headless-fast/references/shared/rest/media.ts +65 -0
- package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +371 -81
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +37 -3
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +266 -0
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +95 -0
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +136 -0
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +29 -130
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +26 -182
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +121 -0
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +53 -136
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +309 -0
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +73 -230
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +147 -0
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +289 -0
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +62 -4
- package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +21 -2
- package/skills/wix-headless-fast/references/storefront/rest/cart.ts +132 -0
- package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +123 -0
- package/skills/wix-headless-fast/references/storefront/seed/SEED.md +25 -5
- package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +24 -0
- package/skills/wix-manage/SKILL.md +4 -1
- package/skills/wix-manage/references/ecommerce/ecom-shipping.md +1 -1
- package/skills/wix-manage/references/events/create-wix-event.md +46 -0
- package/skills/wix-manage/references/events/manage-wix-events.md +51 -1
- package/skills/wix-manage/references/google-ads/manage-campaign-lifecycle.md +6 -6
- package/skills/wix-manage/references/seo/manage-seo-suggestions.md +351 -0
- package/skills/wix-vibe-headless/install/deploy.cjs +33 -2
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed-with-install.md +1 -1
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +13 -4
- package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +1 -1
- package/skills/wix-vibe-headless/platforms/base44.md +19 -4
- package/skills/wix-vibe-headless/platforms/generic.md +6 -0
- package/skills/wix-vibe-headless/references/_shared/nav/nav.tanstack.js +30 -0
- package/skills/wix-vibe-headless/references/_shared/routing.md +86 -0
- package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +44 -0
- package/skills/wix-vibe-headless/references/blog/app/components/PostCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/blog/app/components/PostChips.jsx +1 -1
- package/skills/wix-vibe-headless/references/blog/app/pages/CategoryPage.jsx +1 -1
- package/skills/wix-vibe-headless/references/blog/app/pages/PostDetail.jsx +1 -1
- package/skills/wix-vibe-headless/references/blog/app/pages/TagPage.jsx +1 -1
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +42 -0
- package/skills/wix-vibe-headless/references/bookings/app/components/ServiceCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/bookings/app/pages/ServiceDetail.jsx +1 -1
- package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +42 -0
- package/skills/wix-vibe-headless/references/events/app/components/EventCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/events/app/pages/EventDetail.jsx +1 -1
- package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +42 -0
- package/skills/wix-vibe-headless/references/members/app/components/MemberMenu.jsx +1 -1
- package/skills/wix-vibe-headless/references/members/app/components/RequireAuth.jsx +1 -1
- package/skills/wix-vibe-headless/references/members/app/pages/Login.jsx +1 -1
- package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +43 -0
- package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/portfolio/app/pages/CollectionPage.jsx +1 -1
- package/skills/wix-vibe-headless/references/portfolio/app/pages/ProjectDetail.jsx +1 -1
- package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +43 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanCard.jsx +1 -1
- package/skills/wix-vibe-headless/references/pricing-plans/app/pages/PlanDetail.jsx +1 -1
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +36 -0
- package/skills/wix-vibe-headless/references/shared/app/lib/nav.js +9 -0
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +42 -41
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductCard.js +7 -1
- package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +3 -0
- package/skills/wix-vibe-headless/references/storefront/seed/seed-store.cjs +6 -0
- package/skills/wix-headless-fast/install/pin-agents-md.mjs +0 -57
|
@@ -10,28 +10,40 @@ ordering or reservation logic; you never skip designing.
|
|
|
10
10
|
|
|
11
11
|
## The file map (deployed into `src/`)
|
|
12
12
|
|
|
13
|
-
**
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
**On Astro and React the shipped files are tested and work as they are** — this table and the
|
|
14
|
+
contracts below are everything you need to use them, so don't spend the run reading their source;
|
|
15
|
+
wire them and build your surfaces. Reading them is the right move when something is off (a runtime
|
|
16
|
+
error, a field this playbook doesn't cover) or when the brief wants a behaviour they don't offer —
|
|
17
|
+
then read the file that owns it and change or extend it. On `lib`, `static`, and a port the
|
|
18
|
+
components don't deploy at all, and each wiring section below opens with the files to read before
|
|
19
|
+
writing their equivalents. Files you edit: `SiteLayout.astro`, `styles/global.css`, and the two
|
|
20
|
+
pages' island imports. Files you **create**: your menu, cart-chrome, and reservation components,
|
|
21
|
+
plus your home page.
|
|
16
22
|
|
|
17
23
|
| file | what it is |
|
|
18
24
|
|---|---|
|
|
19
|
-
| `wix/config.ts` · `wix/sdk.ts`
|
|
25
|
+
| `wix/config.ts` · `wix/sdk.ts` | shared auth seam (deploy configures it — nothing to set by hand) |
|
|
26
|
+
| `wix/media.ts` · `wix/money.ts` | `imgAttrs(url, sizes)` — every `<img>` attribute for a DTO image (`src`, `srcSet`, `sizes`, lazy): `<img {...imgAttrs(item.imageUrl, "6rem")} alt={item.name} />`; `imgSrc()` / `imgSrcSet()` / `formatMoney()` underneath, already used by everything shipped |
|
|
20
27
|
| `wix/restaurants/types.ts` | the DTOs (`MenuData`, `MenuSection`, `MenuItem`, `OrderCart`, `ReservationSlot`, …) — contracts below |
|
|
21
|
-
| `wix/restaurants/menu.ts` | `fetchMenus` — the whole display-ordered menu tree, one call |
|
|
22
|
-
| `wix/restaurants/ordering.ts` · `order-store.ts` | dish add-to-cart (Orders-app catalogReference) + eCom Cart V2 + shared cart state (module store — spans Astro islands) |
|
|
23
|
-
| `wix/restaurants/reservations.ts` | locations, AVAILABLE slots, `holdReservation`, `completeReservation` — the exact hold→reserve sequence
|
|
24
|
-
| `
|
|
25
|
-
| `hooks/restaurants/
|
|
26
|
-
| `hooks/restaurants/
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
28
|
+
| `wix/restaurants/menu.ts` | `fetchMenus` — the whole display-ordered menu tree, one call; the transport only — the id-array stitching and item mapping are in `menu-core.ts` beside it (shared with the REST layer) |
|
|
29
|
+
| `wix/restaurants/ordering.ts` · `order-store.ts` | dish add-to-cart (Orders-app `catalogReference`) + eCom Cart V2 + the hosted checkout, and the shared cart state (module store — spans Astro islands); the request shapes and refusal checks are in `ordering-core.ts` |
|
|
30
|
+
| `wix/restaurants/reservations.ts` | locations, AVAILABLE slots, `holdReservation`, `completeReservation` — the exact hold → reserve sequence; the mappers and the reservee body are in `reservations-core.ts` |
|
|
31
|
+
| `wix/restaurants/menu-store.ts` · `reservation-store.ts` | the menu-browsing and reservation state machines, framework-free (`createMenuStore()`, `createReservationStore()` — `getState`/`subscribe` + actions, one instance per surface); the hooks below bind them to React, every other stack uses them directly |
|
|
32
|
+
| `hooks/restaurants/useMenus.ts` | React binding of `menu-store.ts`: menu browsing + menu switching — contract below |
|
|
33
|
+
| `hooks/restaurants/useOrderCart.ts` | React binding of `order-store.ts`: order-cart state + actions — contract below |
|
|
34
|
+
| `hooks/restaurants/useReservation.ts` | React binding of `reservation-store.ts`: the whole reservation state machine — contract below |
|
|
35
|
+
| `components/restaurants/MenuView.tsx` (+ `MenuItemCard`) · `OrderCartButton.tsx` · `OrderCartDrawer.tsx` · `ReservationView.tsx` | **reference implementations** — tested, plain, on the tokens; the layout mounts the cart chrome as shipped, and you replace all four with your own designs (new file names) |
|
|
36
|
+
| `styles/global.css` | **the design system**: Tailwind v4 + the `@theme` token block (colors, radii, fonts — shared across verticals). Everything, shipped and yours, styles from these tokens |
|
|
37
|
+
|
|
38
|
+
The same data layer ships a second time as REST in `references/restaurants/rest/` (`menu.ts`,
|
|
39
|
+
`ordering.ts`, `reservations.ts` — the same exports over `fetch`, importing the same `*-core.ts`);
|
|
40
|
+
`deploy.mjs --stack static` composes it with the stores into `js/wix/` (wiring below).
|
|
29
41
|
|
|
30
42
|
Astro stack additionally gets:
|
|
31
43
|
|
|
32
44
|
| file | what it is |
|
|
33
45
|
|---|---|
|
|
34
|
-
| `layouts/SiteLayout.astro` | site chrome — **yours to brand** (keep the `seo-tags` slot, global.css import, and one OrderCartButton + one OrderCartDrawer
|
|
46
|
+
| `layouts/SiteLayout.astro` | site chrome — **yours to brand** (keep the `seo-tags` slot, the global.css import, and one `OrderCartButton` + one `OrderCartDrawer`, both `client:only`). If another vertical is also deployed, its layout won — merge the Menu/Reservations links + cart mounts there |
|
|
35
47
|
| `pages/menu.astro` | SSR menu — **keep the frontmatter**, swap the island import to YOUR component |
|
|
36
48
|
| `pages/reservations.astro` | reservations — the island stays `client:only="react"` (availability is timezone-specific); swap the import to YOUR component |
|
|
37
49
|
|
|
@@ -51,9 +63,30 @@ Astro stack additionally gets:
|
|
|
51
63
|
your cards; `item.featured` marks highlights), hours/location story, reserve CTA.
|
|
52
64
|
|
|
53
65
|
Plus the **theme** (`@theme` block, one edit) and the **chrome** (`SiteLayout`, one pass).
|
|
54
|
-
Style everything with Tailwind utilities on the tokens.
|
|
55
66
|
|
|
56
|
-
###
|
|
67
|
+
### What a complete restaurant site shows (recommended defaults)
|
|
68
|
+
|
|
69
|
+
Defaults for a brief that says nothing about them; the prompt wins when it asks for something
|
|
70
|
+
else. Look at the seeded menu before designing (how many menus, sections, photos, variants).
|
|
71
|
+
|
|
72
|
+
- **Menu:** dish names in view-source (the page fetches server-side and passes `initialMenus`);
|
|
73
|
+
sections in the menu's own order; a dish card shows name, description, price (or its
|
|
74
|
+
variants, or "Market price"), labels, and the add control; skeletons while `menus === null`,
|
|
75
|
+
an honest empty state for `[]`.
|
|
76
|
+
- **Add control:** three states from the data — "Add to order", "Sold out" (`!inStock`),
|
|
77
|
+
"Ordering unavailable" (`ordering === false`); a market-priced dish has no control. Adding
|
|
78
|
+
opens the cart drawer on its own; the header badge is the live `itemCount`.
|
|
79
|
+
- **Cart:** lines with quantity stepper and remove, `subtotal` as given, checkout as a button in
|
|
80
|
+
the drawer; the order survives a reload (same visitor token) — nothing to wire.
|
|
81
|
+
- **Reservations:** only AVAILABLE times offered; hold → details form → confirm; `RESERVED`
|
|
82
|
+
reads as confirmed, `REQUESTED` as "pending the restaurant's approval"; the toggle-off and
|
|
83
|
+
not-set-up cases read as "call us to book", never as a broken form.
|
|
84
|
+
- **Overlays you build** (cart drawer, mobile nav): mount at the document root, lock background
|
|
85
|
+
scroll, close on Escape, return focus on close — as the shipped `OrderCartDrawer` does.
|
|
86
|
+
- **Copy:** nothing the restaurant didn't supply — no invented hours, reviews, or delivery
|
|
87
|
+
promises; no Wix IDs or technical words in visible text.
|
|
88
|
+
|
|
89
|
+
### The contracts your components consume (tested and work as they are; read the source when something is off or the brief wants more)
|
|
57
90
|
|
|
58
91
|
```ts
|
|
59
92
|
// MenuData → sections → items, all display-ordered:
|
|
@@ -63,9 +96,9 @@ Style everything with Tailwind utilities on the tokens.
|
|
|
63
96
|
// modifierGroups: [{ id, name, required, minSelections, maxSelections,
|
|
64
97
|
// modifiers: [{ id, name, preSelected, additionalCharge, inStock }] }],
|
|
65
98
|
// inStock, featured }
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
99
|
+
// MENU prices carry NO currency symbol unless the platform formatted them — render as given;
|
|
100
|
+
// if plain decimals, prefix the brand's currency yourself. Order-cart prices ARE formatted.
|
|
101
|
+
// Modifier groups are DISPLAY-ONLY (selections aren't sent on the cart line).
|
|
69
102
|
|
|
70
103
|
// useMenus({ initialMenus? }) →
|
|
71
104
|
// { menus: MenuData[]|null /* null = loading → skeletons */,
|
|
@@ -81,6 +114,8 @@ Style everything with Tailwind utilities on the tokens.
|
|
|
81
114
|
// openCart(), closeCart(), refresh() }
|
|
82
115
|
// OrderLine = { lineItemId, itemName, quantity, unitPrice, linePrice, imageUrl,
|
|
83
116
|
// descriptionLines, status /* not "IN_STOCK" → can't check out */ }
|
|
117
|
+
// addToOrder rejects on refusal (no ordering operation, a sold-out dish) AND records .error,
|
|
118
|
+
// opening the drawer on success — render .error in your cart surface and beside the add control.
|
|
84
119
|
|
|
85
120
|
// useReservation() →
|
|
86
121
|
// { locations: [{ id, partySizeMin, partySizeMax, approvalMode, onlineReservationsEnabled }]|null,
|
|
@@ -92,8 +127,76 @@ Style everything with Tailwind utilities on the tokens.
|
|
|
92
127
|
// canConfirm, confirm(), // gate the CTA on canConfirm
|
|
93
128
|
// confirmed: { reservationId, status: "RESERVED"|"REQUESTED" }|null,
|
|
94
129
|
// reset(), loading, error }
|
|
130
|
+
// ReservationSlot = { startIso, label /* "7:00 PM" */, dayKey, durationMinutes, manualApproval }.
|
|
131
|
+
// The hold and reserve calls are premium-gated: on a non-premium site they fail with
|
|
132
|
+
// "site must be premium" in .error — render it, don't retry.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### The islands you create — skeletons
|
|
136
|
+
|
|
137
|
+
The class names in the shipped components are the Astro/React spelling of layout rules that hold
|
|
138
|
+
on every stack; on a stack where they don't deploy, keep the rule and write it in your own CSS.
|
|
139
|
+
Hooks first, branches after (an early return above a hook changes hook order and React throws).
|
|
140
|
+
The menu island renders on the server too (`client:load`); nothing in a render path may throw.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
// src/components/restaurants/YourMenu.tsx — YOU build it; pages/menu.astro mounts it with initialMenus.
|
|
144
|
+
import { useMenus } from "../../hooks/restaurants/useMenus";
|
|
145
|
+
import { useOrderCart } from "../../hooks/restaurants/useOrderCart";
|
|
146
|
+
import { imgAttrs } from "../../wix/media";
|
|
147
|
+
import type { MenuData } from "../../wix/restaurants/types";
|
|
148
|
+
|
|
149
|
+
export default function YourMenu({ initialMenus }: { initialMenus?: MenuData[] }) {
|
|
150
|
+
const { menus, activeMenuId, setActiveMenuId, activeMenu, error } = useMenus({ initialMenus });
|
|
151
|
+
const { addToOrder, ordering, busy } = useOrderCart();
|
|
152
|
+
// …you implement the render:
|
|
153
|
+
// • menus === null → skeletons; [] → your empty state (error when set)
|
|
154
|
+
// • menu tabs when menus.length > 1 (setActiveMenuId); a section nav when activeMenu.sections.length > 1
|
|
155
|
+
// • per section, YOUR dish card: <img {...imgAttrs(item.imageUrl, "6rem")} alt={item.name} /> when
|
|
156
|
+
// item.imageUrl, name, description, item.marketPrice ? "Market price" : item.price ?? variants,
|
|
157
|
+
// labels, modifier groups as text (display-only)
|
|
158
|
+
// • the add control calls addToOrder(item.id, { menuId: activeMenu.id, sectionId: section.id }) —
|
|
159
|
+
// the ids of the menu and section the card is rendered under, never looked up again; disabled
|
|
160
|
+
// when !item.inStock ("Sold out"), ordering === false ("Ordering unavailable"), or busy; hidden
|
|
161
|
+
// for item.marketPrice; the rejection message rendered beside it
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
// src/components/restaurants/YourReservations.tsx — YOU build it; pages/reservations.astro mounts it client:only.
|
|
167
|
+
import { useReservation } from "../../hooks/restaurants/useReservation";
|
|
168
|
+
|
|
169
|
+
export default function YourReservations() {
|
|
170
|
+
const r = useReservation(); // full contract above — the flow lives HERE
|
|
171
|
+
// …you implement the render, in this order:
|
|
172
|
+
// r.locations === null → loading; [] or !r.location → "call us to book";
|
|
173
|
+
// !r.location.onlineReservationsEnabled → "online reservations aren't open yet";
|
|
174
|
+
// r.confirmed → RESERVED as confirmed, REQUESTED as pending approval, r.reset() to start over;
|
|
175
|
+
// else: guests (bounded by partySizeMin/Max), date, time → r.findSlots(); r.slots as pills →
|
|
176
|
+
// r.holdSlot(slot); r.held → the details form (firstName + phone required) and the confirm
|
|
177
|
+
// button gated by r.canConfirm; r.error inline; a location picker only when locations.length > 1
|
|
178
|
+
}
|
|
95
179
|
```
|
|
96
180
|
|
|
181
|
+
### The reference files for stacks where the components don't deploy
|
|
182
|
+
|
|
183
|
+
On `lib`, `static`, and a port, nothing under `components/` or `hooks/` arrives. The state
|
|
184
|
+
machines behind the hooks do arrive — `wix/restaurants/menu-store.ts`, `reservation-store.ts`,
|
|
185
|
+
`order-store.ts` — so you never rewrite them: create a store per surface, `subscribe`, render from
|
|
186
|
+
`getState()`, call its actions. Their `*State` interfaces are the render contract; read those.
|
|
187
|
+
What you write is the rendering — dish card, menu, cart chrome, reservation form — and for that
|
|
188
|
+
read these first; they are tested code for exactly that behaviour:
|
|
189
|
+
|
|
190
|
+
1. `components/restaurants/MenuView.tsx` — the menu tabs / section nav / dish card, and the
|
|
191
|
+
load-bearing wiring: each card threads its `menuId` + `sectionId` from the render context into
|
|
192
|
+
`addToOrder`; the add control's three states; the rejection message beside it.
|
|
193
|
+
2. `components/restaurants/OrderCartDrawer.tsx` — the cart overlay as working code: lines with
|
|
194
|
+
stepper and remove, `status !== "IN_STOCK"` flagged, subtotal, checkout, `error` rendered.
|
|
195
|
+
3. `components/restaurants/ReservationView.tsx` — the state ladder in order: loading → not set up →
|
|
196
|
+
toggle off → confirmed → query → slots → hold → details form; the confirm gate.
|
|
197
|
+
|
|
198
|
+
All under `references/restaurants/app/`.
|
|
199
|
+
|
|
97
200
|
### Wiring — Astro (default)
|
|
98
201
|
|
|
99
202
|
1. Set the `@theme` tokens (one edit); brand `SiteLayout.astro` (one pass — merge into the
|
|
@@ -105,61 +208,151 @@ Style everything with Tailwind utilities on the tokens.
|
|
|
105
208
|
multiple Writes per message.
|
|
106
209
|
3. Write `pages/index.astro` (home) — it exists from the scaffold; Read it before overwriting.
|
|
107
210
|
|
|
211
|
+
### Wiring — another JS framework (`--stack lib`: Vue, Svelte, Solid, plain Vite)
|
|
212
|
+
|
|
213
|
+
Read the reference files listed above before writing any surface.
|
|
214
|
+
|
|
215
|
+
`deploy.mjs restaurants --stack lib` put the data layer in `src/wix/` and nothing else: `sdk.ts`
|
|
216
|
+
(the visitor client, configured with the public client id), `media.ts`, `money.ts`, and
|
|
217
|
+
`wix/restaurants/` — `menu.ts`, `ordering.ts`, `reservations.ts`, `types.ts`, the `*-core.ts`
|
|
218
|
+
rules, and the three stores `menu-store.ts`, `order-store.ts`, `reservation-store.ts`. None of it
|
|
219
|
+
is React. The hooks and components don't ship on this stack; the stores replace the hooks, and you
|
|
220
|
+
write the components in your framework to the contracts on this page:
|
|
221
|
+
|
|
222
|
+
- bind the stores with your framework's external-store primitive (Vue: `shallowRef` updated in
|
|
223
|
+
`subscribe`; Svelte: `readable(store.getState(), (set) => store.subscribe(() => set(store.getState())))`;
|
|
224
|
+
Solid: a signal set in `subscribe`). `createMenuStore({ initialMenus? })` per menu surface
|
|
225
|
+
(`start()` when mounted, `stop()` when unmounted), `createReservationStore()` per reservation
|
|
226
|
+
surface, the order store as-is (module-level: `subscribeOrderCart`/`getOrderCartState`,
|
|
227
|
+
`addOrderLine`, `updateOrderLineQuantity`, `removeLineFromOrder`, `goToOrderCheckout`,
|
|
228
|
+
`setOrderCartOpen`). State in, actions out — exactly the hooks' contracts above;
|
|
229
|
+
- your dish card, cart drawer, and reservation form to the recommended defaults above — the
|
|
230
|
+
shipped `MenuView.tsx`, `OrderCartDrawer.tsx`, `ReservationView.tsx` are readable as behaviour
|
|
231
|
+
specs.
|
|
232
|
+
|
|
233
|
+
Routes `/menu`, `/reservations`; dev server on 4321; a static build goes through
|
|
234
|
+
`npx @wix/cli@latest release` with `site.outputDirectory` pointing at the build folder, an SSR
|
|
235
|
+
build is hosted by you.
|
|
236
|
+
|
|
237
|
+
### Wiring — static site (`--stack static`, no bundler)
|
|
238
|
+
|
|
239
|
+
Read the reference files listed above before writing any surface.
|
|
240
|
+
|
|
241
|
+
`deploy.mjs restaurants --stack static --out site` put the REST layer in `site/js/wix/` (browser
|
|
242
|
+
ESM, the `.ts` beside each `.js` for reading). Everything the visitor loads lives under `site/` —
|
|
243
|
+
pages, styles, `js/` — and `wix.config.json`'s `site.outputDirectory` is `"./site"`; the project
|
|
244
|
+
root (config, plan, seed output) is never the upload. Same function names and DTOs as the table
|
|
245
|
+
above, so the contracts on this page hold unchanged: `fetchMenus` from `./js/wix/menu.js`;
|
|
246
|
+
`resolveOperationId`, `fetchFulfillmentMethods`, `fetchOrderCart`, `addToOrder`,
|
|
247
|
+
`updateOrderQuantity`, `removeOrderLine`, `orderCheckoutUrl` from `./js/wix/ordering.js`;
|
|
248
|
+
`fetchReservationLocations`, `fetchReservationSlots`, `holdReservation`, `completeReservation`
|
|
249
|
+
from `./js/wix/reservations.js`. The state machines ship too: `createMenuStore` from
|
|
250
|
+
`./js/wix/menu-store.js` (`start()` once the page is up; `initialMenus` when you already have
|
|
251
|
+
them), `./js/wix/order-store.js` (the cart — `subscribeOrderCart`/`getOrderCartState`,
|
|
252
|
+
`addOrderLine`, `updateOrderLineQuantity`, `removeLineFromOrder`, `goToOrderCheckout`,
|
|
253
|
+
`setOrderCartOpen`), and `createReservationStore` from `./js/wix/reservation-store.js` (the whole
|
|
254
|
+
reservation flow). No components ship — you write the rendering in plain JS: one render function
|
|
255
|
+
per surface that reads `getState()`, called from `subscribe`, with the surface's controls calling
|
|
256
|
+
the store's actions. The drawer opens after every add on its own; overlays follow the
|
|
257
|
+
OrderCartDrawer contract (root-level, scroll lock, Escape, focus back). Pages are `menu.html`
|
|
258
|
+
and `reservations.html` (a menu switch is local state, or `menu.html?menu=<slug>` read from the
|
|
259
|
+
query string). Wix static hosting serves files, not directories — name the file and link to it.
|
|
260
|
+
There are no item pages here: set `document.title` and the meta description per page yourself,
|
|
261
|
+
from the menu's `name` once it loads. The visitor token persists in `localStorage` on its own;
|
|
262
|
+
never mint per page. `npx @wix/cli@latest release` uploads `site/`.
|
|
263
|
+
|
|
264
|
+
### Wiring — server-rendered, another language (Flask, Laravel, Rails, …)
|
|
265
|
+
|
|
266
|
+
Read the reference files listed above before writing any surface.
|
|
267
|
+
|
|
268
|
+
Run `deploy.mjs restaurants --stack static` in the project folder anyway: `js/wix/` is both the
|
|
269
|
+
browser-side code and the readable spec. Then split by where the call runs. **The menu on the
|
|
270
|
+
server:** port `js/wix/menu.ts` and `menu-core.ts` to your language — seven GETs with literal
|
|
271
|
+
paths and query params (arrays repeat the key: `?variantIds=a&variantIds=b`), then the id-array
|
|
272
|
+
stitching from the core — returning the same `MenuData` tree as dicts, one anonymous visitor token
|
|
273
|
+
per process for these public reads (mint and refresh per `client.ts`) — and render the menu and
|
|
274
|
+
the home page's featured dishes in your templates, so dish names are in the HTML. **Ordering and
|
|
275
|
+
reservations in the browser:** the cart button and drawer on `./js/wix/order-store.js`, each dish
|
|
276
|
+
card's add control calling `addOrderLine(itemId, { menuId, sectionId })` with the ids the template
|
|
277
|
+
rendered it under (data attributes), the reservation form on `./js/wix/reservation-store.js` —
|
|
278
|
+
exactly as the static wiring above; the browser owns the visitor's token, so the server never
|
|
279
|
+
handles per-visitor tokens. Routes stay `/menu`, `/reservations`. Add your public https origin to
|
|
280
|
+
the OAuth app's allowed domains before checkout can return.
|
|
281
|
+
|
|
282
|
+
**Pre-rendered (Frozen-Flask, Pelican, any static-site generator) → Wix-hosted.** Same port for
|
|
283
|
+
the menu read, run at build time with one anonymous token; the generator emits the menu page(s)
|
|
284
|
+
and the home page. Run `deploy.mjs restaurants --stack static --out <build dir>` so `js/wix/` is
|
|
285
|
+
inside the output the pages import from, point `site.outputDirectory` at that folder,
|
|
286
|
+
`wix release`. Pages sit at different depths: give the templates one base path to `js/wix/` (a
|
|
287
|
+
template variable, or root-relative `/js/wix/…`), never a relative `./js/wix/` — it breaks one
|
|
288
|
+
level down. The frozen menu is the first paint; the add controls, cart, and reservation flow run
|
|
289
|
+
client-side on it from the same modules, so the contracts above apply. Close with the live URL,
|
|
290
|
+
the rebuild + release command, and one line for the owner: dashboard edits to the menu reach the
|
|
291
|
+
site when that command runs; ordering and reservations are live regardless.
|
|
292
|
+
|
|
108
293
|
### Wiring — React SPA (Vite etc.)
|
|
109
294
|
|
|
110
295
|
Import `./styles/global.css` once at the app entry (needs `@tailwindcss/vite` in the vite
|
|
111
296
|
plugins — deploy added the dep). Routes: `/menu` → your menu surface (`useMenus()` fetches
|
|
112
297
|
client-side when no `initialMenus`); `/reservations` → your reservation surface. Mount your
|
|
113
|
-
order button in the header and your drawer once.
|
|
298
|
+
order button in the header and your drawer once. Deploy wrote the public client id into
|
|
299
|
+
`wix/config.ts`; nothing else to configure.
|
|
114
300
|
|
|
115
301
|
## Hard rules
|
|
116
302
|
|
|
117
|
-
- **
|
|
118
|
-
restaurant `catalogReference` (the Orders app id + `operationId`/`menuId`/`sectionId`
|
|
119
|
-
three, no `variantId`), the line-refusal checks, and the checkout redirect. Never
|
|
120
|
-
any of it, never hand-build a checkout URL
|
|
303
|
+
- **Data and ordering logic only through the shipped exports** — `useOrderCart`/`addToOrder`
|
|
304
|
+
own the restaurant `catalogReference` (the Orders app id + `operationId`/`menuId`/`sectionId`
|
|
305
|
+
— all three, no `variantId`), the line-refusal checks, and the checkout redirect. Never
|
|
306
|
+
re-derive any of it, never hand-build a checkout URL; extend by adding a function in
|
|
307
|
+
`wix/restaurants/` for what they don't cover (API contracts: the `wix-docs` skill).
|
|
121
308
|
- **Thread `menuId` + `sectionId` from the render context** — each dish is rendered inside a
|
|
122
309
|
known section of a known menu (the `fetchMenus` tree); pass those ids to `addToOrder`.
|
|
123
310
|
Never look them up again.
|
|
124
311
|
- **Modifier groups are display-only** — show them on the dish (diners read them; staff sees
|
|
125
312
|
choices at the counter), but don't invent a way to send selections: that cart-line shape
|
|
126
313
|
isn't documented. Send quantity only, as shipped.
|
|
127
|
-
- **Reservations only through `useReservation`** — AVAILABLE-only slots, the
|
|
128
|
-
`revision`, the firstName+phone requirement, and the RESERVED/REQUESTED split all live
|
|
129
|
-
the data layer. Gate the CTA on `canConfirm`, surface `error` (holds expire in 10 minutes —
|
|
130
|
-
the
|
|
314
|
+
- **Reservations only through `useReservation`** (or its store) — AVAILABLE-only slots, the
|
|
315
|
+
hold's `revision`, the firstName+phone requirement, and the RESERVED/REQUESTED split all live
|
|
316
|
+
in the data layer. Gate the CTA on `canConfirm`, surface `error` (holds expire in 10 minutes —
|
|
317
|
+
the store already restarts the flow).
|
|
131
318
|
- **The confirmed state must reflect REAL success**: render it only from `confirmed`, and
|
|
132
319
|
render `REQUESTED` as "pending the restaurant's approval", never as confirmed. A visitor
|
|
133
320
|
returning from the hosted checkout is NOT an order-success signal.
|
|
134
321
|
- **Honest unavailability**: `ordering === false` → an "ordering unavailable" state on the
|
|
135
322
|
add button; `onlineReservationsEnabled === false` → a "call us to book" notice (the toggle
|
|
136
323
|
is premium-gated). Never mock menus, dishes, prices, slots, or availability.
|
|
137
|
-
-
|
|
324
|
+
- Don't wrap shipped calls in your own API routes — they run client-side by design.
|
|
325
|
+
- **Cart totals come from `cart`** — never summed or hardcoded in the client; fees, tax, and
|
|
326
|
+
delivery resolve on the hosted checkout.
|
|
327
|
+
- **Browsing, ordering and reserving need no login.** They run on the visitor session the
|
|
328
|
+
shipped client already holds; don't add a members/auth flow unless the brief asks for accounts.
|
|
329
|
+
- **Call every hook before any conditional return.** Hooks first, branches after.
|
|
330
|
+
- Where the shipped components deploy (Astro, React): theme via the `@theme` tokens, and your
|
|
331
|
+
markup uses Tailwind utilities on the same tokens — one design system across shipped and written
|
|
332
|
+
code. No parallel theme files, no hardcoded palette values. Where they don't (`lib`, `static`,
|
|
333
|
+
a port): style with whatever your stack does well, on one token set of your own; the rule that
|
|
334
|
+
survives is the token set, not Tailwind.
|
|
138
335
|
|
|
139
336
|
## Point the user to their dashboard
|
|
140
337
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
338
|
+
Hand the owner these links — `{siteId}` is `siteId` in `wix.config.json` (the deploy JSON prints it as
|
|
339
|
+
`dashboardUrl`); a menu id fills the placeholder from the seed result.
|
|
340
|
+
|
|
341
|
+
| page | `https://manage.wix.com/dashboard/{siteId}/` + |
|
|
342
|
+
|---|---|
|
|
343
|
+
| Menus | `wix-restaurants-menus-new` |
|
|
344
|
+
| Edit a menu | `wix-restaurants-menus-new/menu/{menuId}` |
|
|
345
|
+
| Items | `wix-restaurants-menus-new/items` |
|
|
346
|
+
| Online orders board | `wix-restaurants-orders-new` |
|
|
347
|
+
| Ordering settings (pickup/delivery hours, fees) | `wix-restaurants-orders-new/settings` |
|
|
348
|
+
| Reservations | `wix-table-reservations/table-reservations` |
|
|
349
|
+
| Floor plan | `wix-table-reservations/floor-plan` |
|
|
350
|
+
|
|
351
|
+
Real paid orders need a premium plan + a connected payment method, and holding or completing an online
|
|
352
|
+
reservation is premium-gated — mention both.
|
|
146
353
|
|
|
147
354
|
## Seeding
|
|
148
355
|
|
|
149
356
|
Per `seed/SEED.md` — plain-data `plan.json` into `seed-restaurants.mjs` from the project
|
|
150
357
|
root. Seed a menu that exercises the UI (a few sections, an image per dish) and turn on the
|
|
151
358
|
ordering + reservations add-ons when the restaurant takes orders/bookings.
|
|
152
|
-
|
|
153
|
-
## Verify (before declaring done)
|
|
154
|
-
|
|
155
|
-
- [ ] `/menu` renders the live menu SSR (view-source shows dish names) through YOUR
|
|
156
|
-
components, sections in seeded order; an empty backend shows your honest empty state.
|
|
157
|
-
- [ ] Add to order works (drawer opens, count badge is live); quantity ± / remove work; the
|
|
158
|
-
order survives a reload (same visitor token); checkout redirects to the Wix-hosted
|
|
159
|
-
checkout — or, with no ordering operation, your "ordering unavailable" state shows.
|
|
160
|
-
- [ ] `/reservations`: only AVAILABLE times offered; hold → details form → confirm produces
|
|
161
|
-
your RESERVED or REQUESTED state; a non-premium site shows your honest
|
|
162
|
-
"reservations aren't open yet" notice instead of a broken form.
|
|
163
|
-
- [ ] Dish card / menu / cart chrome / reservations / home are YOUR designs on the tokens;
|
|
164
|
-
data-layer/hook files unedited.
|
|
165
|
-
- [ ] Dashboard links handed to the owner, with the premium notes.
|
package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { useMenus } from "../../hooks/restaurants/useMenus";
|
|
7
7
|
import { useOrderCart } from "../../hooks/restaurants/useOrderCart";
|
|
8
|
+
import { imgAttrs } from "../../wix/media";
|
|
8
9
|
import type { MenuData, MenuItem } from "../../wix/restaurants/types";
|
|
9
10
|
|
|
10
11
|
export interface MenuItemCardProps {
|
|
@@ -22,9 +23,8 @@ export function MenuItemCard({ item, menuId, sectionId }: MenuItemCardProps) {
|
|
|
22
23
|
<div className="flex gap-4 rounded-lg border border-border p-4">
|
|
23
24
|
{item.imageUrl && (
|
|
24
25
|
<img
|
|
25
|
-
|
|
26
|
+
{...imgAttrs(item.imageUrl, "6rem")}
|
|
26
27
|
alt={item.name}
|
|
27
|
-
loading="lazy"
|
|
28
28
|
className="h-24 w-24 flex-shrink-0 rounded-md bg-secondary object-cover"
|
|
29
29
|
/>
|
|
30
30
|
)}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Wix-hosted checkout. Mount ONCE per page; opens via useOrderCart().openCart(). Correct and
|
|
3
3
|
// complete; per the skill's model you design your own chrome on useOrderCart.
|
|
4
4
|
import { useOrderCart } from "../../hooks/restaurants/useOrderCart";
|
|
5
|
+
import { imgAttrs } from "../../wix/media";
|
|
5
6
|
|
|
6
7
|
export default function OrderCartDrawer() {
|
|
7
8
|
const { cart, open, closeCart, busy, error, updateQuantity, removeLine, checkout } = useOrderCart();
|
|
@@ -41,9 +42,8 @@ export default function OrderCartDrawer() {
|
|
|
41
42
|
<div className="mb-6 flex gap-4" key={line.lineItemId}>
|
|
42
43
|
{line.imageUrl ? (
|
|
43
44
|
<img
|
|
44
|
-
|
|
45
|
+
{...imgAttrs(line.imageUrl, "4rem")}
|
|
45
46
|
alt=""
|
|
46
|
-
loading="lazy"
|
|
47
47
|
className="h-16 w-16 flex-shrink-0 rounded-md bg-secondary object-cover"
|
|
48
48
|
/>
|
|
49
49
|
) : (
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
// React binding of the menu store (wix/restaurants/menu-store.ts) — menu browsing and switching
|
|
2
|
+
// live there, framework-free; this hook subscribes to one instance per mounted surface. SSR-friendly:
|
|
3
|
+
// pass server-fetched menus as `initialMenus` (Astro frontmatter) and no client fetch happens; a SPA
|
|
4
|
+
// passes nothing. Astro islands and React SPAs use this; a static page, Vue, or Svelte uses the store.
|
|
5
|
+
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
6
|
+
import { createMenuStore, type MenuStore } from "../../wix/restaurants/menu-store";
|
|
6
7
|
import type { MenuData } from "../../wix/restaurants/types";
|
|
7
8
|
|
|
8
9
|
export interface UseMenusOptions {
|
|
@@ -21,35 +22,13 @@ export interface UseMenus {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export function useMenus({ initialMenus }: UseMenusOptions = {}): UseMenus {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
25
|
+
const ref = useRef<MenuStore | null>(null);
|
|
26
|
+
if (!ref.current) ref.current = createMenuStore({ initialMenus });
|
|
27
|
+
const store = ref.current;
|
|
28
28
|
useEffect(() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setMenus(m);
|
|
35
|
-
setActiveMenuId((id) => id ?? m[0]?.id ?? null);
|
|
36
|
-
})
|
|
37
|
-
.catch((e) => {
|
|
38
|
-
if (!alive) return;
|
|
39
|
-
setMenus([]);
|
|
40
|
-
setError(e instanceof Error ? e.message : String(e));
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
return () => {
|
|
44
|
-
alive = false;
|
|
45
|
-
};
|
|
46
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
-
}, []);
|
|
48
|
-
|
|
49
|
-
const activeMenu = useMemo(() => {
|
|
50
|
-
if (!menus) return null;
|
|
51
|
-
return menus.find((m) => m.id === activeMenuId) ?? menus[0] ?? null;
|
|
52
|
-
}, [menus, activeMenuId]);
|
|
53
|
-
|
|
54
|
-
return { menus, activeMenuId: activeMenu?.id ?? null, setActiveMenuId, activeMenu, error };
|
|
29
|
+
store.start();
|
|
30
|
+
return () => store.stop();
|
|
31
|
+
}, [store]);
|
|
32
|
+
const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
|
|
33
|
+
return { ...state, setActiveMenuId: store.setActiveMenuId };
|
|
55
34
|
}
|