@wix/agent-skills 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +4 -1
- package/skills/wix-app/references/APP_TOOLS.md +134 -0
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +1 -1
- package/skills/wix-app/references/DASHBOARD_PAGE.md +0 -10
- package/skills/wix-app/references/DATA_COLLECTION.md +6 -4
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +28 -7
- package/skills/wix-app/references/SERVICE_PLUGIN.md +12 -10
- package/skills/wix-app/references/STORES_VERSIONING.md +9 -211
- package/skills/wix-app/references/app-tools/TOOLS.md +75 -0
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +5 -0
- package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +2 -2
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +172 -0
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +138 -0
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +172 -0
- package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +29 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +1 -1
- package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +57 -0
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +33 -2
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +5 -3
- package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +18 -1
- package/skills/wix-app/references/editor-react-component/PARTS.md +15 -2
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +4 -3
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +13 -9
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +4 -0
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +4 -0
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +3 -1
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +4 -0
- package/skills/wix-app/references/service-plugin/TOOLS_PROVIDER.md +54 -0
- package/skills/wix-app/references/stores/CATEGORIES.md +22 -0
- package/skills/wix-app/references/stores/GET_PRODUCT.md +99 -0
- package/skills/wix-app/references/stores/INVENTORY.md +37 -0
- package/skills/wix-app/references/stores/QUERY.md +119 -0
- package/skills/wix-app/references/stores/WRITE.md +55 -0
- package/skills/wix-docs/SKILL.md +35 -3
- package/skills/wix-headless/SKILL.md +9 -2
- package/skills/wix-headless/entry/bootstrap.mjs +2 -2
- package/skills/wix-headless/entry/skill.md +0 -2
- package/skills/wix-headless/references/CAPABILITIES.md +6 -4
- package/skills/wix-headless/references/CONTENT.md +36 -0
- package/skills/wix-headless/references/DESIGN.md +54 -0
- package/skills/wix-headless/references/DISCOVERY.md +25 -1
- package/skills/wix-headless/references/FEEDBACK.md +16 -5
- package/skills/wix-headless/references/IMAGE_GENERATION.md +10 -0
- package/skills/wix-headless/references/SDK_HANDOFF.md +2 -0
- package/skills/wix-headless/references/SEED.md +3 -1
- package/skills/wix-headless/references/SETUP.md +1 -1
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +3 -2
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +42 -2
- package/skills/wix-headless/references/inline-recipes/setup-bookings.md +5 -1
- package/skills/wix-headless/references/inline-recipes/setup-forms.md +1 -1
- package/skills/wix-headless/references/inline-recipes/setup-online-store.md +33 -8
- package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +3 -1
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +73 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +38 -2
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +20 -1
- package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +1 -1
- package/skills/wix-headless/references/managed/CONNECT.md +2 -2
- package/skills/wix-headless/references/managed/CREATE.md +15 -1
- package/skills/wix-headless/references/managed/DEPLOYMENT.md +47 -0
- package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +8 -0
- package/skills/wix-headless/references/stripe/DEPLOYMENT.md +8 -0
- package/skills/wix-manage/SKILL.md +131 -12
- package/skills/wix-manage/references/analytics/analytics-dashboard-navigation.md +41 -0
- package/skills/wix-manage/references/analytics/query-site-analytics.md +66 -9
- package/skills/wix-manage/references/app-installation/app-installation-dashboard-navigation.md +28 -0
- package/skills/wix-manage/references/app-installation/install-wix-apps.md +3 -0
- package/skills/wix-manage/references/blog/blog-dashboard-navigation.md +56 -0
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +31 -6
- package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +3 -1
- package/skills/wix-manage/references/bookings/bookings-dashboard-navigation.md +63 -0
- package/skills/wix-manage/references/bookings/create-booking-service-from-prompt.md +6 -5
- package/skills/wix-manage/references/bookings/create-course-service.md +30 -5
- package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +85 -42
- package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +44 -0
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +31 -3
- package/skills/wix-manage/references/cms/cms-publishing-flow.md +287 -0
- package/skills/wix-manage/references/cms/cms-schema-management.md +33 -1
- package/skills/wix-manage/references/contacts/contacts-dashboard-navigation.md +46 -0
- package/skills/wix-manage/references/contacts/create-a-contact.md +82 -0
- package/skills/wix-manage/references/contacts/update-a-contact.md +119 -0
- package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +82 -0
- package/skills/wix-manage/references/dashboard-navigation/routes.json +1733 -0
- package/skills/wix-manage/references/domains/domains-dashboard-navigation.md +32 -0
- package/skills/wix-manage/references/ecommerce/ecom-pricing.md +4 -4
- package/skills/wix-manage/references/ecommerce/ecom-shipping.md +1 -1
- package/skills/wix-manage/references/ecommerce/gift-cards/ecom-gift-cards-goal-sell-gift-cards.md +338 -0
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-discount-rule.md +42 -78
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-bundle-and-save.md +1 -1
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-stock-mover.md +1 -1
- package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-flow-upsell-boost.md +1 -1
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +90 -92
- package/skills/wix-manage/references/events/create-wix-event.md +176 -0
- package/skills/wix-manage/references/events/manage-wix-events.md +174 -0
- package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +44 -0
- package/skills/wix-manage/references/get-paid/get-paid-dashboard-navigation.md +52 -0
- package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +30 -7
- package/skills/wix-manage/references/google-ads/billing-and-payment.md +80 -0
- package/skills/wix-manage/references/google-ads/create-performance-max-campaign.md +212 -0
- package/skills/wix-manage/references/google-ads/get-campaign-suggestions.md +110 -0
- package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +25 -0
- package/skills/wix-manage/references/google-ads/install-and-create-account.md +155 -0
- package/skills/wix-manage/references/google-ads/manage-campaign-lifecycle.md +63 -0
- package/skills/wix-manage/references/google-ads/query-campaign-analytics.md +155 -0
- package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +225 -144
- package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +19 -10
- package/skills/wix-manage/references/marketing/marketing-dashboard-navigation.md +52 -0
- package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +99 -1
- package/skills/wix-manage/references/pricing-plans/pricing-plans-dashboard-navigation.md +45 -0
- package/skills/wix-manage/references/restaurants/restaurants-dashboard-navigation.md +68 -0
- package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +94 -125
- package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +48 -9
- package/skills/wix-manage/references/site-properties/site-properties-dashboard-navigation.md +31 -0
- package/skills/wix-manage/references/sites/create-headless-site.md +52 -0
- package/skills/wix-manage/references/sites/create-site-from-template.md +2 -25
- package/skills/wix-manage/references/sites/site-import.md +243 -0
- package/skills/wix-manage/references/sites/sites-dashboard-navigation.md +29 -0
- package/skills/wix-manage/references/stores/add-store-pages-to-site.md +17 -1
- package/skills/wix-manage/references/stores/create-product-from-image.md +8 -6
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +16 -10
- package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +26 -8
- package/skills/wix-manage/references/stores/stores-dashboard-navigation.md +65 -0
- package/skills/wix-manage/references/stores/update-product-with-options.md +39 -7
- package/skills/wix-replatform/.publish-manifest.json +8 -0
- package/skills/wix-replatform/SKILL.md +693 -0
- package/skills/wix-replatform/lib/artifact-freshness.js +215 -0
- package/skills/wix-replatform/lib/completion-report.js +200 -0
- package/skills/wix-replatform/lib/config-env.js +59 -0
- package/skills/wix-replatform/lib/execution-manifest.js +185 -0
- package/skills/wix-replatform/lib/execution-state.js +173 -0
- package/skills/wix-replatform/lib/import-recovery.js +313 -0
- package/skills/wix-replatform/lib/local-state.js +642 -0
- package/skills/wix-replatform/lib/orchestration-preflight.js +143 -0
- package/skills/wix-replatform/lib/orchestration-router.js +122 -0
- package/skills/wix-replatform/lib/orchestration-state.js +455 -0
- package/skills/wix-replatform/lib/progress-log.js +224 -0
- package/skills/wix-replatform/lib/progress-log.sh +140 -0
- package/skills/wix-replatform/lib/url-preservation-state.js +391 -0
- package/skills/wix-replatform/resources/rp-discovery/SKILL.md +184 -0
- package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +529 -0
- package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +316 -0
- package/skills/wix-replatform/resources/rp-execute-setup/scripts/mint-token.sh +64 -0
- package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +1114 -0
- package/skills/wix-replatform/resources/rp-mapper/SKILL.md +430 -0
- package/skills/wix-replatform/resources/rp-mapper/lib/mapping-resolve.js +217 -0
- package/skills/wix-replatform/resources/rp-mapper/scripts/resolve-mapping.js +148 -0
- package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +378 -0
- package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +183 -0
- package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +478 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/canonical-record.js +136 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fingerprint.js +310 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/csv-layout.js +1081 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/csv-parse.js +618 -0
- package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +949 -0
- package/skills/wix-replatform/resources/rp-source-csv/source-schema.example.json +196 -0
- package/skills/wix-replatform/resources/rp-source-csv/vendors/bigcommerce.json +66 -0
- package/skills/wix-replatform/resources/rp-source-csv/vendors/magento.json +60 -0
- package/skills/wix-replatform/resources/rp-source-csv/vendors/shopify.json +95 -0
- package/skills/wix-replatform/resources/rp-source-csv/vendors/woocommerce.json +82 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +256 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +249 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +444 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +774 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/source-schema.example.json +71 -0
- package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +632 -0
- package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +330 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +21 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +39 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +35 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +14 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +35 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +36 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +35 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +14 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +131 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +21 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +97 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +528 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +38 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +53 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +84 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +25 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +38 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +37 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +90 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/audit-summary.js +64 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +141 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +384 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/ndjson.js +260 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +238 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +237 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +238 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +2219 -0
- package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +31 -0
- package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge.js +100 -0
- package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +107 -0
- package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +344 -0
- package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +250 -0
- package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1927 -0
- package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +83 -0
- package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +141 -0
- package/skills/wix-replatform/scripts/artifact-freshness.js +76 -0
- package/skills/wix-replatform/scripts/execution-manifest-validate.js +43 -0
- package/skills/wix-replatform/scripts/execution-state-prepare.js +128 -0
- package/skills/wix-replatform/scripts/orchestration-preflight.js +48 -0
- package/skills/wix-replatform/scripts/orchestration-route.js +46 -0
- package/skills/wix-replatform/scripts/orchestration-state.js +245 -0
- package/skills/wix-vibe-headless/SKILL.md +54 -25
- package/skills/wix-vibe-headless/install/deploy.cjs +95 -0
- package/skills/wix-vibe-headless/install/pin-agents-md.cjs +34 -0
- package/skills/wix-vibe-headless/platforms/README.md +26 -0
- package/skills/wix-vibe-headless/platforms/base44.md +177 -0
- package/skills/wix-vibe-headless/platforms/generic.md +122 -0
- package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +230 -119
- package/skills/wix-vibe-headless/references/blog/app/components/PostCard.jsx +43 -0
- package/skills/wix-vibe-headless/references/blog/app/components/PostChips.jsx +25 -0
- package/skills/wix-vibe-headless/references/blog/app/components/PostGrid.jsx +15 -0
- package/skills/wix-vibe-headless/references/blog/app/context/TaxonomyContext.jsx +35 -0
- package/skills/wix-vibe-headless/references/blog/app/hooks/usePostDetail.js +38 -0
- package/skills/wix-vibe-headless/references/blog/app/pages/Blog.jsx +40 -0
- package/skills/wix-vibe-headless/references/blog/app/pages/CategoryPage.jsx +54 -0
- package/skills/wix-vibe-headless/references/blog/app/pages/PostDetail.jsx +65 -0
- package/skills/wix-vibe-headless/references/blog/app/pages/TagPage.jsx +50 -0
- package/skills/wix-vibe-headless/references/blog/seed/SEED.md +103 -0
- package/skills/wix-vibe-headless/references/blog/seed/seed-blog.js +270 -0
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +260 -145
- package/skills/wix-vibe-headless/references/bookings/app/components/BookingForm.jsx +65 -0
- package/skills/wix-vibe-headless/references/bookings/app/components/ServiceCard.jsx +47 -0
- package/skills/wix-vibe-headless/references/bookings/app/components/ServiceGrid.jsx +13 -0
- package/skills/wix-vibe-headless/references/bookings/app/components/SlotPicker.jsx +126 -0
- package/skills/wix-vibe-headless/references/bookings/app/hooks/useServiceDetail.js +108 -0
- package/skills/wix-vibe-headless/references/bookings/app/hooks/useServices.js +58 -0
- package/skills/wix-vibe-headless/references/bookings/app/lib/serviceFacts.js +95 -0
- package/skills/wix-vibe-headless/references/bookings/app/pages/ServiceDetail.jsx +94 -0
- package/skills/wix-vibe-headless/references/bookings/app/pages/Services.jsx +89 -0
- package/skills/wix-vibe-headless/references/bookings/{wix-bookings-checkout.js → app/rest/wix-bookings-checkout.js} +1 -1
- package/skills/wix-vibe-headless/references/bookings/{wix-bookings-services.js → app/rest/wix-bookings-services.js} +90 -12
- package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +117 -0
- package/skills/wix-vibe-headless/references/bookings/seed/seed-bookings.js +333 -0
- package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +169 -147
- package/skills/wix-vibe-headless/references/cms/app/collection.config.js +31 -0
- package/skills/wix-vibe-headless/references/cms/app/lib/wixImage.js +18 -0
- package/skills/wix-vibe-headless/references/cms/{wix-cms.js → app/rest/wix-cms.js} +47 -2
- package/skills/wix-vibe-headless/references/cms/seed/SEED.md +145 -0
- package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +228 -131
- package/skills/wix-vibe-headless/references/events/app/components/CategoryFilter.jsx +23 -0
- package/skills/wix-vibe-headless/references/events/app/components/EventCard.jsx +43 -0
- package/skills/wix-vibe-headless/references/events/app/components/EventGrid.jsx +13 -0
- package/skills/wix-vibe-headless/references/events/app/components/EventRegistration.jsx +29 -0
- package/skills/wix-vibe-headless/references/events/app/components/RsvpForm.jsx +57 -0
- package/skills/wix-vibe-headless/references/events/app/components/TicketPicker.jsx +78 -0
- package/skills/wix-vibe-headless/references/events/app/hooks/useEventDetail.js +27 -0
- package/skills/wix-vibe-headless/references/events/app/hooks/useEventsList.js +54 -0
- package/skills/wix-vibe-headless/references/events/app/hooks/useRsvpForm.js +40 -0
- package/skills/wix-vibe-headless/references/events/app/hooks/useTicketing.js +81 -0
- package/skills/wix-vibe-headless/references/events/app/pages/EventDetail.jsx +48 -0
- package/skills/wix-vibe-headless/references/events/app/pages/Events.jsx +36 -0
- package/skills/wix-vibe-headless/references/events/{wix-events-browse.js → app/rest/wix-events-browse.js} +3 -2
- package/skills/wix-vibe-headless/references/events/seed/SEED.md +107 -0
- package/skills/wix-vibe-headless/references/events/seed/seed-events.js +251 -0
- package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +276 -188
- package/skills/wix-vibe-headless/references/members/app/components/LoginForm.jsx +101 -0
- package/skills/wix-vibe-headless/references/members/app/components/MemberMenu.jsx +33 -0
- package/skills/wix-vibe-headless/references/members/app/components/RequireAuth.jsx +21 -0
- package/skills/wix-vibe-headless/references/members/app/components/SocialButtons.jsx +29 -0
- package/skills/wix-vibe-headless/references/members/app/context/MemberContext.jsx +54 -0
- package/skills/wix-vibe-headless/references/members/app/hooks/useLoginForm.js +77 -0
- package/skills/wix-vibe-headless/references/members/app/pages/Account.jsx +36 -0
- package/skills/wix-vibe-headless/references/members/app/pages/Callback.jsx +32 -0
- package/skills/wix-vibe-headless/references/members/app/pages/Login.jsx +35 -0
- package/skills/wix-vibe-headless/references/members/{wix-members-auth.js → app/rest/wix-members-auth.js} +6 -3
- package/skills/wix-vibe-headless/references/members/install/Register.jsx +22 -0
- package/skills/wix-vibe-headless/references/members/seed/SEED.md +22 -0
- package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +233 -104
- package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionCard.jsx +31 -0
- package/skills/wix-vibe-headless/references/portfolio/app/components/CollectionGrid.jsx +15 -0
- package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectCard.jsx +39 -0
- package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectGrid.jsx +15 -0
- package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +29 -0
- package/skills/wix-vibe-headless/references/portfolio/app/hooks/useCollectionProjects.js +35 -0
- package/skills/wix-vibe-headless/references/portfolio/app/hooks/usePortfolioGallery.js +27 -0
- package/skills/wix-vibe-headless/references/portfolio/app/hooks/useProjectDetail.js +25 -0
- package/skills/wix-vibe-headless/references/portfolio/app/pages/CollectionPage.jsx +39 -0
- package/skills/wix-vibe-headless/references/portfolio/app/pages/Portfolio.jsx +27 -0
- package/skills/wix-vibe-headless/references/portfolio/app/pages/ProjectDetail.jsx +60 -0
- package/skills/wix-vibe-headless/references/portfolio/{wix-portfolio.js → app/rest/wix-portfolio.js} +84 -55
- package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +94 -0
- package/skills/wix-vibe-headless/references/portfolio/seed/seed-portfolio.js +236 -0
- package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +240 -117
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +35 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanCard.jsx +48 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanGrid.jsx +16 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/components/PlanPrice.jsx +35 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/useMyPlans.js +25 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlanDetail.js +28 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/hooks/usePlans.js +30 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/pages/MyPlans.jsx +30 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/pages/PlanDetail.jsx +53 -0
- package/skills/wix-vibe-headless/references/pricing-plans/app/pages/Plans.jsx +28 -0
- package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +86 -0
- package/skills/wix-vibe-headless/references/pricing-plans/seed/seed-pricing-plans.js +251 -0
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +248 -124
- package/skills/wix-vibe-headless/references/restaurants/app/components/ItemDialog.jsx +81 -0
- package/skills/wix-vibe-headless/references/restaurants/app/components/MenuItemCard.jsx +71 -0
- package/skills/wix-vibe-headless/references/restaurants/app/components/MenuList.jsx +43 -0
- package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartButton.jsx +21 -0
- package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +60 -0
- package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +63 -0
- package/skills/wix-vibe-headless/references/restaurants/app/hooks/useItemOrder.js +32 -0
- package/skills/wix-vibe-headless/references/restaurants/app/hooks/useReservation.js +73 -0
- package/skills/wix-vibe-headless/references/restaurants/app/pages/Menu.jsx +28 -0
- package/skills/wix-vibe-headless/references/restaurants/app/pages/Reservations.jsx +102 -0
- package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +180 -0
- package/skills/wix-vibe-headless/references/restaurants/seed/seed-restaurants.js +452 -0
- package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +56 -0
- package/skills/wix-vibe-headless/references/shared/{wix-client.js → app/rest/wix-client.js} +6 -8
- package/skills/wix-vibe-headless/references/shared/app/rest/wix-config.js +6 -0
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +263 -148
- package/skills/wix-vibe-headless/references/storefront/app/components/CartButton.jsx +20 -0
- package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +150 -0
- package/skills/wix-vibe-headless/references/storefront/app/components/ProductCard.jsx +167 -0
- package/skills/wix-vibe-headless/references/storefront/app/components/ProductGallery.jsx +51 -0
- package/skills/wix-vibe-headless/references/storefront/app/components/ProductGrid.jsx +54 -0
- package/skills/wix-vibe-headless/references/storefront/app/components/VariantPicker.jsx +119 -0
- package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +71 -0
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +109 -0
- package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +98 -0
- package/skills/wix-vibe-headless/references/storefront/app/lib/storeImage.js +27 -0
- package/skills/wix-vibe-headless/references/storefront/app/pages/ProductDetail.jsx +139 -0
- package/skills/wix-vibe-headless/references/storefront/app/pages/Shop.jsx +75 -0
- package/skills/wix-vibe-headless/references/storefront/{wix-store-cart.js → app/rest/wix-store-cart.js} +1 -1
- package/skills/wix-vibe-headless/references/storefront/{wix-store-catalog.js → app/rest/wix-store-catalog.js} +25 -2
- package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +111 -0
- package/skills/wix-vibe-headless/references/storefront/seed/seed-store.js +299 -0
- /package/skills/wix-vibe-headless/references/blog/{wix-blog.js → app/rest/wix-blog.js} +0 -0
- /package/skills/wix-vibe-headless/references/events/{wix-events-registration.js → app/rest/wix-events-registration.js} +0 -0
- /package/skills/wix-vibe-headless/references/pricing-plans/{wix-pricing-plans.js → app/rest/wix-pricing-plans.js} +0 -0
- /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-menu.js → app/rest/wix-restaurants-menu.js} +0 -0
- /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-ordering.js → app/rest/wix-restaurants-ordering.js} +0 -0
- /package/skills/wix-vibe-headless/references/restaurants/{wix-restaurants-reservations.js → app/rest/wix-restaurants-reservations.js} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Grid tile for one event. Styled with base44 design tokens (shadcn Tailwind classes) — re-skin via
|
|
2
|
+
// those tokens (src/index.css :root/.dark), not this JSX. The date/location/teaser field paths and
|
|
3
|
+
// the TICKETING "from" price are load-bearing: lowestPrice is a Money object { value, currency,
|
|
4
|
+
// formattedValue } — render formattedValue, NEVER the raw object (React "objects are not valid as a
|
|
5
|
+
// child" crash). This is a different shape from the ticket-definition price (pricing.fixedPrice.amount)
|
|
6
|
+
// used in the picker.
|
|
7
|
+
import { Link } from "react-router-dom";
|
|
8
|
+
|
|
9
|
+
export default function EventCard({ event }) {
|
|
10
|
+
const when = event.dateAndTimeSettings?.formatted?.dateAndTime;
|
|
11
|
+
const where = event.location?.name;
|
|
12
|
+
const isTicketing = event.registration?.type === "TICKETING";
|
|
13
|
+
const fromPrice = event.registration?.tickets?.lowestPrice?.formattedValue;
|
|
14
|
+
const soldOut = event.registration?.tickets?.soldOut;
|
|
15
|
+
const image = event.mainImage?.url;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Link to={`/events/${event.slug}`}
|
|
19
|
+
className="flex flex-col no-underline text-foreground bg-card border border-border rounded-lg overflow-hidden shadow-sm">
|
|
20
|
+
<div className="relative aspect-[3/2] bg-background">
|
|
21
|
+
{image
|
|
22
|
+
? <img src={image} alt={event.title} loading="lazy" className="w-full h-full object-cover" />
|
|
23
|
+
: <div className="w-full h-full bg-muted flex items-center justify-center" aria-hidden="true"><svg viewBox="0 0 24 24" className="w-8 h-8 text-muted-foreground/40" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="3" width="18" height="18" rx="2" /><circle cx="8.5" cy="8.5" r="1.5" /><path d="m21 15-5-5L5 21" /></svg></div>}
|
|
24
|
+
{isTicketing && soldOut && (
|
|
25
|
+
<span className="absolute top-2 left-2 py-0.5 px-2 text-xs bg-destructive text-destructive-foreground rounded-sm">Sold out</span>
|
|
26
|
+
)}
|
|
27
|
+
</div>
|
|
28
|
+
<div className="p-3 flex flex-col gap-1">
|
|
29
|
+
<h3 className="m-0 font-display text-base font-semibold">{event.title}</h3>
|
|
30
|
+
{when && <span className="text-muted-foreground text-[13px]">{when}</span>}
|
|
31
|
+
{where && <span className="text-muted-foreground text-[13px]">{where}</span>}
|
|
32
|
+
{event.shortDescription && (
|
|
33
|
+
<p className="m-0 mt-1 text-muted-foreground text-sm leading-[1.4]">
|
|
34
|
+
{event.shortDescription}
|
|
35
|
+
</p>
|
|
36
|
+
)}
|
|
37
|
+
{isTicketing && !soldOut && fromPrice && (
|
|
38
|
+
<span className="mt-1 font-semibold text-primary">From {fromPrice}</span>
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
</Link>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Responsive event grid + empty state. Styled with base44 design tokens (shadcn Tailwind classes).
|
|
2
|
+
import EventCard from "./EventCard";
|
|
3
|
+
|
|
4
|
+
export default function EventGrid({ events, empty = "No events yet." }) {
|
|
5
|
+
if (!events?.length) {
|
|
6
|
+
return <p className="text-muted-foreground p-4 text-center">{empty}</p>;
|
|
7
|
+
}
|
|
8
|
+
return (
|
|
9
|
+
<div className="grid gap-4 [grid-template-columns:repeat(auto-fill,minmax(280px,1fr))]">
|
|
10
|
+
{events.map((e) => <EventCard key={e.id} event={e} />)}
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Registration surface for the detail page — branches on registration.type and respects `open`
|
|
2
|
+
// (only OPEN_* statuses accept new registrations). Pure UI; the RSVP/ticketing logic lives in their
|
|
3
|
+
// own hooks/components. Styled with base44 design tokens (shadcn Tailwind classes).
|
|
4
|
+
import RsvpForm from "./RsvpForm";
|
|
5
|
+
import TicketPicker from "./TicketPicker";
|
|
6
|
+
|
|
7
|
+
const closed = "text-destructive font-semibold";
|
|
8
|
+
const link = "inline-block py-3 px-6 no-underline bg-primary text-primary-foreground border-none rounded-sm text-[15px] font-semibold";
|
|
9
|
+
|
|
10
|
+
export default function EventRegistration({ event, type, open, registration }) {
|
|
11
|
+
if (type === "EXTERNAL") {
|
|
12
|
+
return registration.external?.url
|
|
13
|
+
? <a href={registration.external.url} target="_blank" rel="noopener" className={link}>Register</a>
|
|
14
|
+
: null;
|
|
15
|
+
}
|
|
16
|
+
if (type === "NONE") return null;
|
|
17
|
+
|
|
18
|
+
if (type === "RSVP") {
|
|
19
|
+
return open
|
|
20
|
+
? <RsvpForm eventId={event.id} responseType={registration.rsvp?.responseType} />
|
|
21
|
+
: <p className={closed}>Registration is closed.</p>;
|
|
22
|
+
}
|
|
23
|
+
if (type === "TICKETING") {
|
|
24
|
+
return open
|
|
25
|
+
? <TicketPicker event={event} />
|
|
26
|
+
: <p className={closed}>Ticket sales are closed.</p>;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// RSVP form for an RSVP-type event. Pure UI over useRsvpForm — no data logic here. Styled with
|
|
2
|
+
// base44 design tokens (shadcn Tailwind classes). Offers a "NO" reply only when responseType is
|
|
3
|
+
// "YES_AND_NO"; a WAITLIST result (event full) is surfaced distinctly from a confirmed YES.
|
|
4
|
+
import { useRsvpForm } from "@/hooks/useRsvpForm";
|
|
5
|
+
|
|
6
|
+
const input = "w-full px-3 py-2.5 box-border font-body border border-input rounded-sm bg-background text-foreground";
|
|
7
|
+
const label = "block mb-1.5 text-[13px] font-semibold text-muted-foreground";
|
|
8
|
+
const field = "mb-4";
|
|
9
|
+
|
|
10
|
+
export default function RsvpForm({ eventId, responseType }) {
|
|
11
|
+
const { form, setField, submit, submitting, canSubmit, result, error } = useRsvpForm(eventId);
|
|
12
|
+
|
|
13
|
+
if (result) {
|
|
14
|
+
const waitlisted = result.status === "WAITLIST";
|
|
15
|
+
return (
|
|
16
|
+
<div className="p-4 rounded-lg bg-card border border-border text-foreground">
|
|
17
|
+
{waitlisted
|
|
18
|
+
? "This event is full — you've been added to the waitlist. We'll email you if a spot opens."
|
|
19
|
+
: "You're on the list! A confirmation is on its way to your email."}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<form onSubmit={(e) => { e.preventDefault(); submit(); }} className="max-w-[440px]">
|
|
26
|
+
<div className={field}>
|
|
27
|
+
<label className={label}>First name</label>
|
|
28
|
+
<input className={input} value={form.firstName} onChange={(e) => setField("firstName", e.target.value)} required />
|
|
29
|
+
</div>
|
|
30
|
+
<div className={field}>
|
|
31
|
+
<label className={label}>Last name</label>
|
|
32
|
+
<input className={input} value={form.lastName} onChange={(e) => setField("lastName", e.target.value)} required />
|
|
33
|
+
</div>
|
|
34
|
+
<div className={field}>
|
|
35
|
+
<label className={label}>Email</label>
|
|
36
|
+
<input className={input} type="email" value={form.email} onChange={(e) => setField("email", e.target.value)} required />
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{responseType === "YES_AND_NO" && (
|
|
40
|
+
<div className={field}>
|
|
41
|
+
<label className={label}>Will you attend?</label>
|
|
42
|
+
<select className={input} value={form.status} onChange={(e) => setField("status", e.target.value)}>
|
|
43
|
+
<option value="YES">Yes, I'll be there</option>
|
|
44
|
+
<option value="NO">No, I can't make it</option>
|
|
45
|
+
</select>
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
|
|
49
|
+
{error && <p className="text-destructive mb-4">{error}</p>}
|
|
50
|
+
|
|
51
|
+
<button type="submit" disabled={!canSubmit}
|
|
52
|
+
className="py-3 px-6 cursor-pointer bg-primary text-primary-foreground border-none rounded-sm text-[15px] font-semibold disabled:opacity-50 disabled:cursor-not-allowed">
|
|
53
|
+
{submitting ? "Sending…" : "RSVP"}
|
|
54
|
+
</button>
|
|
55
|
+
</form>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Ticket picker for a TICKETING event. Pure UI over useTicketing — no data logic here. Styled with
|
|
2
|
+
// base44 design tokens (shadcn Tailwind classes).
|
|
3
|
+
// • Ticket-definition price is a plain number at pricing.fixedPrice.amount (+ price.currency here).
|
|
4
|
+
// • FREE-only selection → an in-app buyer form + checkoutTickets (no redirect).
|
|
5
|
+
// • Any PAID ticket → "Continue to checkout", which reserves then redirects to the Wix-hosted form.
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { useTicketing } from "@/hooks/useTicketing";
|
|
8
|
+
|
|
9
|
+
const input = "px-3 py-2.5 box-border font-body border border-input rounded-sm bg-background text-foreground";
|
|
10
|
+
|
|
11
|
+
function ticketPrice(def) {
|
|
12
|
+
if (def.free) return "Free";
|
|
13
|
+
const amount = def.price?.amount ?? def.pricing?.fixedPrice?.amount;
|
|
14
|
+
const currency = def.price?.currency ?? def.pricing?.fixedPrice?.currency ?? "";
|
|
15
|
+
return amount != null ? `${amount} ${currency}`.trim() : "";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function TicketPicker({ event }) {
|
|
19
|
+
const t = useTicketing(event);
|
|
20
|
+
const [buyer, setBuyer] = useState({ firstName: "", lastName: "", email: "" });
|
|
21
|
+
const setBuyerField = (k, v) => setBuyer((b) => ({ ...b, [k]: v }));
|
|
22
|
+
|
|
23
|
+
if (t.order) {
|
|
24
|
+
return (
|
|
25
|
+
<div className="p-4 rounded-lg bg-card border border-border">
|
|
26
|
+
Your tickets are confirmed.{" "}
|
|
27
|
+
{t.order.ticketsPdf && (
|
|
28
|
+
<a href={t.order.ticketsPdf} target="_blank" rel="noopener" className="text-primary">Download tickets (PDF)</a>
|
|
29
|
+
)}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!t.definitions.length) {
|
|
35
|
+
return <p className="text-muted-foreground">No tickets are currently on sale.</p>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const buyerReady = buyer.firstName && buyer.lastName && buyer.email;
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div>
|
|
42
|
+
{t.definitions.map((def) => (
|
|
43
|
+
<div key={def.id} className="flex items-center justify-between gap-4 py-3 border-b border-border">
|
|
44
|
+
<div>
|
|
45
|
+
<div className="font-semibold">{def.name}</div>
|
|
46
|
+
{def.description && <div className="text-muted-foreground text-sm">{def.description}</div>}
|
|
47
|
+
<div className="text-primary font-semibold mt-0.5">{ticketPrice(def)}</div>
|
|
48
|
+
</div>
|
|
49
|
+
<input type="number" min={0} value={t.selection[def.id]?.quantity ?? 0}
|
|
50
|
+
onChange={(e) => t.setQuantity(def.id, Number(e.target.value) || 0)}
|
|
51
|
+
className={`${input} w-[72px] text-center`} />
|
|
52
|
+
</div>
|
|
53
|
+
))}
|
|
54
|
+
|
|
55
|
+
{t.error && <p className="text-destructive mt-4">{t.error}</p>}
|
|
56
|
+
|
|
57
|
+
{t.hasSelection && t.allFree && (
|
|
58
|
+
<div className="mt-4 grid gap-2 max-w-[440px]">
|
|
59
|
+
<input className={`${input} w-full`} placeholder="First name" value={buyer.firstName}
|
|
60
|
+
onChange={(e) => setBuyerField("firstName", e.target.value)} />
|
|
61
|
+
<input className={`${input} w-full`} placeholder="Last name" value={buyer.lastName}
|
|
62
|
+
onChange={(e) => setBuyerField("lastName", e.target.value)} />
|
|
63
|
+
<input className={`${input} w-full`} type="email" placeholder="Email" value={buyer.email}
|
|
64
|
+
onChange={(e) => setBuyerField("email", e.target.value)} />
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
|
|
68
|
+
{t.hasSelection && (
|
|
69
|
+
<button
|
|
70
|
+
disabled={t.submitting || (t.allFree && !buyerReady)}
|
|
71
|
+
onClick={() => (t.allFree ? t.checkoutFree(buyer) : t.checkoutPaid())}
|
|
72
|
+
className="mt-4 py-3 px-6 cursor-pointer bg-primary text-primary-foreground border-none rounded-sm text-[15px] font-semibold disabled:opacity-50 disabled:cursor-not-allowed">
|
|
73
|
+
{t.submitting ? "Processing…" : t.allFree ? "Get tickets" : "Continue to checkout"}
|
|
74
|
+
</button>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// useEventDetail — load one event by slug and derive its registration state. No markup.
|
|
2
|
+
// • getEventBySlug returns null on miss → notFound (never invent an event).
|
|
3
|
+
// • registration.type is "RSVP" | "TICKETING" | "EXTERNAL" | "NONE" — the detail page branches on it.
|
|
4
|
+
// • Only registration.status values starting "OPEN_" accept new registrations; otherwise `open` is
|
|
5
|
+
// false and the page shows the closed state.
|
|
6
|
+
// • shortDescription is a plain string (safe to render). event.description is Ricos rich content
|
|
7
|
+
// { nodes: [...] } — NOT a string; render with @wix/ricos or walk nodes, never call string
|
|
8
|
+
// methods on it (that crashes the page). This hook does not touch description.
|
|
9
|
+
import { useState, useEffect } from "react";
|
|
10
|
+
import { getEventBySlug } from "@/rest/wix-events-browse";
|
|
11
|
+
|
|
12
|
+
export function useEventDetail(slug) {
|
|
13
|
+
const [event, setEvent] = useState(null);
|
|
14
|
+
const [notFound, setNotFound] = useState(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setEvent(null);
|
|
18
|
+
setNotFound(false);
|
|
19
|
+
getEventBySlug(slug).then((e) => (e ? setEvent(e) : setNotFound(true)));
|
|
20
|
+
}, [slug]);
|
|
21
|
+
|
|
22
|
+
const reg = event?.registration ?? {};
|
|
23
|
+
const type = reg.type ?? "NONE";
|
|
24
|
+
const open = typeof reg.status === "string" && reg.status.startsWith("OPEN_");
|
|
25
|
+
|
|
26
|
+
return { event, notFound, type, open, registration: reg };
|
|
27
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// useEventsList — all listing logic, no markup: load the category menu + upcoming count, list
|
|
2
|
+
// events (all or filtered by category), and page with offset "load more". The data shapes here are
|
|
3
|
+
// the bug-prone part — keep them verbatim; the Events page only renders what this returns.
|
|
4
|
+
// • queryEvents / listEventsByCategory return { events, total, offset, nextOffset } — an OBJECT,
|
|
5
|
+
// not a bare array; nextOffset is null when there are no more pages.
|
|
6
|
+
// • queryEventCategories returns { categories, total }; render category.name,
|
|
7
|
+
// key/filter by category.id, count = counts.assignedEventsCount.
|
|
8
|
+
// • total === 0 → the whole catalog is empty; show the "publish events" empty state.
|
|
9
|
+
import { useState, useEffect } from "react";
|
|
10
|
+
import {
|
|
11
|
+
queryEvents, listEventsByCategory, queryEventCategories, countUpcomingEvents,
|
|
12
|
+
} from "@/rest/wix-events-browse";
|
|
13
|
+
|
|
14
|
+
export function useEventsList({ pageSize = 24 } = {}) {
|
|
15
|
+
const [events, setEvents] = useState([]);
|
|
16
|
+
const [nextOffset, setNextOffset] = useState(null); // offset for the next page; null when no more
|
|
17
|
+
const [categories, setCategories] = useState([]); // category menu
|
|
18
|
+
const [active, setActive] = useState(null); // selected category id, or null for "all"
|
|
19
|
+
const [total, setTotal] = useState(null); // upcoming count across the whole catalog
|
|
20
|
+
const [loading, setLoading] = useState(true);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
countUpcomingEvents().then(setTotal);
|
|
24
|
+
queryEventCategories().then(({ categories }) => setCategories(categories));
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setLoading(true);
|
|
29
|
+
const load = active
|
|
30
|
+
? listEventsByCategory(active, { limit: pageSize })
|
|
31
|
+
: queryEvents({ limit: pageSize });
|
|
32
|
+
load.then(({ events, nextOffset }) => {
|
|
33
|
+
setEvents(events);
|
|
34
|
+
setNextOffset(nextOffset);
|
|
35
|
+
setLoading(false);
|
|
36
|
+
});
|
|
37
|
+
}, [active, pageSize]);
|
|
38
|
+
|
|
39
|
+
const loadMore = () => {
|
|
40
|
+
if (nextOffset === null) return;
|
|
41
|
+
const load = active
|
|
42
|
+
? listEventsByCategory(active, { limit: pageSize, offset: nextOffset })
|
|
43
|
+
: queryEvents({ limit: pageSize, offset: nextOffset });
|
|
44
|
+
load.then(({ events: more, nextOffset: next }) => {
|
|
45
|
+
setEvents((e) => [...e, ...more]);
|
|
46
|
+
setNextOffset(next);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
events, categories, active, setActive,
|
|
52
|
+
total, loading, hasMore: nextOffset !== null, loadMore,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// useRsvpForm — RSVP submission logic for an RSVP-type event, no markup.
|
|
2
|
+
// • createRsvp(eventId, { firstName, lastName, email, status, additionalGuestNames? }) completes
|
|
3
|
+
// fully client-side (no redirect) and throws on closed/full registration, guest-limit, duplicate
|
|
4
|
+
// email, or invalid form — surface the message, don't swallow it.
|
|
5
|
+
// • Only offer status "NO" when registration.rsvp.responseType === "YES_AND_NO".
|
|
6
|
+
// • A full-with-waitlist event returns the RSVP with status "WAITLIST" — tell the guest.
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { createRsvp } from "@/rest/wix-events-registration";
|
|
9
|
+
|
|
10
|
+
export function useRsvpForm(eventId) {
|
|
11
|
+
const [form, setForm] = useState({ firstName: "", lastName: "", email: "", status: "YES" });
|
|
12
|
+
const [guests, setGuests] = useState([]); // additional guest names (strings)
|
|
13
|
+
const [submitting, setSubmitting] = useState(false);
|
|
14
|
+
const [result, setResult] = useState(null); // the created RSVP (carries .status) on success
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
|
|
17
|
+
const setField = (name, value) => setForm((f) => ({ ...f, [name]: value }));
|
|
18
|
+
|
|
19
|
+
async function submit() {
|
|
20
|
+
setSubmitting(true);
|
|
21
|
+
setError(null);
|
|
22
|
+
try {
|
|
23
|
+
const rsvp = await createRsvp(eventId, {
|
|
24
|
+
firstName: form.firstName,
|
|
25
|
+
lastName: form.lastName,
|
|
26
|
+
email: form.email,
|
|
27
|
+
status: form.status,
|
|
28
|
+
additionalGuestNames: guests.filter(Boolean),
|
|
29
|
+
});
|
|
30
|
+
setResult(rsvp); // rsvp.status is "YES" | "NO" | "WAITLIST"
|
|
31
|
+
} catch (e) {
|
|
32
|
+
setError(e.message);
|
|
33
|
+
} finally {
|
|
34
|
+
setSubmitting(false);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const canSubmit = !!(form.firstName && form.lastName && form.email) && !submitting;
|
|
39
|
+
return { form, setField, guests, setGuests, submit, submitting, canSubmit, result, error };
|
|
40
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// useTicketing — ticket selection + checkout logic for a TICKETING event, no markup.
|
|
2
|
+
// • queryTicketDefinitions(eventId) already returns only non-hidden, buyable (SALE_STARTED) tickets.
|
|
3
|
+
// • Ticket-definition price is a PLAIN number at pricing.fixedPrice.amount (+ currency) — a different
|
|
4
|
+
// shape from the card's registration.tickets.lowestPrice Money object.
|
|
5
|
+
// • reserveTickets([...]) holds the tickets (status PENDING) and throws if they aren't actually held.
|
|
6
|
+
// • PAID tickets: reserve → window.location = getTicketCheckoutUrl(event, reservationId) (the Wix-
|
|
7
|
+
// hosted ticket form collects guest details + payment). NEVER hand-build that URL.
|
|
8
|
+
// • FREE tickets only: reserve → checkoutTickets(eventId, { reservationId, buyer, guests }) finishes
|
|
9
|
+
// in-app and returns an order with status "FREE"; it throws for paid orders.
|
|
10
|
+
import { useState, useEffect } from "react";
|
|
11
|
+
import {
|
|
12
|
+
queryTicketDefinitions, reserveTickets, getTicketCheckoutUrl, checkoutTickets,
|
|
13
|
+
} from "@/rest/wix-events-registration";
|
|
14
|
+
|
|
15
|
+
export function useTicketing(event) {
|
|
16
|
+
const eventId = event?.id;
|
|
17
|
+
const [definitions, setDefinitions] = useState([]);
|
|
18
|
+
const [selection, setSelection] = useState({}); // { [defId]: { quantity, guestPrice?, pricingOptionId? } }
|
|
19
|
+
const [submitting, setSubmitting] = useState(false);
|
|
20
|
+
const [order, setOrder] = useState(null); // free-checkout order on success
|
|
21
|
+
const [error, setError] = useState(null);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!eventId) return;
|
|
25
|
+
queryTicketDefinitions(eventId).then(setDefinitions);
|
|
26
|
+
}, [eventId]);
|
|
27
|
+
|
|
28
|
+
const setLine = (defId, patch) =>
|
|
29
|
+
setSelection((s) => ({ ...s, [defId]: { quantity: 0, ...s[defId], ...patch } }));
|
|
30
|
+
const setQuantity = (defId, quantity) => setLine(defId, { quantity: Math.max(0, quantity) });
|
|
31
|
+
|
|
32
|
+
const lines = Object.entries(selection)
|
|
33
|
+
.filter(([, l]) => l.quantity > 0)
|
|
34
|
+
.map(([ticketDefinitionId, l]) => ({
|
|
35
|
+
ticketDefinitionId,
|
|
36
|
+
quantity: l.quantity,
|
|
37
|
+
guestPrice: l.guestPrice,
|
|
38
|
+
pricingOptionId: l.pricingOptionId,
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
const hasSelection = lines.length > 0;
|
|
42
|
+
const allFree = hasSelection && lines.every((l) => definitions.find((d) => d.id === l.ticketDefinitionId)?.free);
|
|
43
|
+
|
|
44
|
+
// PAID (or mixed): reserve then hand off to the Wix-hosted ticket form.
|
|
45
|
+
async function checkoutPaid() {
|
|
46
|
+
setSubmitting(true);
|
|
47
|
+
setError(null);
|
|
48
|
+
try {
|
|
49
|
+
const reservation = await reserveTickets(lines);
|
|
50
|
+
window.location.href = getTicketCheckoutUrl(event, reservation.id);
|
|
51
|
+
} catch (e) {
|
|
52
|
+
setError(e.message);
|
|
53
|
+
setSubmitting(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// FREE tickets only: reserve then finish in-app; buyer = { firstName, lastName, email }.
|
|
58
|
+
async function checkoutFree(buyer) {
|
|
59
|
+
setSubmitting(true);
|
|
60
|
+
setError(null);
|
|
61
|
+
try {
|
|
62
|
+
const reservation = await reserveTickets(lines);
|
|
63
|
+
const created = await checkoutTickets(eventId, {
|
|
64
|
+
reservationId: reservation.id,
|
|
65
|
+
buyer,
|
|
66
|
+
guests: [{ firstName: buyer.firstName, lastName: buyer.lastName, email: buyer.email }],
|
|
67
|
+
});
|
|
68
|
+
setOrder(created); // status "FREE"; carries ticketsPdf + tickets[]
|
|
69
|
+
} catch (e) {
|
|
70
|
+
setError(e.message);
|
|
71
|
+
} finally {
|
|
72
|
+
setSubmitting(false);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
definitions, selection, setQuantity, setLine,
|
|
78
|
+
hasSelection, allFree, submitting, order, error,
|
|
79
|
+
checkoutPaid, checkoutFree,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Event detail page — thin view over useEventDetail (all logic lives in the hook). Renders the
|
|
2
|
+
// event summary + the registration surface. Styled with base44 design tokens (shadcn Tailwind classes).
|
|
3
|
+
//
|
|
4
|
+
// shortDescription is a PLAIN string (safe to render). event.description is Ricos rich content
|
|
5
|
+
// { nodes: [...] } — NOT a string; to show the full body render it with @wix/ricos or walk `nodes`.
|
|
6
|
+
// NEVER call string methods (.slice/.substring/.split) on event.description — that crashes the page.
|
|
7
|
+
import { useParams } from "react-router-dom";
|
|
8
|
+
import { useEventDetail } from "@/hooks/useEventDetail";
|
|
9
|
+
import EventRegistration from "@/components/EventRegistration";
|
|
10
|
+
|
|
11
|
+
export default function EventDetail() {
|
|
12
|
+
const { slug } = useParams();
|
|
13
|
+
const d = useEventDetail(slug);
|
|
14
|
+
|
|
15
|
+
if (d.notFound) return <Centered>Event not found.</Centered>;
|
|
16
|
+
if (!d.event) return <Centered>Loading…</Centered>;
|
|
17
|
+
|
|
18
|
+
const { event } = d;
|
|
19
|
+
const when = event.dateAndTimeSettings?.formatted?.dateAndTime;
|
|
20
|
+
const where = event.location?.name;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<main className="max-w-[1200px] mx-auto p-4 grid gap-8 [grid-template-columns:repeat(auto-fit,minmax(320px,1fr))]">
|
|
24
|
+
<div className="aspect-[3/2] bg-card rounded-lg overflow-hidden">
|
|
25
|
+
{event.mainImage?.url &&
|
|
26
|
+
<img src={event.mainImage.url} alt={event.title} className="w-full h-full object-cover" />}
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div>
|
|
30
|
+
<h1 className="font-display m-0 mb-2">{event.title}</h1>
|
|
31
|
+
{when && <p className="m-0 mb-1 text-muted-foreground">{when}</p>}
|
|
32
|
+
{where && <p className="m-0 mb-4 text-muted-foreground">{where}</p>}
|
|
33
|
+
|
|
34
|
+
{event.shortDescription && (
|
|
35
|
+
<p className="text-foreground leading-relaxed mb-6">
|
|
36
|
+
{event.shortDescription}
|
|
37
|
+
</p>
|
|
38
|
+
)}
|
|
39
|
+
|
|
40
|
+
<EventRegistration event={event} type={d.type} open={d.open} registration={d.registration} />
|
|
41
|
+
</div>
|
|
42
|
+
</main>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function Centered({ children }) {
|
|
47
|
+
return <div className="p-12 text-center text-muted-foreground">{children}</div>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Events listing page — category menu + grid + empty state + load more. Thin view over
|
|
2
|
+
// useEventsList (all logic lives in the hook). Styled with base44 design tokens (shadcn Tailwind classes).
|
|
3
|
+
import { useEventsList } from "@/hooks/useEventsList";
|
|
4
|
+
import CategoryFilter from "@/components/CategoryFilter";
|
|
5
|
+
import EventGrid from "@/components/EventGrid";
|
|
6
|
+
|
|
7
|
+
export default function Events() {
|
|
8
|
+
const { events, categories, active, setActive, total, loading, hasMore, loadMore } = useEventsList();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<main className="max-w-[1200px] mx-auto p-4">
|
|
12
|
+
<h1 className="font-display mb-4">Events</h1>
|
|
13
|
+
|
|
14
|
+
{total === 0 ? (
|
|
15
|
+
<p className="text-muted-foreground p-4 text-center">
|
|
16
|
+
No events published yet — add and publish events from your Wix dashboard.
|
|
17
|
+
</p>
|
|
18
|
+
) : (
|
|
19
|
+
<>
|
|
20
|
+
<CategoryFilter categories={categories} active={active} onSelect={setActive} />
|
|
21
|
+
{loading
|
|
22
|
+
? <p className="text-muted-foreground">Loading…</p>
|
|
23
|
+
: <EventGrid events={events} empty="No events in this category yet." />}
|
|
24
|
+
{hasMore && (
|
|
25
|
+
<div className="text-center mt-6">
|
|
26
|
+
<button onClick={loadMore}
|
|
27
|
+
className="py-2.5 px-6 cursor-pointer text-[15px] font-semibold bg-card text-foreground border border-border rounded-sm">
|
|
28
|
+
Load more
|
|
29
|
+
</button>
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
</>
|
|
33
|
+
)}
|
|
34
|
+
</main>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -24,13 +24,14 @@ import { wixApiRequest } from "./wix-client.js";
|
|
|
24
24
|
* type {string} — "RSVP"|"TICKETING"|"EXTERNAL"|"NONE",
|
|
25
25
|
* status {string} — only OPEN_* statuses accept new registrations,
|
|
26
26
|
* rsvp.responseType — "YES_AND_NO" allows a "NO" reply,
|
|
27
|
-
* tickets.
|
|
27
|
+
* tickets.lowestPrice {object} — money { value, currency, formattedValue }; render
|
|
28
|
+
* formattedValue, not the object (see "Money/price fields" in SKILL.md). tickets.soldOut {boolean},
|
|
28
29
|
* external.url — link out when type === "EXTERNAL",
|
|
29
30
|
* eventPageUrl {object} — { base, path } (URLS fieldset) — needed for getTicketCheckoutUrl,
|
|
30
31
|
* form {object} — registration form controls (FORM fieldset),
|
|
31
32
|
* calendarUrls {object} — { google, ics } (DETAILS fieldset)
|
|
32
33
|
*
|
|
33
|
-
* Category: { id,
|
|
34
|
+
* Category: { id, name, counts.assignedEventsCount }
|
|
34
35
|
* Full model: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/categories
|
|
35
36
|
*/
|
|
36
37
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Events — seeding
|
|
2
|
+
|
|
3
|
+
Seed Wix Events (Events V3) by **calling `seed-events.js`** — don't hand-write the REST calls. It's
|
|
4
|
+
a build-time module (run via `exec_tool`, not shipped in the app) that abstracts every Wix Events
|
|
5
|
+
seed operation. `require` it and call the functions with plain data.
|
|
6
|
+
|
|
7
|
+
> **NOT yet live-verified — transcribed from `setup-events.md`.** Endpoints/fields are as written in
|
|
8
|
+
> the recipe; if a live call disagrees, trust the docs (see Fallback).
|
|
9
|
+
|
|
10
|
+
Two one-way constraints fix the order: `registration.initialType` (`TICKETING`/`RSVP`) is **immutable**
|
|
11
|
+
after create, and **publishing is one-way**. So per event: create DRAFT → (ticketed) add tiers → publish.
|
|
12
|
+
`setupEvents` **installs the Wix Events app first** (idempotent — a re-install returns 200), so seeding works even if the site doesn't have it yet.
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
// build-time exec_tool
|
|
16
|
+
const { accessToken } = await base44.asServiceRole.connectors.getConnection("wix"); // Base44 (generic: use $TOKEN)
|
|
17
|
+
const fs = require("fs");
|
|
18
|
+
// exec_tool's require can return EMPTY exports for these build-time modules — load the file itself:
|
|
19
|
+
const seed = (() => { const m = { exports: {} };
|
|
20
|
+
new Function("module", "exports", "require", fs.readFileSync("/app/.agents/skills/wix-vibe-headless/references/events/seed/seed-events.js", "utf8"))(m, m.exports, require);
|
|
21
|
+
return m.exports; })();
|
|
22
|
+
const ctx = { token: accessToken, siteId: WIX_METASITE_ID };
|
|
23
|
+
|
|
24
|
+
// DEFAULT — one call runs the whole flow per event (create DRAFT → tiers → publish), then resolves
|
|
25
|
+
// category NAMES → ids + assigns and attaches main images. Ids are kept in memory; nothing is
|
|
26
|
+
// hand-threaded across exec calls. Dates MUST be in the future (ISO-8601 UTC); default ~60–90 days
|
|
27
|
+
// out and note it if the request gives none. price is a decimal STRING; ticket name <= 30 chars;
|
|
28
|
+
// omit ticketTiers for RSVP/free, omit imageUrl if you have none.
|
|
29
|
+
const summary = await seed.setupEvents(ctx, {
|
|
30
|
+
events: [{
|
|
31
|
+
title: "Summer Synth Festival", shortDescription: "One night of analog sound.",
|
|
32
|
+
type: "TICKETING", startDate: "2026-10-01T03:30:00.000Z", endDate: "2026-10-01T07:00:00.000Z",
|
|
33
|
+
timeZoneId: "America/Los_Angeles",
|
|
34
|
+
location: { name: "The Echo Lot", type: "VENUE", address: { addressLine: "120 Harbor St", city: "Seattle", subdivision: "US-WA", postalCode: "98101", country: "US" } },
|
|
35
|
+
ticketTiers: [{ name: "General Admission", price: "65.00", initialLimit: 200 }],
|
|
36
|
+
category: "Talks",
|
|
37
|
+
// imageUrl is optional and attached IN this one call. Pass a plain url — the module imports it to
|
|
38
|
+
// Wix Media for you (events binds the main image by file id). Use the FINAL https://media.base44.com/...
|
|
39
|
+
// url from the COMPLETED generate_image (it runs in the background while you build — wait for it),
|
|
40
|
+
// never a still-generating /__generating__/<id>.png placeholder. altText defaults to the event slug.
|
|
41
|
+
imageUrl: "https://media.base44.com/…",
|
|
42
|
+
}],
|
|
43
|
+
});
|
|
44
|
+
// summary -> { events: [{ id, slug, ticketCount, category }], categories: [{ id, name }], imagesAttached }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Seeding is additive — never delete or overwrite existing content.** Don't clean up, don't remove
|
|
48
|
+
"sample" data, don't reset. Just add.
|
|
49
|
+
|
|
50
|
+
## Escape hatch — individual functions
|
|
51
|
+
Reach for the functions below only when the one-call `setupEvents` doesn't fit (re-running a single
|
|
52
|
+
step, a shape it doesn't model). `setupEvents` is built from them, in this order:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// STEP 1 — create each event as a DRAFT. TICKETING = paid tiers; RSVP = free built-in form (no fields to seed).
|
|
56
|
+
const ev = await seed.createEvent(ctx, {
|
|
57
|
+
title: "Summer Synth Festival", shortDescription: "One night of analog sound.",
|
|
58
|
+
type: "TICKETING", startDate: "2026-10-01T03:30:00.000Z", endDate: "2026-10-01T07:00:00.000Z",
|
|
59
|
+
timeZoneId: "America/Los_Angeles",
|
|
60
|
+
location: { name: "The Echo Lot", type: "VENUE", address: { addressLine: "120 Harbor St", city: "Seattle", subdivision: "US-WA", postalCode: "98101", country: "US" } },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// STEP 2 — TICKETING only: add tiers BEFORE publish. price is a decimal STRING; name <= 30 chars; omit initialLimit for unlimited.
|
|
64
|
+
const tiers = await seed.createTicketTiers(ctx, ev.id, [{ name: "General Admission", price: "65.00", initialLimit: 200 }]);
|
|
65
|
+
|
|
66
|
+
// STEP 3 — publish (one-way; ticketed events only after tiers exist)
|
|
67
|
+
await seed.publishEvent(ctx, ev.id);
|
|
68
|
+
|
|
69
|
+
// STEP 4 (optional) — group by a format/track (v1 Categories)
|
|
70
|
+
const cats = await seed.createEventCategories(ctx, ["Talks"]);
|
|
71
|
+
await seed.assignEventsToCategory(ctx, cats[0].id, [ev.id]);
|
|
72
|
+
|
|
73
|
+
// Attach images (optional): import the url to Wix Media (events binds by file id), then set mainImage.
|
|
74
|
+
const file = await seed.importImage(ctx, imageUrl); // → { id, url } (Wix Media file id + wixstatic url)
|
|
75
|
+
await seed.setEventMainImage(ctx, { eventId: ev.id, id: file.id, url: file.url, height: 1024, width: 1024, altText: ev.slug });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Paid-ticket precondition — record, do NOT block:** seeding succeeds and the event goes live
|
|
79
|
+
regardless of payment setup, but *completing a paid purchase* later needs a premium plan **and** a
|
|
80
|
+
configured payment method in the dashboard. Note it in the kept output; never fail the seed over it.
|
|
81
|
+
Free/RSVP events need neither.
|
|
82
|
+
|
|
83
|
+
## Functions
|
|
84
|
+
| fn | does |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `setupEvents(ctx, {events})` | **DEFAULT** — one call: per event create DRAFT → tiers → publish, then resolve category names → assign + attach images → `{events, categories, imagesAttached}` |
|
|
87
|
+
| `createEvent(ctx, event)` | STEP 1 — create ONE draft event (no bulk; loop for many) → `{id, slug}` |
|
|
88
|
+
| `createTicketTiers(ctx, eventId, tiers)` | STEP 2 — TICKETING only, parallel batch → `[{id}]` |
|
|
89
|
+
| `publishEvent(ctx, eventId)` | STEP 3 — publish (one-way) |
|
|
90
|
+
| `createEventCategories(ctx, names)` | STEP 4 (opt) — v1 Categories, one call each → `[{id,name}]` |
|
|
91
|
+
| `assignEventsToCategory(ctx, categoryId, eventIds)` | STEP 4 (opt) — path `/{categoryId}/events`, body `{eventId:[…]}` |
|
|
92
|
+
| `importImage(ctx, url)` | import an external url into Wix Media → `{id,url}` (file id + wixstatic url); the main image binds by this file id |
|
|
93
|
+
| `setEventMainImage(ctx, {eventId,id,url,height,width,altText})` | optional — PATCH `mainImage` (no revision); `id` = a Wix Media file id from `importImage` |
|
|
94
|
+
|
|
95
|
+
## Reference
|
|
96
|
+
If a call returns a shape you didn't expect, or you need an operation this module doesn't cover,
|
|
97
|
+
use the **`wix-docs`** skill to search + read the live Wix API reference — never guess. The
|
|
98
|
+
authoritative source recipe is `wix-headless/references/inline-recipes/setup-events.md`.
|
|
99
|
+
|
|
100
|
+
Read a method's page before writing its call: it carries the exact body shape, the required
|
|
101
|
+
permission scope, and the response envelope.
|
|
102
|
+
- Install a Wix app onto the site: https://dev.wix.com/docs/api-reference/business-management/app-installation/app-installation/install-app.md
|
|
103
|
+
- Import an image into Wix Media: https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/import-file.md
|
|
104
|
+
- Create Event: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/events-v3/create-event.md
|
|
105
|
+
- Create Ticket Definition: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/ticket-definitions-v3/create-ticket-definition.md
|
|
106
|
+
- Create Category: https://dev.wix.com/docs/api-reference/business-solutions/events/event-management/categories/create-category.md
|
|
107
|
+
- Get Site Properties (timezone / currency): https://dev.wix.com/docs/api-reference/business-management/site-properties/properties/get-site-properties.md
|