@wix/agent-skills 1.14.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.
Files changed (247) hide show
  1. package/README.md +4 -1
  2. package/package.json +1 -1
  3. package/skills/README.md +23 -0
  4. package/skills/wix-app/SKILL.md +10 -2
  5. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
  6. package/skills/wix-app/references/CODE_QUALITY.md +1 -0
  7. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
  9. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
  10. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  11. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  12. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  13. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  31. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  32. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  33. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  34. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
  35. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  36. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  37. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
  38. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  39. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  40. package/skills/wix-auth/SKILL.md +12 -0
  41. package/skills/wix-auth/references/device-flow.md +140 -0
  42. package/skills/wix-docs/SKILL.md +188 -0
  43. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  44. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  45. package/skills/wix-headless/SKILL.md +84 -130
  46. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  47. package/skills/wix-headless/entry/skill.md +78 -0
  48. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  49. package/skills/wix-headless/references/CAPABILITIES.md +84 -0
  50. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  51. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  52. package/skills/wix-headless/references/FEEDBACK.md +118 -0
  53. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  54. package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
  55. package/skills/wix-headless/references/SEED.md +44 -188
  56. package/skills/wix-headless/references/SETUP.md +32 -103
  57. package/skills/wix-headless/references/astro.md +98 -0
  58. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  59. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  60. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  61. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  62. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  63. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  64. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  65. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  66. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  67. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  72. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  73. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
  74. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  75. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  76. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  77. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
  78. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
  79. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  80. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
  81. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  83. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  84. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  85. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  86. package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
  87. package/skills/wix-headless/references/non-astro.md +59 -0
  88. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  89. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
  90. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  91. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
  92. package/skills/wix-manage/SKILL.md +24 -1
  93. package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
  94. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  95. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
  96. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
  97. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
  98. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  99. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
  100. package/skills/wix-vibe-headless/SKILL.md +136 -0
  101. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  102. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  103. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
  104. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  105. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
  106. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  107. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  108. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  109. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
  110. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  111. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  112. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  113. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  114. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
  115. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  116. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  117. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  118. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  119. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  120. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  121. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  122. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
  123. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  124. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
  125. package/skills/wix-headless/references/BUILD-astro.md +0 -253
  126. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  127. package/skills/wix-headless/references/BUILD.md +0 -105
  128. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  129. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  130. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  131. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  132. package/skills/wix-headless/references/PLAN-create.md +0 -17
  133. package/skills/wix-headless/references/PLAN.md +0 -92
  134. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  135. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  136. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  137. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  138. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  139. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  140. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  141. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  142. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  143. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  144. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  145. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  146. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  147. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  148. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  149. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  150. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  151. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  152. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  153. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  154. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  155. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  156. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  157. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  158. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  159. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  160. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  161. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  162. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  163. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  164. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  165. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  166. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  167. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  168. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  169. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  170. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  171. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  172. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  173. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  174. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  175. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  176. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  177. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  178. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  179. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  180. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  181. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  182. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  183. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  184. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  185. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  186. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  187. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  188. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  189. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  190. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  191. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  192. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  193. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  194. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  195. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  196. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  197. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  198. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  199. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  200. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  201. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  202. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  203. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  204. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  205. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  206. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  207. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  208. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  209. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  210. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  211. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  212. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  213. package/skills/wix-headless/references/seed-recipes.md +0 -49
  214. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  215. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  216. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  217. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  218. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  219. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  220. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  221. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  222. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  223. package/skills/wix-headless/references/shared/STYLING.md +0 -140
  224. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  225. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  226. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  227. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  228. package/skills/wix-headless/references/verticals/blog.md +0 -31
  229. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  230. package/skills/wix-headless/references/verticals/cms.md +0 -30
  231. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  232. package/skills/wix-headless/references/verticals/forms.md +0 -26
  233. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  234. package/skills/wix-headless/references/verticals/stores.md +0 -33
  235. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  236. package/skills/wix-headless/scripts/compose.mjs +0 -520
  237. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  238. package/skills/wix-headless/scripts/flatten.sh +0 -61
  239. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  240. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
  241. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  242. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  243. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  244. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  245. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  246. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  247. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -1,424 +0,0 @@
1
- /* src/styles/components-bookings.css
2
- *
3
- * Bookings-pack component CSS. Pre-copied by the orchestrator before the build
4
- * wave (it is brand-agnostic var(--token) CSS). The designer's global.css does
5
- * NOT publish these classes — they live here. See references/shared/STYLING.md
6
- * § "Component-specific CSS is owned by the component, not the designer".
7
- *
8
- * Class groups:
9
- * - .service-card / .service-grid / .service-card-* → ServiceCard.astro, services/index.astro
10
- * - .booking-filter-bar / .booking-filter-chip* → services/index.astro (location + category filters)
11
- * - .availability-* / .time-slot* → AvailabilityCalendar.tsx (week calendar, slots, staff picker)
12
- * - .booking-* → BookingForm.tsx (schema-driven form)
13
- *
14
- * Primary actions (a selected slot, the confirm button) use var(--color-accent)
15
- * so the flow matches the site's primary-action styling.
16
- *
17
- * Direct var(--token) only (no @apply). Fallback chains for sometimes-published
18
- * tokens, e.g. var(--color-paper-warm, var(--color-paper, var(--color-cream))).
19
- */
20
-
21
- /* ── Service grid + card ────────────────────────────────────────────────────── */
22
- .service-grid {
23
- display: grid;
24
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
25
- gap: 2rem;
26
- transition: opacity 200ms ease;
27
- }
28
- body[data-navigating="true"] .service-grid {
29
- opacity: 0.55;
30
- pointer-events: none;
31
- }
32
-
33
- .service-card {
34
- position: relative;
35
- display: flex;
36
- flex-direction: column;
37
- background: var(--color-paper, var(--color-cream));
38
- border-radius: var(--radius-xl);
39
- overflow: hidden;
40
- text-decoration: none;
41
- color: inherit;
42
- transition: transform 280ms ease, box-shadow 280ms ease;
43
- box-shadow: var(--shadow-card, 0 4px 16px -8px rgba(0, 0, 0, 0.15));
44
- }
45
- .service-card:hover {
46
- transform: translateY(-4px);
47
- }
48
- .service-card:hover .service-card-image img {
49
- transform: scale(1.04);
50
- }
51
-
52
- .service-card-image {
53
- aspect-ratio: 3 / 2;
54
- overflow: hidden;
55
- background: var(--color-paper-warm, var(--color-surface-secondary, var(--color-cream)));
56
- }
57
- .service-card-image img {
58
- width: 100%;
59
- height: 100%;
60
- object-fit: cover;
61
- transition: transform 600ms ease;
62
- }
63
-
64
- .service-card-meta {
65
- display: flex;
66
- flex-direction: column;
67
- gap: 0.5rem;
68
- padding: 1rem 1rem 1.5rem;
69
- flex: 1;
70
- }
71
- .service-card-name {
72
- margin: 0;
73
- font-family: var(--font-display);
74
- font-size: 1.125rem;
75
- line-height: 1.25;
76
- color: var(--color-ink);
77
- }
78
- .service-card-tagline {
79
- margin: 0;
80
- font-family: var(--font-body);
81
- font-size: 0.875rem;
82
- color: var(--color-ink-soft, var(--color-mute));
83
- line-height: 1.45;
84
- }
85
- .service-card-price {
86
- display: flex;
87
- align-items: center;
88
- gap: 0.75rem;
89
- margin-top: auto;
90
- padding-top: 0.75rem;
91
- font-family: var(--font-body);
92
- font-size: 0.875rem;
93
- color: var(--color-mute);
94
- }
95
- .service-card-price span + span::before {
96
- content: "·";
97
- padding-right: 0.75rem;
98
- color: var(--color-rule);
99
- }
100
-
101
- /* ── Catalog filters (location + category) ──────────────────────────────────── */
102
- .booking-filter-bar {
103
- display: flex;
104
- flex-wrap: wrap;
105
- gap: 0.75rem;
106
- margin-bottom: 2rem;
107
- }
108
- .booking-filter-chip {
109
- padding: 0.5rem 1rem;
110
- border: 1px solid var(--color-rule);
111
- border-radius: var(--radius-pill, 999px);
112
- background: var(--color-paper, var(--color-cream));
113
- color: var(--color-ink);
114
- font-family: var(--font-body);
115
- font-size: 0.875rem;
116
- text-decoration: none;
117
- cursor: pointer;
118
- transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
119
- }
120
- .booking-filter-chip:hover {
121
- border-color: var(--color-ink);
122
- }
123
- .booking-filter-chip--active {
124
- background: var(--color-accent);
125
- border-color: var(--color-accent);
126
- color: var(--color-paper);
127
- }
128
-
129
- /* ── Availability — week calendar ───────────────────────────────────────────── */
130
- .availability-calendar {
131
- display: flex;
132
- flex-direction: column;
133
- gap: 1.5rem;
134
- }
135
-
136
- /* Filter row — holds the optional location + staff pickers side by side. */
137
- .availability-filters {
138
- display: flex;
139
- flex-wrap: wrap;
140
- gap: 1rem;
141
- }
142
- .availability-filters > * {
143
- flex: 1 1 12rem;
144
- }
145
-
146
- /* Location / staff picker (shown only when there's >1 option). */
147
- .availability-staff {
148
- display: flex;
149
- flex-direction: column;
150
- gap: 0.5rem;
151
- }
152
- .availability-staff-label {
153
- font-family: var(--font-display);
154
- font-size: 0.75rem;
155
- text-transform: uppercase;
156
- letter-spacing: 0.05em;
157
- color: var(--color-ink-soft, var(--color-mute));
158
- }
159
- .availability-staff-select {
160
- width: 100%;
161
- padding: 0.75rem 1rem;
162
- font-family: var(--font-body);
163
- font-size: 0.9375rem;
164
- border: 1px solid var(--color-rule);
165
- border-radius: var(--radius-sm);
166
- background: var(--color-paper, var(--color-cream));
167
- color: var(--color-ink);
168
- box-sizing: border-box;
169
- }
170
- .availability-staff-select:focus {
171
- outline: none;
172
- border-color: var(--color-accent);
173
- }
174
-
175
- .availability-week-nav {
176
- display: flex;
177
- align-items: center;
178
- justify-content: space-between;
179
- gap: 1rem;
180
- padding: 0.75rem 0;
181
- border-bottom: 1px solid var(--color-rule);
182
- }
183
- .availability-week-label {
184
- font-family: var(--font-display);
185
- font-size: 1rem;
186
- color: var(--color-ink);
187
- flex: 1;
188
- text-align: center;
189
- }
190
-
191
- .availability-nav-btn {
192
- padding: 0.75rem 1rem;
193
- background: transparent;
194
- border: 1px solid var(--color-rule);
195
- border-radius: var(--radius-sm);
196
- color: var(--color-ink);
197
- font-family: var(--font-body);
198
- font-size: 0.875rem;
199
- cursor: pointer;
200
- transition: background-color 150ms ease, border-color 150ms ease;
201
- }
202
- .availability-nav-btn:hover:not(:disabled) {
203
- background: var(--color-paper-warm, var(--color-cream));
204
- border-color: var(--color-ink);
205
- }
206
- .availability-nav-btn:disabled {
207
- opacity: 0.35;
208
- cursor: not-allowed;
209
- }
210
-
211
- /* The 7-day strip. */
212
- .availability-day-strip {
213
- display: grid;
214
- grid-template-columns: repeat(7, 1fr);
215
- gap: 0.75rem;
216
- }
217
- .availability-day {
218
- display: flex;
219
- flex-direction: column;
220
- align-items: center;
221
- gap: 2px;
222
- padding: 0.75rem 0;
223
- border: 1px solid var(--color-rule);
224
- border-radius: var(--radius-sm);
225
- background: var(--color-paper, var(--color-cream));
226
- color: var(--color-ink);
227
- font-family: var(--font-body);
228
- cursor: pointer;
229
- transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
230
- }
231
- .availability-day-name {
232
- font-size: 0.7rem;
233
- text-transform: uppercase;
234
- letter-spacing: 0.04em;
235
- color: var(--color-mute);
236
- }
237
- .availability-day-num {
238
- font-size: 1rem;
239
- font-weight: 600;
240
- }
241
- .availability-day--has-slots:hover {
242
- border-color: var(--color-accent);
243
- }
244
- .availability-day--empty {
245
- opacity: 0.4;
246
- cursor: not-allowed;
247
- }
248
- .availability-day--selected {
249
- background: var(--color-accent);
250
- border-color: var(--color-accent);
251
- color: var(--color-paper);
252
- }
253
- .availability-day--selected .availability-day-name {
254
- color: var(--color-paper);
255
- }
256
-
257
- .availability-slots {
258
- display: grid;
259
- grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
260
- gap: 0.75rem;
261
- }
262
- .availability-loading,
263
- .availability-empty,
264
- .availability-error {
265
- font-family: var(--font-body);
266
- font-size: 0.9375rem;
267
- color: var(--color-ink-soft, var(--color-mute));
268
- padding: 1.5rem 0;
269
- text-align: center;
270
- }
271
- .availability-empty {
272
- display: flex;
273
- flex-direction: column;
274
- align-items: center;
275
- gap: 1rem;
276
- }
277
- .availability-error {
278
- color: var(--color-error, var(--color-accent));
279
- }
280
-
281
- /* ── Time-slot buttons ──────────────────────────────────────────────────────── */
282
- .time-slot {
283
- padding: 0.75rem 1rem;
284
- border: 1px solid var(--color-rule);
285
- border-radius: var(--radius-sm);
286
- background: var(--color-paper, var(--color-cream));
287
- color: var(--color-ink);
288
- font-family: var(--font-body);
289
- font-size: 0.875rem;
290
- text-align: center;
291
- cursor: pointer;
292
- transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
293
- }
294
- .time-slot-time {
295
- font-weight: 500;
296
- }
297
- .time-slot--available {
298
- border-color: var(--color-ink);
299
- }
300
- .time-slot--available:hover {
301
- background: var(--color-accent);
302
- border-color: var(--color-accent);
303
- color: var(--color-paper);
304
- }
305
- .time-slot--selected {
306
- background: var(--color-accent);
307
- border-color: var(--color-accent);
308
- color: var(--color-paper);
309
- font-weight: 600;
310
- }
311
-
312
- /* ── Booking form (schema-driven) ───────────────────────────────────────────── */
313
- .booking-form {
314
- display: flex;
315
- flex-direction: column;
316
- gap: 1.5rem;
317
- padding: 2rem;
318
- border: 1px solid var(--color-rule);
319
- border-radius: var(--radius-md);
320
- background: var(--color-paper-warm, var(--color-paper, var(--color-cream)));
321
- }
322
-
323
- .booking-form-summary {
324
- display: flex;
325
- flex-direction: column;
326
- gap: 0.5rem;
327
- padding-bottom: 1rem;
328
- border-bottom: 1px solid var(--color-rule);
329
- }
330
- .booking-form-summary strong {
331
- font-family: var(--font-display);
332
- font-size: 1.125rem;
333
- color: var(--color-ink);
334
- }
335
- .booking-form-summary span {
336
- font-family: var(--font-body);
337
- font-size: 0.9375rem;
338
- color: var(--color-ink-soft, var(--color-mute));
339
- }
340
- .booking-form-change {
341
- align-self: flex-start;
342
- margin-top: 0.5rem;
343
- background: none;
344
- border: none;
345
- padding: 0;
346
- font-family: var(--font-body);
347
- font-size: 0.8125rem;
348
- color: var(--color-mute);
349
- text-decoration: underline;
350
- cursor: pointer;
351
- }
352
- .booking-form-change:hover {
353
- color: var(--color-ink);
354
- }
355
-
356
- .booking-field {
357
- display: flex;
358
- flex-direction: column;
359
- gap: 0.5rem;
360
- }
361
- .booking-label {
362
- font-family: var(--font-display);
363
- font-size: 0.75rem;
364
- text-transform: uppercase;
365
- letter-spacing: 0.05em;
366
- color: var(--color-ink-soft, var(--color-mute));
367
- }
368
- .booking-required {
369
- color: var(--color-accent);
370
- }
371
-
372
- .booking-input {
373
- width: 100%;
374
- padding: 0.75rem 1rem;
375
- font-family: var(--font-body);
376
- font-size: 0.9375rem;
377
- border: 1px solid var(--color-rule);
378
- border-radius: var(--radius-sm);
379
- background: var(--color-paper, var(--color-cream));
380
- color: var(--color-ink);
381
- transition: border-color 150ms ease;
382
- box-sizing: border-box;
383
- }
384
- .booking-input:focus {
385
- outline: none;
386
- border-color: var(--color-accent);
387
- }
388
- textarea.booking-input {
389
- resize: vertical;
390
- min-height: 6rem;
391
- }
392
-
393
- .booking-error {
394
- font-family: var(--font-body);
395
- font-size: 0.875rem;
396
- color: var(--color-error, var(--color-accent));
397
- padding: 0.75rem 1rem;
398
- border: 1px solid var(--color-error, var(--color-accent));
399
- border-radius: var(--radius-sm);
400
- }
401
-
402
- .booking-cta {
403
- display: inline-flex;
404
- align-items: center;
405
- justify-content: center;
406
- width: 100%;
407
- padding: 1rem 2rem;
408
- font-family: var(--font-display);
409
- font-size: 0.9375rem;
410
- font-weight: 500;
411
- background: var(--color-accent);
412
- color: var(--color-paper);
413
- border: 1px solid var(--color-accent);
414
- border-radius: var(--radius-sm);
415
- cursor: pointer;
416
- transition: opacity 150ms ease;
417
- }
418
- .booking-cta:hover:not(:disabled) {
419
- opacity: 0.9;
420
- }
421
- .booking-cta:disabled {
422
- opacity: 0.5;
423
- cursor: not-allowed;
424
- }
@@ -1,176 +0,0 @@
1
- ---
2
- // src/pages/services/[slug].astro — SSR service detail + client-side booking flow.
3
- // Two dirs deep inside src/ → import with ../../ (not three ../).
4
- import Layout from "../../layouts/Layout.astro";
5
- import SeoTags from "../../components/SeoTags.astro";
6
- import ServiceBookingFlow from "../../components/ServiceBookingFlow";
7
- import { services } from "@wix/bookings";
8
- import { forms } from "@wix/forms";
9
- import { auth } from "@wix/essentials";
10
-
11
- const BOOKING_APP_ID = "13d21c63-b5ec-5912-8397-c3a5ddb27a97";
12
- const { slug } = Astro.params;
13
-
14
- // Carried from the catalog's location selector (when the site has >1 location):
15
- // the default location the availability picker scopes to. Absent on single-location
16
- // sites (and on deep links — the picker then defaults to the service's first location).
17
- const reqUrl = new URL(Astro.request.url);
18
- const locationId = reqUrl.searchParams.get("locationId") ?? undefined;
19
-
20
- let service: any = null;
21
- try {
22
- // Ambient SSR via @wix/essentials. Single service by slug: the .eq() builder
23
- // chain on mainSlug.name + appId (the form the @wix/bookings SDK expects).
24
- const result = await auth
25
- .elevate(services.queryServices)({ conditionalFields: ["STAFF_MEMBER_DETAILS"] })
26
- .eq("mainSlug.name", slug)
27
- .eq("appId", BOOKING_APP_ID)
28
- .limit(1)
29
- .find();
30
- service = result.items?.[0] ?? null;
31
- } catch (err) {
32
- console.error(`[services/${slug}] detail query failed:`, err);
33
- }
34
-
35
- if (!service) return Astro.redirect("/services", 302);
36
-
37
- // Booking-form SCHEMA — the form belongs to the service (service.form._id) in the
38
- // bookings namespace. Read it server-side and pass the field list to the island.
39
- // Same renderer the forms vertical uses (references/astro/forms/CONTACT_FORM.md):
40
- // keep the field's `target` — that is the key createBooking expects in formSubmission.
41
- let formFields: any[] = [];
42
- try {
43
- const formId = service.form?._id;
44
- if (formId) {
45
- const res: any = await auth.elevate(forms.getForm)(formId);
46
- const form = res?.form ?? res;
47
- // Only render field types we can submit as a simple value. Skip complex,
48
- // object-valued fields (e.g. a multi-line ADDRESS) — they carry no string
49
- // `componentType`, and sending a string for them fails createBooking with
50
- // "must be object". The booking enforces only the contact basics
51
- // (first_name/last_name/email), so skipping optional complex fields is safe.
52
- const RENDERABLE = ["TEXT_INPUT", "PHONE_INPUT", "DROPDOWN"];
53
- formFields = (form?.formFields ?? [])
54
- .filter(
55
- (f: any) =>
56
- f.fieldType === "INPUT" &&
57
- !f.hidden &&
58
- RENDERABLE.includes(f.inputOptions?.stringOptions?.componentType),
59
- )
60
- .map((f: any) => {
61
- const opts = f.inputOptions;
62
- const str = opts?.stringOptions;
63
- const label =
64
- str?.textInputOptions?.label ??
65
- str?.dropdownOptions?.label ??
66
- str?.phoneInputOptions?.label ??
67
- "";
68
- return {
69
- label,
70
- target: opts?.target ?? "",
71
- required: opts?.required ?? false,
72
- componentType: str?.componentType ?? "TEXT_INPUT",
73
- identifier: f.identifier ?? "",
74
- options: str?.dropdownOptions?.options?.map((o: any) => ({
75
- value: o.value ?? o.label ?? "",
76
- label: o.label ?? o.value ?? "",
77
- })),
78
- };
79
- });
80
- }
81
- } catch (err) {
82
- console.error(`[services/${slug}] booking form schema failed:`, err);
83
- }
84
-
85
- const formatPrice = (p: any): string | undefined => {
86
- if (!p || p.rateType === "NO_FEE") return undefined;
87
- if (p.rateType === "FIXED" && p.fixed?.price) {
88
- const { value, currency } = p.fixed.price;
89
- if (!value) return undefined;
90
- return new Intl.NumberFormat("en-US", { style: "currency", currency: currency ?? "USD" }).format(Number(value));
91
- }
92
- return undefined;
93
- };
94
- const price = formatPrice(service.payment);
95
- const duration = service.schedule?.availabilityConstraints?.sessionDurations?.[0] ?? 60;
96
- const imageUrl = service.media?.mainMedia?.image?.url ?? service.media?.items?.[0]?.image?.url;
97
- const serviceName = service.name ?? "Service";
98
- const seoTags = service.seoData?.tags ?? [];
99
-
100
- // Staff for the optional staff picker — carried on the service via the
101
- // STAFF_MEMBER_DETAILS conditional field (already requested in the query above).
102
- // Each entry is { staffMemberId, name } — `staffMemberId` is, despite the name,
103
- // the resource id (the calendar filters availability + books by it). The calendar
104
- // shows the picker only when there is more than one; empty/absent → "any staff
105
- // member" (the ANY_RESOURCE fallback).
106
- const staffMembers = service.staffMemberDetails?.staffMembers ?? [];
107
-
108
- // Business locations the service is offered at — sourced from `queryLocations()`
109
- // (the site's real business locations, whose ids the availability engine
110
- // recognizes), intersected with the service's own location ids. Availability is
111
- // scoped to one of these so a multi-location service doesn't return duplicate
112
- // per-location time slots (listAvailabilityTimeSlots returns one slot per location
113
- // otherwise). Source from `queryLocations()`, NOT from `service.locations` alone:
114
- // a service's location entry can carry an id the availability engine doesn't
115
- // recognize, and scoping to it returns zero slots. When the site has no business
116
- // locations this resolves to [] and the calendar fetches unscoped.
117
- let serviceLocations: { _id: string; name?: string }[] = [];
118
- try {
119
- const locResult: any = await auth.elevate(services.queryLocations)();
120
- const businessLocations = locResult?.businessLocations?.locations ?? [];
121
- const serviceLocationIds = new Set(
122
- (service.locations ?? [])
123
- .filter((l: any) => (l.type ?? "BUSINESS") === "BUSINESS")
124
- .map((l: any) => l.business?._id ?? l._id)
125
- .filter(Boolean),
126
- );
127
- serviceLocations = businessLocations
128
- .filter((l: any) => serviceLocationIds.has(l._id))
129
- .map((l: any) => ({ _id: l._id, name: l.business?.name ?? "Location" }));
130
- } catch (err) {
131
- console.error(`[services/${slug}] queryLocations failed:`, err);
132
- }
133
- ---
134
-
135
- <!--
136
- Width: use `container-reading` (max-width: var(--container-prose) + auto margins)
137
- for a deliberate prose measure. Bare `max-w-<size>` keys resolve to Tailwind's
138
- --container-* scale, which is wider than ideal for reading text.
139
- -->
140
- <Layout title={serviceName} description={service.tagLine ?? service.description}>
141
- <SeoTags tags={seoTags} slot="head" />
142
- <section class="container-reading px-6 py-24">
143
- <a href="/services" class="inline-block text-sm text-mute hover:text-ink mb-8">← All services</a>
144
-
145
- <!-- Optional banner image — only when the service has media (image-less is the
146
- common seed case; rendering a fixed placeholder collapses the layout). -->
147
- {imageUrl && (
148
- <img src={imageUrl} alt={serviceName} class="w-full h-64 object-cover rounded-lg mb-8" />
149
- )}
150
-
151
- <div class="flex flex-col gap-4 mb-16">
152
- <hr class="editorial-rule w-16 ml-0" />
153
- <h1 class="font-display text-4xl md:text-5xl leading-tight">{serviceName}</h1>
154
- {service.tagLine && <p class="text-lg text-mute leading-relaxed max-w-prose">{service.tagLine}</p>}
155
- <div class="flex items-center gap-4 text-sm text-mute">
156
- <span>{duration} min</span>
157
- {price && <span class="text-ink font-medium">{price}</span>}
158
- </div>
159
- {service.description && <p class="text-ink leading-relaxed max-w-prose">{service.description}</p>}
160
- </div>
161
-
162
- <section class="border-t border-rule pt-12">
163
- <h2 class="font-display text-3xl leading-tight mb-8">Book this service</h2>
164
- <ServiceBookingFlow
165
- service={service}
166
- serviceName={serviceName}
167
- serviceType={service.type ?? "APPOINTMENT"}
168
- fields={formFields}
169
- staffMembers={staffMembers}
170
- locations={serviceLocations}
171
- locationId={locationId}
172
- client:only="react"
173
- />
174
- </section>
175
- </section>
176
- </Layout>