@wix/agent-skills 1.20.1 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +71 -113
- package/skills/wix-app/references/APP_TOOLS.md +2 -1
- package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
- package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
- package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
- package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
- package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
- package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
- package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
- package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
- package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
- package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
- package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
- package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
- package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
- package/skills/wix-headless-fast/SKILL.md +144 -221
- package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
- package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
- package/skills/wix-headless-fast/guides/existing-site.md +76 -0
- package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
- package/skills/wix-headless-fast/install/AGENTS.md +35 -0
- package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
- package/skills/wix-headless-fast/install/attach.mjs +161 -86
- package/skills/wix-headless-fast/install/deploy.mjs +21 -60
- package/skills/wix-headless-fast/install/lock.mjs +55 -0
- package/skills/wix-headless-fast/install/setup.mjs +259 -0
- package/skills/wix-headless-fast/install/templates.mjs +168 -0
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
- package/skills/wix-manage/references/events/create-wix-event.md +5 -1
- package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
- package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
- package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
- package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
- package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
- package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
- package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
- package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
- package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
- package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
- package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
- package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
- package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
- package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
- package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
- package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
- package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
- package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
- package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
- package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
- package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
- package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
- package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
- package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
- package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
- package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
- package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
- package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
- package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
- package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
- package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
- package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
- package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
- package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
- package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
- package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
- package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
- package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
- package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
- package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
- package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
- package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
- package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
- package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
- package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
- package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
- package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
- package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
- package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
- package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
- package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
- package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
- package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
- package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
- package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
- package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
- package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
- package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
- package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
- package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
- package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
- package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
- package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
- package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
- package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
- package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
- package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
- package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
- package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
- package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
- package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
- package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
- package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
- package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
- package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
- package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
- package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
- package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
- package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
- package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
- package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
- package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
- package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
- package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
- package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
- package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
- package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
- package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
- package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
- package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
- package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
- package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
- package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
- package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
- package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
- package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
- package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
- package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
- package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
- package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
- package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
- package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
- package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
- package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
- package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
- package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
- package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
- package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
- package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
- package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
- package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
- package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
- package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
- package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
- package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
- package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
- package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
- package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
- package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
- package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
- package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
- package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
- package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
- package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
- package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
- package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
- package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
- package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
- package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
- package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
- package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
- package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
- package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
- package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
- package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
- package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
- package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
- package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
- package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
- package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
- package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
- package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
- package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
- package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
- package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
- package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
- package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
# Bookings — playbook
|
|
2
|
-
|
|
3
|
-
The booking machinery ships as files — services reads, availability (appointment AND class),
|
|
4
|
-
the schema-driven booking form, and the exact `createBooking → cart → checkout-or-place`
|
|
5
|
-
sequence, typed end-to-end. **The presentation is yours**: you design and implement the
|
|
6
|
-
service card, the listing surface, and the booking surface on the shipped hooks/DTOs, plus
|
|
7
|
-
the home page and the brand. You never write booking logic; you never skip designing.
|
|
8
|
-
|
|
9
|
-
## The file map (deployed into `src/`)
|
|
10
|
-
|
|
11
|
-
**On Astro and React the shipped files are tested and work as they are** — this table and the
|
|
12
|
-
contracts below are everything you need to use them, so don't spend the run reading their source;
|
|
13
|
-
wire them and build your surfaces. Reading them is the right move when something is off (a runtime
|
|
14
|
-
error, a field this playbook doesn't cover) or when the brief wants a behaviour they don't offer —
|
|
15
|
-
then read the file that owns it and change or extend it. On `lib`, `static`, and a port the
|
|
16
|
-
components don't deploy at all, and each wiring section below opens with the files to read before
|
|
17
|
-
writing their equivalents. Files you edit: `SiteLayout.astro`, `styles/global.css`, and the two
|
|
18
|
-
pages' island imports. Files you **create**: your listing and booking components, plus your home page.
|
|
19
|
-
|
|
20
|
-
| file | what it is |
|
|
21
|
-
|---|---|
|
|
22
|
-
| `wix/config.ts` · `wix/sdk.ts` | shared auth seam (deploy configures it — nothing to set by hand) |
|
|
23
|
-
| `wix/media.ts` · `wix/money.ts` | `imgAttrs(url, sizes)` — every `<img>` attribute for a DTO image (`src`, `srcSet`, `sizes`, lazy): `<img {...imgAttrs(s.imageUrl, "33vw")} alt={s.name} />`; `imgSrc()` / `imgSrcSet()` / `formatMoney()` underneath |
|
|
24
|
-
| `wix/bookings/types.ts` | the DTOs (`ServiceSummary`, `ServiceDetail`, `BookingCategory`, `Slot`, `BookingFormField`, `BookingResult`) — contracts below |
|
|
25
|
-
| `wix/bookings/services.ts` | `fetchServices`, `fetchServiceBySlug`, `fetchBookingCategories` — the transport; the rules and DTO mappers are in `services-core.ts` beside it (shared with the REST layer) |
|
|
26
|
-
| `wix/bookings/booking.ts` | `fetchSlots`, `fetchBookingForm`, `bookService` — the transport; the request bodies, the slot and form mappers, and the checkout-or-place rule are in `booking-core.ts` beside it (shared with the REST layer) |
|
|
27
|
-
| `wix/bookings/services-store.ts` · `booking-flow-store.ts` | the listing and booking state machines, framework-free (`createServicesStore()`, `createBookingFlowStore(service)` — `getState`/`subscribe` + actions, one instance per surface); the hooks below bind them to React, every other stack uses them directly |
|
|
28
|
-
| `hooks/bookings/useServices.ts` | React binding of `services-store.ts`: listing + category filter — contract below |
|
|
29
|
-
| `hooks/bookings/useBookingFlow.ts` | React binding of `booking-flow-store.ts`: the whole booking state machine — contract below |
|
|
30
|
-
| `components/bookings/ServicesView.tsx` (+ `ServiceCard`) · `ServiceBookingView.tsx` | **REFERENCE implementations** — correct, plain; build your own instead of shipping them |
|
|
31
|
-
| `styles/global.css` | the design system: Tailwind v4 + the `@theme` token block (shared across verticals) |
|
|
32
|
-
|
|
33
|
-
Astro stack additionally gets:
|
|
34
|
-
|
|
35
|
-
| file | what it is |
|
|
36
|
-
|---|---|
|
|
37
|
-
| `layouts/SiteLayout.astro` | site chrome — **yours to brand** (keep the `seo-tags` slot + global.css import). If storefront is also deployed, its layout won — add a Services nav link there |
|
|
38
|
-
| `pages/services.astro` | SSR listing — **keep the frontmatter**, swap the island import to YOUR component |
|
|
39
|
-
| `pages/services/[slug].astro` | SSR detail + booking with owner-editable SEO — **keep the frontmatter and the SEO pieces** (`wixMetadata`, `loadSEOTagsServiceConfig`, `<SEO.Tags>`) exactly; swap the island import. The booking island stays `client:only="react"` (availability is timezone-specific) |
|
|
40
|
-
|
|
41
|
-
## What you build — the design job
|
|
42
|
-
|
|
43
|
-
1. **The service card + listing surface** — your tile (image, type badge, duration/price
|
|
44
|
-
presentation) and rhythm, with skeletons while loading and an honest empty state — on
|
|
45
|
-
`useServices`.
|
|
46
|
-
2. **The booking surface** — day-grouped slot picking, week paging, staff filter (only when
|
|
47
|
-
>1 staff), the schema-driven form, the book CTA (label free vs priced), and the confirmed
|
|
48
|
-
state — on `useBookingFlow`, which owns ALL booking logic; you own how it looks.
|
|
49
|
-
3. **The home page** — hero, featured services (fetch in frontmatter → your components),
|
|
50
|
-
brand story.
|
|
51
|
-
|
|
52
|
-
Plus the **theme** (`@theme` block, one edit) and the **chrome** (`SiteLayout`, one pass).
|
|
53
|
-
Style everything with Tailwind utilities on the tokens.
|
|
54
|
-
|
|
55
|
-
### What a complete booking site shows (recommended defaults)
|
|
56
|
-
|
|
57
|
-
Defaults for a brief that says nothing about them; the prompt wins where it differs. Look at the
|
|
58
|
-
services before designing (appointments vs classes, categories, staff, prices, images) and design
|
|
59
|
-
for this business, not a stereotype of its category. Then, by default:
|
|
60
|
-
|
|
61
|
-
- **Home:** what the business offers and one booking action in the first screen; real services
|
|
62
|
-
under truthful headings; not a repeat of the listing.
|
|
63
|
-
- **Listing:** a real service card — image, name, duration and price, link — in the first screen;
|
|
64
|
-
category pills only when there is more than one category; `services === null` → skeleton tiles,
|
|
65
|
-
`[]` → your honest empty state.
|
|
66
|
-
- **Service page:** name, price, and the first bookable day's times in the first screen **at 390px
|
|
67
|
-
wide too** — the image is a bounded band on a phone, not a full-screen hero; week paging beside
|
|
68
|
-
the times; the staff filter only when `service.staff.length > 1`; the form under the times, the
|
|
69
|
-
CTA under the form with its label from `service.free` / `service.price`; a week with no times says
|
|
70
|
-
so and points to the next one.
|
|
71
|
-
- **Confirmed state:** rendered only from `confirmed`; a visitor returning from the hosted checkout
|
|
72
|
-
is not a success signal.
|
|
73
|
-
- **A slug that resolves to nothing** shows only the not-found state — no heading or empty picker
|
|
74
|
-
rendered around it.
|
|
75
|
-
- **Copy:** nothing the owner didn't supply — no invented reviews, availability pressure, or
|
|
76
|
-
guarantees; no Wix IDs or technical words in visible text.
|
|
77
|
-
|
|
78
|
-
### The contracts your components consume
|
|
79
|
-
|
|
80
|
-
Everything you need to build on the shipped code; read the source only when something is off.
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
// ServiceSummary (tiles) — display-ready:
|
|
84
|
-
// { id, slug, name, tagLine, type: "APPOINTMENT"|"CLASS", price /* "€75.00" | "Free" */,
|
|
85
|
-
// free, durationMinutes|null, imageUrl /* https or "" */, categoryId|null, staff: [{id,name}] }
|
|
86
|
-
// ServiceDetail adds: description, formId, paymentOption, cancellationFeeEnabled.
|
|
87
|
-
// BookingCategory = { id, name }.
|
|
88
|
-
|
|
89
|
-
// useServices({ initialServices?, initialCategories? }) →
|
|
90
|
-
// { services: ServiceSummary[]|null /* null = loading → skeletons */,
|
|
91
|
-
// categories: BookingCategory[], activeCategoryId, setActiveCategoryId(id|null), error }
|
|
92
|
-
// Category filtering is client-side (a bookings catalog is small and fully fetched).
|
|
93
|
-
|
|
94
|
-
// useBookingFlow(service: ServiceDetail) →
|
|
95
|
-
// { days: [{ dayKey, dayLabel, slots: Slot[] }] | null, // day-grouped; null = loading
|
|
96
|
-
// windowStart, nextWeek(), prevWeek(), // 7-day paging (prev clamps to today)
|
|
97
|
-
// staffId, setStaffId(id|undefined), // show a picker only when service.staff.length > 1
|
|
98
|
-
// selectedSlot, setSelectedSlot(slot|null), // Slot = { startLocal, endLocal, dayKey, label, scheduleId|null, eventId|null, staff }
|
|
99
|
-
// formFields: [{ target, label, type, options?, required }], // never empty (contact-basics fallback); only required ones gate canBook
|
|
100
|
-
// values, setValue(target, value), // inputs write here, keyed by target
|
|
101
|
-
// canBook, // gate the CTA on this
|
|
102
|
-
// book(): Promise<BookingResult>, // paid → the browser navigates to the Wix checkout;
|
|
103
|
-
// booking, confirmed, error } // free/offline → confirmed is set (REAL success)
|
|
104
|
-
// A window or staff change clears selectedSlot and sets days to null while the new week loads.
|
|
105
|
-
// book() rejects on refusal (slot taken, invalid form) AND records .error — render it beside the CTA.
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### The reference files for stacks where the components don't deploy
|
|
109
|
-
|
|
110
|
-
On `lib`, `static`, and a port, nothing under `components/` or `hooks/` arrives. The state machines
|
|
111
|
-
behind the hooks do arrive — `wix/bookings/services-store.ts`, `booking-flow-store.ts` — so you
|
|
112
|
-
never rewrite them: create a store per surface, `subscribe`, render from `getState()`, call its
|
|
113
|
-
actions. Their `ServicesState` / `BookingFlowState` interfaces are the render contract; read those.
|
|
114
|
-
What you write is the rendering — tiles, the slot picker, the form, the CTA — and for that read
|
|
115
|
-
these first; they are tested code for exactly that behaviour:
|
|
116
|
-
|
|
117
|
-
1. `components/bookings/ServiceBookingView.tsx` — the booking surface as working code: day
|
|
118
|
-
groups with slot chips, week paging controls, the staff filter only when there is more than one
|
|
119
|
-
staff member, one input per `formFields` entry typed from its `type` (a `<select>` when it has
|
|
120
|
-
`options`), the CTA disabled until `canBook`, labelled free vs priced, `error` inline, and the
|
|
121
|
-
confirmed state rendered only from `confirmed`.
|
|
122
|
-
2. `components/bookings/ServicesView.tsx` — category pills only when `categories.length > 1`,
|
|
123
|
-
skeleton tiles while `services === null`, the honest empty state, and `ServiceCard`: image with
|
|
124
|
-
the type badge, name, tagLine, "duration · price".
|
|
125
|
-
|
|
126
|
-
All under `references/bookings/app/`.
|
|
127
|
-
|
|
128
|
-
### Wiring — Astro (default)
|
|
129
|
-
|
|
130
|
-
1. Set the `@theme` tokens (one edit); brand `SiteLayout.astro` (one pass — merge into the
|
|
131
|
-
storefront layout instead if both verticals are deployed).
|
|
132
|
-
2. Write your components under `src/components/bookings/` (new names — don't overwrite the
|
|
133
|
-
references), swap the island imports in `pages/services.astro` and
|
|
134
|
-
`pages/services/[slug].astro`. Listing island: `client:load` with the SSR props; booking
|
|
135
|
-
island: `client:only="react"`. **Author your surfaces in as few messages as possible** —
|
|
136
|
-
batch multiple Writes per message.
|
|
137
|
-
3. Write `pages/index.astro` (home) — it exists from the scaffold; Read it before overwriting.
|
|
138
|
-
|
|
139
|
-
### Wiring — another JS framework (`--stack lib`: Vue, Svelte, Solid, plain Vite)
|
|
140
|
-
|
|
141
|
-
Read the reference files listed above before writing any surface.
|
|
142
|
-
|
|
143
|
-
`deploy.mjs bookings --stack lib` put the data layer in `src/wix/` and nothing else: `sdk.ts`
|
|
144
|
-
(the visitor client, configured with the public client id), `media.ts`, `money.ts`, and
|
|
145
|
-
`wix/bookings/` — `services.ts`, `booking.ts`, `types.ts`, the `*-core.ts` rules, and the two
|
|
146
|
-
stores `services-store.ts`, `booking-flow-store.ts`. None of it is React. The hooks and components
|
|
147
|
-
don't ship on this stack; the stores replace the hooks, and you write the components in your
|
|
148
|
-
framework to the contracts on this page:
|
|
149
|
-
|
|
150
|
-
- bind the stores with your framework's external-store primitive (Vue: `shallowRef` updated in
|
|
151
|
-
`subscribe`; Svelte: `readable(store.getState(), (set) => store.subscribe(() => set(store.getState())))`;
|
|
152
|
-
Solid: a signal set in `subscribe`). `createServicesStore(options)` per listing (`start()` when
|
|
153
|
-
mounted, `stop()` when unmounted), `createBookingFlowStore(service)` per booking surface (the
|
|
154
|
-
`ServiceDetail` from `fetchServiceBySlug`; `start()` in the browser only — availability is
|
|
155
|
-
timezone-specific). State in, actions out — exactly the hooks' contracts above;
|
|
156
|
-
- your tiles, slot picker, form, and CTA to the defaults in "What a complete booking site shows" —
|
|
157
|
-
the shipped `ServiceBookingView.tsx` and `ServicesView.tsx` are readable as behaviour specs.
|
|
158
|
-
|
|
159
|
-
Routes `/services`, `/services/:slug` (via `fetchServiceBySlug`, null → your 404); dev server on
|
|
160
|
-
4321; a static build goes through `npx @wix/cli@latest release` with `site.outputDirectory`
|
|
161
|
-
pointing at the build folder, an SSR build is hosted by you. Service-page tags from the
|
|
162
|
-
`ServiceDetail` (name, tagLine, description).
|
|
163
|
-
|
|
164
|
-
### Wiring — static site (`--stack static`, no bundler)
|
|
165
|
-
|
|
166
|
-
Read the reference files listed above before writing any surface.
|
|
167
|
-
|
|
168
|
-
`deploy.mjs bookings --stack static --out site` put the REST layer in `site/js/wix/` (browser
|
|
169
|
-
ESM, the `.ts` beside each `.js` for reading). Everything the visitor loads lives under `site/` —
|
|
170
|
-
pages, styles, `js/` — and `wix.config.json`'s `site.outputDirectory` is `"./site"`; the project
|
|
171
|
-
root (config, plan, seed output) is never the upload. Same function names and DTOs as the table
|
|
172
|
-
above, so the contracts on this page hold unchanged: `fetchServices`, `fetchServiceBySlug`,
|
|
173
|
-
`fetchBookingCategories` from `./js/wix/services.js`; `fetchSlots`, `fetchBookingForm`,
|
|
174
|
-
`bookService` from `./js/wix/booking.js`. The state machines ship too: `createServicesStore` from
|
|
175
|
-
`./js/wix/services-store.js` (the listing — `start()` once the page is up, `setActiveCategoryId`)
|
|
176
|
-
and `createBookingFlowStore(service)` from `./js/wix/booking-flow-store.js` (the booking surface —
|
|
177
|
-
`fetchServiceBySlug(slug)` first, then the store: days, week paging, staff filter, `formFields`,
|
|
178
|
-
`setValue`, `canBook`, `book()`). No components ship — you write the rendering in plain JS: one
|
|
179
|
-
render function per surface that reads `getState()`, called from `subscribe`, with the surface's
|
|
180
|
-
controls calling the store's actions. `book()` navigates the full document to the hosted checkout
|
|
181
|
-
for a paid service on its own (`window.location.origin` must be on the OAuth app's allowed domains
|
|
182
|
-
so checkout can return); for a free or pay-in-person service it sets `confirmed`. Pages are
|
|
183
|
-
`services.html` and `service.html?slug=…` (Wix static hosting serves files, not directories — name
|
|
184
|
-
the file and link to it). Set `document.title` and the meta description from the `ServiceDetail`
|
|
185
|
-
once it loads. The visitor token persists in `localStorage` on its own; never mint per page.
|
|
186
|
-
`npx @wix/cli@latest release` uploads `site/`.
|
|
187
|
-
|
|
188
|
-
### Wiring — server-rendered, another language (Flask, Laravel, Rails, …)
|
|
189
|
-
|
|
190
|
-
Read the reference files listed above before writing any surface.
|
|
191
|
-
|
|
192
|
-
Run `deploy.mjs bookings --stack static` in the project folder anyway: `js/wix/` is both the
|
|
193
|
-
browser-side code and the readable spec. Then split by where the call runs. **Reads on the
|
|
194
|
-
server:** port `js/wix/services.ts` and `services-core.ts` to your language — the same three
|
|
195
|
-
functions returning the same DTO shapes as dicts, one anonymous visitor token per process for these
|
|
196
|
-
public reads (mint and refresh per `client.ts`) — and render the listing and the service page in
|
|
197
|
-
your templates to the contracts above, so service names and prices are in the HTML; page tags from
|
|
198
|
-
the `ServiceDetail`. **Booking in the browser:** the booking surface on
|
|
199
|
-
`./js/wix/booking-flow-store.js` with the rendered `ServiceDetail` (a JSON script tag, or
|
|
200
|
-
`fetchServiceBySlug(slug)` from `./js/wix/services.js`), exactly as the static wiring above — the
|
|
201
|
-
browser owns the visitor's token, so the server never handles per-visitor tokens, and the booking,
|
|
202
|
-
its cart, and the checkout redirect are the visitor's. Routes stay `/services`, `/services/<slug>`.
|
|
203
|
-
Add your public https origin to the OAuth app's allowed domains before checkout can return.
|
|
204
|
-
|
|
205
|
-
**Pre-rendered (Frozen-Flask, Pelican, any static-site generator) → Wix-hosted.** Same port for
|
|
206
|
-
the reads, run at build time with one anonymous token; the generator must emit a page for every
|
|
207
|
-
slug `fetchServices()` returns. Run `deploy.mjs bookings --stack static --out <build dir>` so
|
|
208
|
-
`js/wix/` is inside the output the pages import from, point `site.outputDirectory` at that folder,
|
|
209
|
-
`wix release`. Pages sit at different depths (`/`, `/services/…`): give the templates one base path
|
|
210
|
-
to `js/wix/` (a template variable, or root-relative `/js/wix/…`), never a relative `./js/wix/` — it
|
|
211
|
-
breaks one level down. The frozen listing is the first paint; availability and booking still run
|
|
212
|
-
client-side on the service page through `createBookingFlowStore()` from
|
|
213
|
-
`./js/wix/booking-flow-store.js`, exactly as on a static site, so the booking contract above
|
|
214
|
-
applies. Close with the live URL, the rebuild + release command, and one line for the owner:
|
|
215
|
-
dashboard edits to services reach the site when that command runs; availability and booking are
|
|
216
|
-
live regardless.
|
|
217
|
-
|
|
218
|
-
### Wiring — React SPA (Vite etc.)
|
|
219
|
-
|
|
220
|
-
Import `./styles/global.css` once at the app entry (needs `@tailwindcss/vite` in the vite
|
|
221
|
-
plugins — deploy added the dep). Routes: `/services` → your listing; `/services/:slug` →
|
|
222
|
-
fetch with `fetchServiceBySlug(slug)` client-side, then your booking surface on
|
|
223
|
-
`useBookingFlow(service)`. Deploy wrote the public client id into `wix/config.ts`; nothing else
|
|
224
|
-
to configure.
|
|
225
|
-
|
|
226
|
-
## Hard rules
|
|
227
|
-
|
|
228
|
-
- **Booking logic only through the shipped exports** — `useBookingFlow`/`bookService` own the
|
|
229
|
-
sequence (createBooking → cart holds the seat → checkout-or-place), the payment-option
|
|
230
|
-
derivation, ANY_RESOURCE, and the formSubmission shape. Never re-derive any of it, never
|
|
231
|
-
call `confirmBooking`, never hand-build a checkout URL.
|
|
232
|
-
- **The form is schema-driven** — render `formFields` as given (values keyed by `target`);
|
|
233
|
-
never hardcode field names beyond what the fallback already guarantees.
|
|
234
|
-
- **Gate the CTA on `canBook`** and surface `error` — `book()` can reject (slot taken,
|
|
235
|
-
validation); that message is for the visitor.
|
|
236
|
-
- **The confirmed state must reflect REAL success**: render it only from `confirmed` (set by
|
|
237
|
-
the free/offline branch). A visitor returning from the hosted checkout redirect is NOT a
|
|
238
|
-
success signal — don't fake a confirmation page off the return URL.
|
|
239
|
-
- Where the shipped components deploy (Astro, React): theme via the `@theme` tokens, and your
|
|
240
|
-
markup uses Tailwind utilities on the same tokens — one design system across shipped and written
|
|
241
|
-
code. No parallel theme files, no hardcoded palette values. Where they don't (`lib`, `static`, a
|
|
242
|
-
port): style with whatever your stack does well, on one token set of your own; the rule that
|
|
243
|
-
survives is the token set, not Tailwind.
|
|
244
|
-
- Live data or an honest empty state — never mock services, slots, or availability.
|
|
245
|
-
- Keep the detail page's SEO pieces exactly as shipped (Astro).
|
|
246
|
-
- **Browsing and booking need no login.** They run on the Wix visitor session the shipped client
|
|
247
|
-
already holds; don't gate services or booking behind sign-in unless the brief asks for accounts.
|
|
248
|
-
- **Call every hook before any conditional return.** Hooks first, branches after.
|
|
249
|
-
|
|
250
|
-
## Point the user to their dashboard
|
|
251
|
-
|
|
252
|
-
Hand the owner these links — `{siteId}` is `siteId` in `wix.config.json` (the deploy JSON prints it as
|
|
253
|
-
`dashboardUrl`); a service id fills the placeholder from the seed result.
|
|
254
|
-
|
|
255
|
-
| page | `https://manage.wix.com/dashboard/{siteId}/` + |
|
|
256
|
-
|---|---|
|
|
257
|
-
| Services | `bookings/services` |
|
|
258
|
-
| Edit a service | `bookings/services/form/{serviceId}` |
|
|
259
|
-
| Calendar | `bookings/calendar` |
|
|
260
|
-
| Bookings list | `bookings/bookings/bookings-list` |
|
|
261
|
-
| Staff | `bookings/staff` |
|
|
262
|
-
| Availability | `bookings/availability` |
|
|
263
|
-
| Booking form | `bookings/settings/booking-form-page` |
|
|
264
|
-
| Policies | `bookings/settings/policies` |
|
|
265
|
-
|
|
266
|
-
Completing a booking online — free services included — needs a payment method on the site (Settings →
|
|
267
|
-
Accept payments; "manual payments" is enough for free and pay-in-person); taking real online payments
|
|
268
|
-
also needs a premium plan. Until then `book()` surfaces "the site is not accepting payments" — mention
|
|
269
|
-
it, don't treat it as a code failure.
|
|
270
|
-
|
|
271
|
-
## Seeding
|
|
272
|
-
|
|
273
|
-
Per `seed/SEED.md` — plain-data `plan.json` into `seed-bookings.mjs` from the project root.
|
|
274
|
-
Seed services that exercise the UI (an APPOINTMENT with duration+price, a free one, a CLASS
|
|
275
|
-
with future sessions when it fits the business; an image per service).
|
package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
// REFERENCE booking surface: service info + day-grouped slot picker + staff filter +
|
|
2
|
-
// schema-driven form + book CTA, on the @theme tokens. Correct and complete; per the
|
|
3
|
-
// skill's model you design and build your own on useBookingFlow. Mount client:only —
|
|
4
|
-
// availability is timezone/session-specific.
|
|
5
|
-
import { useBookingFlow } from "../../hooks/bookings/useBookingFlow";
|
|
6
|
-
import type { ServiceDetail } from "../../wix/bookings/types";
|
|
7
|
-
|
|
8
|
-
const chip = (selected: boolean) =>
|
|
9
|
-
`rounded-full border px-4 py-1.5 text-sm transition-colors ${
|
|
10
|
-
selected
|
|
11
|
-
? "border-primary bg-primary text-primary-foreground"
|
|
12
|
-
: "border-border text-foreground hover:bg-secondary"
|
|
13
|
-
}`;
|
|
14
|
-
|
|
15
|
-
export default function ServiceBookingView({ service }: { service: ServiceDetail }) {
|
|
16
|
-
const {
|
|
17
|
-
days,
|
|
18
|
-
nextWeek,
|
|
19
|
-
prevWeek,
|
|
20
|
-
staffId,
|
|
21
|
-
setStaffId,
|
|
22
|
-
selectedSlot,
|
|
23
|
-
setSelectedSlot,
|
|
24
|
-
formFields,
|
|
25
|
-
values,
|
|
26
|
-
setValue,
|
|
27
|
-
canBook,
|
|
28
|
-
book,
|
|
29
|
-
booking,
|
|
30
|
-
confirmed,
|
|
31
|
-
error,
|
|
32
|
-
} = useBookingFlow(service);
|
|
33
|
-
|
|
34
|
-
if (confirmed) {
|
|
35
|
-
return (
|
|
36
|
-
<div className="rounded-lg border border-border bg-secondary p-8 text-center">
|
|
37
|
-
<p className="text-lg font-semibold">You're booked! 🎉</p>
|
|
38
|
-
<p className="mt-2 text-sm text-muted-foreground">
|
|
39
|
-
{service.name}
|
|
40
|
-
{selectedSlot ? ` — ${selectedSlot.dayKey} at ${selectedSlot.label}` : ""}. A confirmation
|
|
41
|
-
email is on its way.
|
|
42
|
-
</p>
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return (
|
|
48
|
-
<div>
|
|
49
|
-
{service.staff.length > 1 && (
|
|
50
|
-
<div className="mb-5">
|
|
51
|
-
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">Staff</p>
|
|
52
|
-
<div className="flex flex-wrap gap-2">
|
|
53
|
-
<button type="button" className={chip(staffId === undefined)} onClick={() => setStaffId(undefined)}>
|
|
54
|
-
Anyone
|
|
55
|
-
</button>
|
|
56
|
-
{service.staff.map((m) => (
|
|
57
|
-
<button key={m.id} type="button" className={chip(staffId === m.id)} onClick={() => setStaffId(m.id)}>
|
|
58
|
-
{m.name}
|
|
59
|
-
</button>
|
|
60
|
-
))}
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
)}
|
|
64
|
-
|
|
65
|
-
<div className="mb-2 flex items-center justify-between">
|
|
66
|
-
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Pick a time</p>
|
|
67
|
-
<div className="flex gap-2">
|
|
68
|
-
<button type="button" onClick={prevWeek} aria-label="Previous week" className="rounded-full border border-border px-3 py-1 text-sm text-foreground transition-colors hover:bg-secondary">←</button>
|
|
69
|
-
<button type="button" onClick={nextWeek} aria-label="Next week" className="rounded-full border border-border px-3 py-1 text-sm text-foreground transition-colors hover:bg-secondary">→</button>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
{days === null ? (
|
|
74
|
-
<div className="space-y-3" aria-busy="true">
|
|
75
|
-
{Array.from({ length: 3 }, (_, i) => (
|
|
76
|
-
<div key={i} className="h-10 animate-pulse rounded-md bg-secondary" />
|
|
77
|
-
))}
|
|
78
|
-
</div>
|
|
79
|
-
) : days.length === 0 ? (
|
|
80
|
-
<p className="rounded-md border border-border p-4 text-sm text-muted-foreground">
|
|
81
|
-
No times in this week — try the next one.
|
|
82
|
-
</p>
|
|
83
|
-
) : (
|
|
84
|
-
<div className="space-y-4">
|
|
85
|
-
{days.map((day) => (
|
|
86
|
-
<div key={day.dayKey}>
|
|
87
|
-
<p className="mb-2 text-sm font-medium">{day.dayLabel}</p>
|
|
88
|
-
<div className="flex flex-wrap gap-2">
|
|
89
|
-
{day.slots.map((s) => (
|
|
90
|
-
<button
|
|
91
|
-
key={s.startLocal + (s.eventId ?? "")}
|
|
92
|
-
type="button"
|
|
93
|
-
className={chip(selectedSlot?.startLocal === s.startLocal)}
|
|
94
|
-
onClick={() => setSelectedSlot(s)}
|
|
95
|
-
>
|
|
96
|
-
{s.label}
|
|
97
|
-
</button>
|
|
98
|
-
))}
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
))}
|
|
102
|
-
</div>
|
|
103
|
-
)}
|
|
104
|
-
|
|
105
|
-
<div className="mt-6 grid max-w-md gap-3">
|
|
106
|
-
{formFields.map((f) => (
|
|
107
|
-
<label key={f.target} className="block">
|
|
108
|
-
<span className="mb-1 block text-xs font-semibold uppercase tracking-wider text-muted-foreground">{f.label}{f.required ? " *" : ""}</span>
|
|
109
|
-
{f.options?.length ? (
|
|
110
|
-
<select
|
|
111
|
-
value={values[f.target] ?? ""}
|
|
112
|
-
onChange={(e) => setValue(f.target, e.target.value)}
|
|
113
|
-
className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-shadow focus:ring-2 focus:ring-primary"
|
|
114
|
-
>
|
|
115
|
-
<option value="">Choose…</option>
|
|
116
|
-
{f.options.map((o) => (
|
|
117
|
-
<option key={o} value={o}>{o}</option>
|
|
118
|
-
))}
|
|
119
|
-
</select>
|
|
120
|
-
) : (
|
|
121
|
-
<input
|
|
122
|
-
type={f.type === "EMAIL" ? "email" : f.type === "PHONE" ? "tel" : f.type === "NUMBER" ? "number" : f.type === "URL" ? "url" : "text"}
|
|
123
|
-
value={values[f.target] ?? ""}
|
|
124
|
-
required={f.required}
|
|
125
|
-
onChange={(e) => setValue(f.target, e.target.value)}
|
|
126
|
-
className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-shadow focus:ring-2 focus:ring-primary"
|
|
127
|
-
/>
|
|
128
|
-
)}
|
|
129
|
-
</label>
|
|
130
|
-
))}
|
|
131
|
-
</div>
|
|
132
|
-
|
|
133
|
-
{error && <p className="mt-3 text-sm text-red-600">{error}</p>}
|
|
134
|
-
<button
|
|
135
|
-
type="button"
|
|
136
|
-
disabled={!canBook || booking}
|
|
137
|
-
onClick={() => book().catch(() => {})}
|
|
138
|
-
className="mt-5 rounded-full bg-primary px-8 py-3 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-50"
|
|
139
|
-
>
|
|
140
|
-
{booking ? "Booking…" : service.free ? "Book — free" : `Book · ${service.price}`}
|
|
141
|
-
</button>
|
|
142
|
-
</div>
|
|
143
|
-
);
|
|
144
|
-
}
|
package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// REFERENCE listing surface: category filter + services grid on the @theme tokens.
|
|
2
|
-
// Correct and complete; per the skill's model you design and build your own on useServices.
|
|
3
|
-
import type { ComponentType, ReactNode } from "react";
|
|
4
|
-
import { useServices } from "../../hooks/bookings/useServices";
|
|
5
|
-
import type { BookingCategory, ServiceSummary } from "../../wix/bookings/types";
|
|
6
|
-
|
|
7
|
-
export interface LinkLikeProps {
|
|
8
|
-
href: string;
|
|
9
|
-
className?: string;
|
|
10
|
-
children?: ReactNode;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const PlainLink = ({ href, className, children }: LinkLikeProps) => (
|
|
14
|
-
<a href={href} className={className}>
|
|
15
|
-
{children}
|
|
16
|
-
</a>
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
export interface ServiceCardProps {
|
|
20
|
-
service: ServiceSummary;
|
|
21
|
-
serviceHref?: (slug: string) => string;
|
|
22
|
-
LinkComponent?: ComponentType<LinkLikeProps>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function ServiceCard({
|
|
26
|
-
service,
|
|
27
|
-
serviceHref = (slug) => `/services/${slug}`,
|
|
28
|
-
LinkComponent = PlainLink,
|
|
29
|
-
}: ServiceCardProps) {
|
|
30
|
-
return (
|
|
31
|
-
<LinkComponent href={serviceHref(service.slug)} className="group block no-underline">
|
|
32
|
-
<div className="relative aspect-[4/3] overflow-hidden rounded-lg bg-secondary">
|
|
33
|
-
{service.imageUrl && (
|
|
34
|
-
<img
|
|
35
|
-
src={service.imageUrl}
|
|
36
|
-
alt={service.name}
|
|
37
|
-
loading="lazy"
|
|
38
|
-
className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]"
|
|
39
|
-
/>
|
|
40
|
-
)}
|
|
41
|
-
<span className="absolute left-3 top-3 rounded-full bg-background/90 px-3 py-1 text-xs font-semibold text-foreground backdrop-blur">
|
|
42
|
-
{service.type === "CLASS" ? "Class" : "Appointment"}
|
|
43
|
-
</span>
|
|
44
|
-
</div>
|
|
45
|
-
<p className="mt-3 text-sm font-medium text-foreground">{service.name}</p>
|
|
46
|
-
{service.tagLine && <p className="mt-0.5 text-xs text-muted-foreground">{service.tagLine}</p>}
|
|
47
|
-
<p className="mt-1 text-sm text-muted-foreground">
|
|
48
|
-
{service.durationMinutes ? `${service.durationMinutes} min · ` : ""}
|
|
49
|
-
<span className="text-foreground">{service.price}</span>
|
|
50
|
-
</p>
|
|
51
|
-
</LinkComponent>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface ServicesViewProps {
|
|
56
|
-
initialServices?: ServiceSummary[];
|
|
57
|
-
initialCategories?: BookingCategory[];
|
|
58
|
-
emptyMessage?: string;
|
|
59
|
-
serviceHref?: ServiceCardProps["serviceHref"];
|
|
60
|
-
LinkComponent?: ComponentType<LinkLikeProps>;
|
|
61
|
-
CardComponent?: ComponentType<ServiceCardProps>;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const pill = (active: boolean) =>
|
|
65
|
-
`rounded-full border px-4 py-1.5 text-sm font-medium transition-colors ${
|
|
66
|
-
active
|
|
67
|
-
? "border-primary bg-primary text-primary-foreground"
|
|
68
|
-
: "border-border text-foreground hover:bg-secondary"
|
|
69
|
-
}`;
|
|
70
|
-
|
|
71
|
-
export default function ServicesView({
|
|
72
|
-
initialServices,
|
|
73
|
-
initialCategories,
|
|
74
|
-
emptyMessage = "No services yet — check back soon.",
|
|
75
|
-
serviceHref,
|
|
76
|
-
LinkComponent,
|
|
77
|
-
CardComponent = ServiceCard,
|
|
78
|
-
}: ServicesViewProps) {
|
|
79
|
-
const { services, categories, activeCategoryId, setActiveCategoryId, error } = useServices({
|
|
80
|
-
initialServices,
|
|
81
|
-
initialCategories,
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<div>
|
|
86
|
-
{categories.length > 1 && (
|
|
87
|
-
<div className="mb-8 flex flex-wrap gap-2" role="group" aria-label="Categories">
|
|
88
|
-
<button type="button" className={pill(activeCategoryId === null)} onClick={() => setActiveCategoryId(null)}>
|
|
89
|
-
All
|
|
90
|
-
</button>
|
|
91
|
-
{categories.map((c) => (
|
|
92
|
-
<button key={c.id} type="button" className={pill(activeCategoryId === c.id)} onClick={() => setActiveCategoryId(c.id)}>
|
|
93
|
-
{c.name}
|
|
94
|
-
</button>
|
|
95
|
-
))}
|
|
96
|
-
</div>
|
|
97
|
-
)}
|
|
98
|
-
{error && <p className="mb-4 text-sm text-red-600">{error}</p>}
|
|
99
|
-
{services === null ? (
|
|
100
|
-
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3" aria-busy="true">
|
|
101
|
-
{Array.from({ length: 6 }, (_, i) => (
|
|
102
|
-
<div key={i}>
|
|
103
|
-
<div className="aspect-[4/3] animate-pulse rounded-lg bg-secondary" />
|
|
104
|
-
<div className="mt-3 h-3.5 w-2/3 animate-pulse rounded bg-secondary" />
|
|
105
|
-
</div>
|
|
106
|
-
))}
|
|
107
|
-
</div>
|
|
108
|
-
) : services.length === 0 ? (
|
|
109
|
-
<p className="py-16 text-center text-muted-foreground">{emptyMessage}</p>
|
|
110
|
-
) : (
|
|
111
|
-
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
|
112
|
-
{services.map((s) => (
|
|
113
|
-
<CardComponent key={s.id} service={s} serviceHref={serviceHref} LinkComponent={LinkComponent} />
|
|
114
|
-
))}
|
|
115
|
-
</div>
|
|
116
|
-
)}
|
|
117
|
-
</div>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// React binding of the booking-flow store (wix/bookings/booking-flow-store.ts) — the whole booking
|
|
2
|
-
// state machine for one service lives there, framework-free: availability window (day-grouped
|
|
3
|
-
// slots, week paging, optional staff filter), the schema-driven form, and book(). All correctness
|
|
4
|
-
// (slot scheduleId vs eventId, ANY_RESOURCE, formSubmission, payment option, checkout-or-place)
|
|
5
|
-
// lives in the data layer; you own how it looks. Mount the surface client-only: availability is
|
|
6
|
-
// timezone/session-specific.
|
|
7
|
-
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
8
|
-
import { createBookingFlowStore, type BookingFlowState, type BookingFlowStore } from "../../wix/bookings/booking-flow-store";
|
|
9
|
-
import type { ServiceDetail } from "../../wix/bookings/types";
|
|
10
|
-
|
|
11
|
-
export type UseBookingFlow = BookingFlowState &
|
|
12
|
-
Pick<BookingFlowStore, "nextWeek" | "prevWeek" | "setStaffId" | "setSelectedSlot" | "setValue" | "book">;
|
|
13
|
-
|
|
14
|
-
export function useBookingFlow(service: ServiceDetail): UseBookingFlow {
|
|
15
|
-
const ref = useRef<{ serviceId: string; store: BookingFlowStore } | null>(null);
|
|
16
|
-
if (!ref.current || ref.current.serviceId !== service.id) ref.current = { serviceId: service.id, store: createBookingFlowStore(service) };
|
|
17
|
-
const store = ref.current.store;
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
store.start();
|
|
20
|
-
return () => store.stop();
|
|
21
|
-
}, [store]);
|
|
22
|
-
const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
|
|
23
|
-
return {
|
|
24
|
-
...state,
|
|
25
|
-
nextWeek: store.nextWeek,
|
|
26
|
-
prevWeek: store.prevWeek,
|
|
27
|
-
setStaffId: store.setStaffId,
|
|
28
|
-
setSelectedSlot: store.setSelectedSlot,
|
|
29
|
-
setValue: store.setValue,
|
|
30
|
-
book: store.book,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// React binding of the services store (wix/bookings/services-store.ts) — the listing state lives
|
|
2
|
-
// there, framework-free; this hook subscribes to one instance per mounted listing and exposes its
|
|
3
|
-
// state and actions under one name. SSR-friendly: pass server-fetched data as `initial*` (Astro
|
|
4
|
-
// frontmatter / server component) and no client fetch happens; a SPA passes nothing. Astro islands
|
|
5
|
-
// and React SPAs use this; a static page, Vue, or Svelte uses the store directly.
|
|
6
|
-
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
7
|
-
import { createServicesStore, type ServicesState, type ServicesStore, type ServicesStoreOptions } from "../../wix/bookings/services-store";
|
|
8
|
-
|
|
9
|
-
export type UseServicesOptions = ServicesStoreOptions;
|
|
10
|
-
|
|
11
|
-
export type UseServices = ServicesState & Pick<ServicesStore, "setActiveCategoryId">;
|
|
12
|
-
|
|
13
|
-
export function useServices(options: UseServicesOptions = {}): UseServices {
|
|
14
|
-
const ref = useRef<ServicesStore | null>(null);
|
|
15
|
-
if (!ref.current) ref.current = createServicesStore(options);
|
|
16
|
-
const store = ref.current;
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
store.start();
|
|
19
|
-
return () => store.stop();
|
|
20
|
-
}, [store]);
|
|
21
|
-
const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
|
|
22
|
-
return { ...state, setActiveCategoryId: store.setActiveCategoryId };
|
|
23
|
-
}
|