@wix/agent-skills 1.13.0 → 1.15.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 +4 -1
- package/package.json +1 -1
- package/skills/README.md +23 -0
- package/skills/wix-app/SKILL.md +10 -2
- package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
- package/skills/wix-app/references/CODE_QUALITY.md +1 -0
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
- package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
- package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
- package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
- package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
- package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
- package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
- package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
- package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
- package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
- package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
- package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
- package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
- package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
- package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
- package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
- package/skills/wix-auth/SKILL.md +12 -0
- package/skills/wix-auth/references/device-flow.md +140 -0
- package/skills/wix-docs/SKILL.md +188 -0
- package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
- package/skills/wix-docs/references/EXTRACTING.md +120 -0
- package/skills/wix-headless/SKILL.md +84 -130
- package/skills/wix-headless/entry/bootstrap.mjs +93 -0
- package/skills/wix-headless/entry/skill.md +78 -0
- package/skills/wix-headless/references/AI_FEATURES.md +178 -0
- package/skills/wix-headless/references/CAPABILITIES.md +84 -0
- package/skills/wix-headless/references/DISCOVERY.md +34 -56
- package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
- package/skills/wix-headless/references/FEEDBACK.md +118 -0
- package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
- package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
- package/skills/wix-headless/references/SEED.md +44 -188
- package/skills/wix-headless/references/SETUP.md +32 -103
- package/skills/wix-headless/references/astro.md +98 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
- package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
- package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
- package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
- package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
- package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
- package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
- package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
- package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
- package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
- package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
- package/skills/wix-headless/references/managed/CONNECT.md +74 -0
- package/skills/wix-headless/references/managed/CREATE.md +130 -0
- package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
- package/skills/wix-headless/references/non-astro.md +59 -0
- package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
- package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
- package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
- package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
- package/skills/wix-manage/SKILL.md +24 -1
- package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
- package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
- package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
- package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
- package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
- package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
- package/skills/wix-vibe-headless/SKILL.md +136 -0
- package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
- package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
- package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
- package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
- package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
- package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
- package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
- package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
- package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
- package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
- package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
- package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
- package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
- package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
- package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
- package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
- package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
- package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
- package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
- package/skills/wix-headless/references/BUILD-astro.md +0 -244
- package/skills/wix-headless/references/BUILD-own-build.md +0 -167
- package/skills/wix-headless/references/BUILD.md +0 -105
- package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
- package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
- package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
- package/skills/wix-headless/references/PLAN-connect.md +0 -19
- package/skills/wix-headless/references/PLAN-create.md +0 -17
- package/skills/wix-headless/references/PLAN.md +0 -92
- package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
- package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
- package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
- package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
- package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
- package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
- package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
- package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
- package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
- package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
- package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
- package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
- package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
- package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
- package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
- package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
- package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
- package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
- package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
- package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
- package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
- package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
- package/skills/wix-headless/references/astro/templates/Footer.astro +0 -27
- package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
- package/skills/wix-headless/references/astro/templates/Navigation.astro +0 -38
- package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
- package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
- package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
- package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
- package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
- package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
- package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
- package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
- package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
- package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
- package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
- package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
- package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
- package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
- package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
- package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
- package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
- package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
- package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
- package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
- package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
- package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
- package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
- package/skills/wix-headless/references/astro/templates/global.css +0 -288
- package/skills/wix-headless/references/astro/templates/index.astro +0 -56
- package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
- package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
- package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
- package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
- package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
- package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
- package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
- package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
- package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
- package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
- package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
- package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
- package/skills/wix-headless/references/bookings/FLOW.md +0 -246
- package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
- package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
- package/skills/wix-headless/references/commands/known-apps.json +0 -6
- package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
- package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
- package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
- package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
- package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
- package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
- package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
- package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
- package/skills/wix-headless/references/seed-recipes.md +0 -49
- package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
- package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
- package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
- package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
- package/skills/wix-headless/references/shared/STYLING.md +0 -141
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
- package/skills/wix-headless/references/verticals/_schema.json +0 -74
- package/skills/wix-headless/references/verticals/_schema.md +0 -95
- package/skills/wix-headless/references/verticals/blog.md +0 -31
- package/skills/wix-headless/references/verticals/bookings.md +0 -41
- package/skills/wix-headless/references/verticals/cms.md +0 -30
- package/skills/wix-headless/references/verticals/ecom.md +0 -25
- package/skills/wix-headless/references/verticals/forms.md +0 -26
- package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
- package/skills/wix-headless/references/verticals/stores.md +0 -33
- package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
- package/skills/wix-headless/scripts/compose.mjs +0 -525
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
- package/skills/wix-headless/scripts/flatten.sh +0 -61
- package/skills/wix-headless/scripts/generate-images.mjs +0 -242
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -148
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
- package/skills/wix-headless/scripts/scaffold.sh +0 -139
- package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
- package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
- package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
- package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
- package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
// src/pages/services/index.astro — SSR services listing grid (APPOINTMENT or CLASS).
|
|
3
|
-
// One dir deep inside src/pages → ../../ reaches src/. Adapt copy/headings to the
|
|
4
|
-
// brand; keep the SSR data wiring.
|
|
5
|
-
//
|
|
6
|
-
// Optional catalog filters (both auto-skip when there's nothing to filter):
|
|
7
|
-
// location — a location selector, shown ONLY when the site has >1 location
|
|
8
|
-
// (business + custom + customer). Mirrors the SoT's location-first
|
|
9
|
-
// flow without forcing a separate step: single-location sites never
|
|
10
|
-
// see it. The choice is carried as ?locationId (+?locationType) and
|
|
11
|
-
// forwarded into both the services query and the detail page's
|
|
12
|
-
// availability.
|
|
13
|
-
// category — a category filter bar, shown ONLY when >1 category exists. The
|
|
14
|
-
// choice is carried as ?category and merged into the services query.
|
|
15
|
-
// Both are plain links that re-SSR with query params (re-query, like the SoT) —
|
|
16
|
-
// no client JS on the catalog.
|
|
17
|
-
import Layout from "../../layouts/Layout.astro";
|
|
18
|
-
import ServiceCard from "../../components/ServiceCard.astro";
|
|
19
|
-
import { services, categoriesV2 } from "@wix/bookings";
|
|
20
|
-
import { auth } from "@wix/essentials";
|
|
21
|
-
|
|
22
|
-
// Wix Bookings app id — the base filter must scope queryServices to it.
|
|
23
|
-
const BOOKING_APP_ID = "13d21c63-b5ec-5912-8397-c3a5ddb27a97";
|
|
24
|
-
|
|
25
|
-
const reqUrl = new URL(Astro.request.url);
|
|
26
|
-
const selectedCategory = reqUrl.searchParams.get("category") ?? "";
|
|
27
|
-
const selectedLocation = reqUrl.searchParams.get("locationId") ?? "";
|
|
28
|
-
const selectedLocationType = reqUrl.searchParams.get("locationType") ?? "";
|
|
29
|
-
|
|
30
|
-
// ── Services filter (appId + optional category + optional location) ─────────
|
|
31
|
-
// A real business-location id filters by locations.business.id; the synthetic
|
|
32
|
-
// "custom"/"customer" ids map to a location-TYPE filter (the SoT mapping). Built
|
|
33
|
-
// from URL params only, so it doesn't depend on the locations/categories reads.
|
|
34
|
-
const filter: Record<string, any> = { appId: BOOKING_APP_ID };
|
|
35
|
-
if (selectedCategory) filter["category.id"] = { $eq: selectedCategory };
|
|
36
|
-
if (selectedLocation === "custom") filter["locations.type"] = { $hasSome: ["CUSTOM"] };
|
|
37
|
-
else if (selectedLocation === "customer") filter["locations.type"] = { $hasSome: ["CUSTOMER"] };
|
|
38
|
-
else if (selectedLocation) filter["locations.business.id"] = { $hasSome: [selectedLocation] };
|
|
39
|
-
|
|
40
|
-
// ── Catalog reads — three INDEPENDENT queries, fetched concurrently ─────────
|
|
41
|
-
// queryServices (the filtered list) + queryLocations (selector) + queryCategories
|
|
42
|
-
// (bar) don't depend on each other, so run them in parallel (the SoT fetches
|
|
43
|
-
// services + categories with Promise.allSettled likewise) — one round-trip's
|
|
44
|
-
// latency, not three. Each is individually non-fatal: a failed read degrades only
|
|
45
|
-
// its own piece (an empty list / a hidden selector or bar), never the whole page.
|
|
46
|
-
// Ambient @wix/astro SSR client via @wix/essentials — do NOT build
|
|
47
|
-
// createClient({ auth: OAuthStrategy({ clientId: import.meta.env.* }) }); that env
|
|
48
|
-
// var is client-only and undefined at server render → 500.
|
|
49
|
-
const [servicesResult, locResult, catResult] = await Promise.all([
|
|
50
|
-
auth
|
|
51
|
-
.elevate(services.queryServices)({ query: { filter, paging: { limit: 100 } }, conditionalFields: ["STAFF_MEMBER_DETAILS"] })
|
|
52
|
-
.find()
|
|
53
|
-
.catch((err: any) => { console.error("[services] listing query failed:", err); return null; }),
|
|
54
|
-
auth.elevate(services.queryLocations)().catch((err: any) => { console.error("[services] queryLocations failed:", err); return null; }),
|
|
55
|
-
auth.elevate(categoriesV2.queryCategories)().find().catch((err: any) => { console.error("[services] queryCategories failed:", err); return null; }),
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
const serviceList: any[] = (servicesResult?.items ?? []).filter((s: any) => !s.hidden);
|
|
59
|
-
|
|
60
|
-
// Locations — auto-skip the selector when ≤1 (business + custom + customer).
|
|
61
|
-
const businessLocations: any[] = locResult?.businessLocations?.locations ?? [];
|
|
62
|
-
const hasCustomLocations: boolean = locResult?.customLocations?.exists ?? false;
|
|
63
|
-
const hasCustomerLocations: boolean = locResult?.customerLocations?.exists ?? false;
|
|
64
|
-
const locationCount =
|
|
65
|
-
businessLocations.length + (hasCustomLocations ? 1 : 0) + (hasCustomerLocations ? 1 : 0);
|
|
66
|
-
const showLocationSelector = locationCount > 1;
|
|
67
|
-
|
|
68
|
-
// Categories — non-fatal; show the bar only when >1 (a fresh site has one default).
|
|
69
|
-
const categories: any[] = catResult?.items ?? [];
|
|
70
|
-
const showCategoryBar = categories.length > 1;
|
|
71
|
-
|
|
72
|
-
// Build a /services href preserving the current selection, applying overrides.
|
|
73
|
-
// Pass null to clear a param. locationType is always paired with locationId.
|
|
74
|
-
const hrefWith = (patch: Record<string, string | null>): string => {
|
|
75
|
-
const p = new URLSearchParams();
|
|
76
|
-
if (selectedCategory) p.set("category", selectedCategory);
|
|
77
|
-
if (selectedLocation) {
|
|
78
|
-
p.set("locationId", selectedLocation);
|
|
79
|
-
if (selectedLocationType) p.set("locationType", selectedLocationType);
|
|
80
|
-
}
|
|
81
|
-
for (const [k, v] of Object.entries(patch)) {
|
|
82
|
-
if (v === null) p.delete(k);
|
|
83
|
-
else p.set(k, v);
|
|
84
|
-
}
|
|
85
|
-
if (patch.locationId === null) p.delete("locationType");
|
|
86
|
-
const qs = p.toString();
|
|
87
|
-
return qs ? `/services?${qs}` : "/services";
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
// Is a filter narrowing the list right now? Drives the empty-state copy.
|
|
91
|
-
const filterActive = Boolean(selectedCategory || selectedLocation);
|
|
92
|
-
|
|
93
|
-
const getSlug = (s: any): string => s.mainSlug?.name ?? s.supportedSlugs?.[0]?.name ?? s._id;
|
|
94
|
-
const formatPrice = (s: any): string | undefined => {
|
|
95
|
-
const p = s.payment;
|
|
96
|
-
if (!p || p.rateType === "NO_FEE") return undefined;
|
|
97
|
-
if (p.rateType === "FIXED" && p.fixed?.price) {
|
|
98
|
-
const { value, currency } = p.fixed.price;
|
|
99
|
-
if (!value) return undefined;
|
|
100
|
-
return new Intl.NumberFormat("en-US", { style: "currency", currency: currency ?? "USD" }).format(Number(value));
|
|
101
|
-
}
|
|
102
|
-
return undefined;
|
|
103
|
-
};
|
|
104
|
-
const getDuration = (s: any): number => s.schedule?.availabilityConstraints?.sessionDurations?.[0] ?? 60;
|
|
105
|
-
const locationName = (loc: any): string => loc?.business?.name ?? loc?.calculatedAddress?.city ?? "Location";
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
<Layout title="Services">
|
|
109
|
-
<section class="max-w-6xl mx-auto px-6 py-24">
|
|
110
|
-
<header class="flex flex-col gap-4 max-w-prose mb-16">
|
|
111
|
-
<hr class="editorial-rule w-16 ml-0" />
|
|
112
|
-
<h1 class="font-display text-4xl md:text-5xl leading-tight">Our Services</h1>
|
|
113
|
-
<!-- Optional brand tagline -->
|
|
114
|
-
</header>
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
showLocationSelector && (
|
|
118
|
-
<nav class="booking-filter-bar" aria-label="Filter by location">
|
|
119
|
-
<a href={hrefWith({ locationId: null })} class={`booking-filter-chip${selectedLocation ? "" : " booking-filter-chip--active"}`}>All locations</a>
|
|
120
|
-
{businessLocations.map((loc: any) => (
|
|
121
|
-
<a
|
|
122
|
-
href={hrefWith({ locationId: loc._id, locationType: "BUSINESS" })}
|
|
123
|
-
class={`booking-filter-chip${selectedLocation === loc._id ? " booking-filter-chip--active" : ""}`}
|
|
124
|
-
>
|
|
125
|
-
{locationName(loc)}
|
|
126
|
-
</a>
|
|
127
|
-
))}
|
|
128
|
-
{hasCustomLocations && (
|
|
129
|
-
<a href={hrefWith({ locationId: "custom", locationType: "CUSTOM" })} class={`booking-filter-chip${selectedLocation === "custom" ? " booking-filter-chip--active" : ""}`}>Custom location</a>
|
|
130
|
-
)}
|
|
131
|
-
{hasCustomerLocations && (
|
|
132
|
-
<a href={hrefWith({ locationId: "customer", locationType: "CUSTOMER" })} class={`booking-filter-chip${selectedLocation === "customer" ? " booking-filter-chip--active" : ""}`}>My location</a>
|
|
133
|
-
)}
|
|
134
|
-
</nav>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
{
|
|
139
|
-
showCategoryBar && (
|
|
140
|
-
<nav class="booking-filter-bar" aria-label="Filter by category">
|
|
141
|
-
<a href={hrefWith({ category: null })} class={`booking-filter-chip${selectedCategory ? "" : " booking-filter-chip--active"}`}>All</a>
|
|
142
|
-
{categories.map((cat: any) => (
|
|
143
|
-
<a
|
|
144
|
-
href={hrefWith({ category: cat._id })}
|
|
145
|
-
class={`booking-filter-chip${selectedCategory === cat._id ? " booking-filter-chip--active" : ""}`}
|
|
146
|
-
>
|
|
147
|
-
{cat.name ?? "Category"}
|
|
148
|
-
</a>
|
|
149
|
-
))}
|
|
150
|
-
</nav>
|
|
151
|
-
)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
serviceList.length === 0 ? (
|
|
156
|
-
<p class="text-mute">
|
|
157
|
-
{filterActive
|
|
158
|
-
? "No services match your selection — try a different filter."
|
|
159
|
-
: "Services coming soon — check back shortly."}
|
|
160
|
-
</p>
|
|
161
|
-
) : (
|
|
162
|
-
<div class="service-grid">
|
|
163
|
-
{serviceList.map((s) => (
|
|
164
|
-
<ServiceCard
|
|
165
|
-
id={s._id}
|
|
166
|
-
slug={getSlug(s)}
|
|
167
|
-
name={s.name ?? "Untitled"}
|
|
168
|
-
tagLine={s.tagLine ?? s.description}
|
|
169
|
-
durationMinutes={getDuration(s)}
|
|
170
|
-
price={formatPrice(s)}
|
|
171
|
-
imageUrl={s.media?.mainMedia?.image?.url ?? s.media?.items?.[0]?.image?.url}
|
|
172
|
-
type={s.type ?? "APPOINTMENT"}
|
|
173
|
-
locationId={selectedLocation || undefined}
|
|
174
|
-
locationType={selectedLocationType || undefined}
|
|
175
|
-
/>
|
|
176
|
-
))}
|
|
177
|
-
</div>
|
|
178
|
-
)
|
|
179
|
-
}
|
|
180
|
-
</section>
|
|
181
|
-
</Layout>
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
2
|
-
import { currentCart } from "@wix/ecom";
|
|
3
|
-
|
|
4
|
-
// CartView writes { lineItems, summary } to sessionStorage on every successful
|
|
5
|
-
// fetch/update. Read the snapshot here so the badge count renders instantly
|
|
6
|
-
// on every navigation instead of flashing empty while the fresh fetch runs.
|
|
7
|
-
// Same key as CartView; CartBadge is a read-only consumer.
|
|
8
|
-
const CART_CACHE_KEY = "cart:last-snapshot";
|
|
9
|
-
|
|
10
|
-
function readCachedCount(): number {
|
|
11
|
-
if (typeof window === "undefined") return 0;
|
|
12
|
-
try {
|
|
13
|
-
const raw = window.sessionStorage.getItem(CART_CACHE_KEY);
|
|
14
|
-
if (!raw) return 0;
|
|
15
|
-
const parsed = JSON.parse(raw);
|
|
16
|
-
const items = Array.isArray(parsed?.lineItems) ? parsed.lineItems : [];
|
|
17
|
-
return items.reduce(
|
|
18
|
-
(sum: number, item: any) => sum + (item?.quantity ?? 0),
|
|
19
|
-
0,
|
|
20
|
-
);
|
|
21
|
-
} catch {
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default function CartBadge() {
|
|
27
|
-
const [count, setCount] = useState(() => readCachedCount());
|
|
28
|
-
|
|
29
|
-
const fetchCount = async () => {
|
|
30
|
-
try {
|
|
31
|
-
const cart = await currentCart.getCurrentCart();
|
|
32
|
-
const total = (cart.lineItems ?? []).reduce(
|
|
33
|
-
(sum, item) => sum + (item.quantity ?? 0),
|
|
34
|
-
0
|
|
35
|
-
);
|
|
36
|
-
setCount(total);
|
|
37
|
-
} catch {
|
|
38
|
-
setCount(0);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
// Always fetch client-side — cart count is per-visitor and must not
|
|
44
|
-
// be server-rendered (would break SSR caching)
|
|
45
|
-
fetchCount();
|
|
46
|
-
|
|
47
|
-
const handleCartUpdate = (e: Event) => {
|
|
48
|
-
const detail = (e as CustomEvent).detail;
|
|
49
|
-
if (detail?.cart?.lineItems) {
|
|
50
|
-
const total = (detail.cart.lineItems as any[]).reduce(
|
|
51
|
-
(sum: number, item: any) => sum + (item.quantity ?? 0),
|
|
52
|
-
0
|
|
53
|
-
);
|
|
54
|
-
setCount(total);
|
|
55
|
-
} else if (detail?.delta) {
|
|
56
|
-
setCount((prev) => prev + detail.delta);
|
|
57
|
-
} else {
|
|
58
|
-
fetchCount();
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
window.addEventListener("cart-updated", handleCartUpdate);
|
|
62
|
-
return () => window.removeEventListener("cart-updated", handleCartUpdate);
|
|
63
|
-
}, []);
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<a href="/cart" className="cart-badge" aria-label={count > 0 ? `Cart, ${count} items` : "Cart"}>
|
|
67
|
-
<svg
|
|
68
|
-
className="cart-badge-icon"
|
|
69
|
-
viewBox="0 0 24 24"
|
|
70
|
-
fill="none"
|
|
71
|
-
stroke="currentColor"
|
|
72
|
-
strokeWidth="1.6"
|
|
73
|
-
strokeLinecap="round"
|
|
74
|
-
strokeLinejoin="round"
|
|
75
|
-
aria-hidden="true"
|
|
76
|
-
focusable="false"
|
|
77
|
-
>
|
|
78
|
-
<path d="M5 8h14l-1.2 10.2a2 2 0 0 1-2 1.8H8.2a2 2 0 0 1-2-1.8L5 8Z" />
|
|
79
|
-
<path d="M9 8V6a3 3 0 0 1 6 0v2" />
|
|
80
|
-
</svg>
|
|
81
|
-
{count > 0 && <span className="cart-badge-count">{count}</span>}
|
|
82
|
-
</a>
|
|
83
|
-
);
|
|
84
|
-
}
|