@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.
Files changed (250) 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 -244
  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/Footer.astro +0 -27
  157. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  158. package/skills/wix-headless/references/astro/templates/Navigation.astro +0 -38
  159. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  160. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  161. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  162. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  163. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  164. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  165. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  166. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  167. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  168. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  169. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  170. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  171. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  172. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  173. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  174. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  175. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  176. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  177. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  178. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  179. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  180. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  181. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  182. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  183. package/skills/wix-headless/references/astro/templates/index.astro +0 -56
  184. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  185. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  186. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  187. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  188. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  189. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  190. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  191. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  192. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  193. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  194. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  195. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  196. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  197. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  198. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  199. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  200. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  201. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  202. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  203. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  204. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  205. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  206. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  207. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  208. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  209. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  210. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  211. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  212. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  213. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  214. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  215. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  216. package/skills/wix-headless/references/seed-recipes.md +0 -49
  217. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  218. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  219. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  220. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  221. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  222. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  223. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  224. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  225. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  226. package/skills/wix-headless/references/shared/STYLING.md +0 -141
  227. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  228. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  229. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  230. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  231. package/skills/wix-headless/references/verticals/blog.md +0 -31
  232. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  233. package/skills/wix-headless/references/verticals/cms.md +0 -30
  234. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  235. package/skills/wix-headless/references/verticals/forms.md +0 -26
  236. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  237. package/skills/wix-headless/references/verticals/stores.md +0 -33
  238. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  239. package/skills/wix-headless/scripts/compose.mjs +0 -525
  240. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  241. package/skills/wix-headless/scripts/flatten.sh +0 -61
  242. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  243. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -148
  244. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  245. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  246. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  247. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  248. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  249. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  250. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -1,354 +0,0 @@
1
- # Recipe: Resource Library / Downloads
2
-
3
- Build a downloadable resource library using `@wix/data` — file listings with category filtering, file type badges, and detail pages with download buttons. Use for documents, guides, templates, whitepapers, or any downloadable assets.
4
-
5
- > Read `CMS_FOUNDATIONS.md` (this folder — service module, query patterns, image resolution, elevation) for page-rendering patterns, and `../../cms/CMS_FOUNDATIONS.md` for REST-based seeding.
6
-
7
- ## Collection Schema
8
-
9
- The schema the `seed` scope creates via REST (see `../../cms/CMS_FOUNDATIONS.md`) — fields:
10
-
11
- | Field | Type | Purpose |
12
- |-------|------|---------|
13
- | `title` | Text | Resource name |
14
- | `slug` | Text | URL-friendly identifier |
15
- | `description` | Rich Text | Resource description (HTML) |
16
- | `category` | Text | Resource category (e.g., "Guides", "Templates") |
17
- | `fileType` | Text | File extension — `PDF`, `DOC`, `ZIP`, `XLS`, etc. |
18
- | `fileUrl` | URL | Download URL (external link or Wix media URL) |
19
- | `fileSize` | Text | Human-readable file size (e.g., "2.4 MB") |
20
- | `coverImage` | Image | Thumbnail (`wix:image://` — resolve with `media.getScaledToFillImageUrl()`) |
21
- | `published` | Boolean | Publish status |
22
- | `_createdDate` | Date | Auto-populated creation date |
23
-
24
- ## Files to Create
25
-
26
- | File | Purpose |
27
- |------|---------|
28
- | `src/lib/resources.ts` | Service module — queries, category filtering, related resources |
29
- | `src/pages/resources/index.astro` | Listing with category filter + file type badges |
30
- | `src/pages/resources/[slug].astro` | Detail page with download button + related resources |
31
- | `src/components/ResourceCard.astro` | Card with file type icon, title, size |
32
- | `src/components/FileTypeIcon.astro` | SVG switch for PDF/DOC/ZIP/generic |
33
-
34
- ## Implementation
35
-
36
- ### 1. Resources Service Module (`src/lib/resources.ts`)
37
-
38
- ```typescript
39
- import { items } from "@wix/data";
40
- import { auth } from "@wix/essentials";
41
- import { media } from "@wix/sdk";
42
-
43
- const COLLECTION_ID = "Resources";
44
-
45
- export interface Resource {
46
- _id: string;
47
- title: string;
48
- slug: string;
49
- description?: string;
50
- category: string;
51
- fileType: string;
52
- fileUrl: string;
53
- fileSize?: string;
54
- coverImage?: string;
55
- published: boolean;
56
- _createdDate?: string;
57
- }
58
-
59
- function resolveImage(url: string | undefined): string | undefined {
60
- if (!url) return undefined;
61
- return media.getScaledToFillImageUrl(url, 600, 400, {});
62
- }
63
-
64
- function mapResource(item: Record<string, any>): Resource {
65
- return {
66
- _id: item._id,
67
- title: item.title ?? "",
68
- slug: item.slug ?? "",
69
- description: item.description,
70
- category: item.category ?? "",
71
- fileType: (item.fileType ?? "FILE").toUpperCase(),
72
- fileUrl: item.fileUrl ?? "",
73
- fileSize: item.fileSize,
74
- coverImage: resolveImage(item.coverImage),
75
- published: item.published ?? false,
76
- _createdDate: item._createdDate,
77
- };
78
- }
79
-
80
- export async function queryResources(): Promise<Resource[]> {
81
- const elevatedQuery = auth.elevate(items.query);
82
- const { items: results } = await elevatedQuery(COLLECTION_ID)
83
- .eq("published", true)
84
- .descending("_createdDate")
85
- .limit(50)
86
- .find();
87
-
88
- return results.map(mapResource);
89
- }
90
-
91
- export async function getResourceBySlug(slug: string): Promise<Resource | null> {
92
- const elevatedQuery = auth.elevate(items.query);
93
- const { items: results } = await elevatedQuery(COLLECTION_ID)
94
- .eq("slug", slug)
95
- .eq("published", true)
96
- .limit(1)
97
- .find();
98
-
99
- const item = results[0];
100
- if (!item) return null;
101
- return mapResource(item);
102
- }
103
-
104
- export async function queryRelatedResources(category: string, excludeId: string, limit = 3): Promise<Resource[]> {
105
- const elevatedQuery = auth.elevate(items.query);
106
- const { items: results } = await elevatedQuery(COLLECTION_ID)
107
- .eq("published", true)
108
- .eq("category", category)
109
- .ne("_id", excludeId)
110
- .descending("_createdDate")
111
- .limit(limit)
112
- .find();
113
-
114
- return results.map(mapResource);
115
- }
116
- ```
117
-
118
- Key details:
119
- - `queryRelatedResources()` finds same-category items excluding the current one
120
- - `fileType` normalized to uppercase for consistent badge display
121
- - Sorted by `_createdDate` descending (newest first)
122
- - Update `COLLECTION_ID` to match the exact collection name from the Wix dashboard (no namespace prefix for native collections)
123
-
124
- ### 2. File Type Icon (`src/components/FileTypeIcon.astro`)
125
-
126
- ```astro
127
- ---
128
- interface Props {
129
- type: string;
130
- class?: string;
131
- }
132
-
133
- const { type, class: className = "w-8 h-8" } = Astro.props;
134
- const fileType = type.toUpperCase();
135
-
136
- // File type colors are applied by the design skill's component styles
137
- ---
138
-
139
- <div class={className}>
140
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="w-full h-full">
141
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
142
- <polyline points="14 2 14 8 20 8" />
143
- <text x="12" y="17" text-anchor="middle" font-size="5" fill="currentColor" stroke="none" font-weight="bold">{fileType.slice(0, 4)}</text>
144
- </svg>
145
- </div>
146
- ```
147
-
148
- Key details:
149
- - The SVG uses `stroke="currentColor"` — any per-file-type coloring is purely CSS-driven (e.g. a `.file-type-pdf` class on the wrapper), not set here
150
- - File type label rendered inside the document icon SVG
151
-
152
- ### 3. Resource Card (`src/components/ResourceCard.astro`)
153
-
154
- ```astro
155
- ---
156
- import FileTypeIcon from "./FileTypeIcon.astro";
157
-
158
- interface Props {
159
- resource: {
160
- title: string;
161
- slug: string;
162
- category: string;
163
- fileType: string;
164
- fileSize?: string;
165
- coverImage?: string;
166
- };
167
- }
168
-
169
- const { resource } = Astro.props;
170
- ---
171
-
172
- <a href={`/resources/${resource.slug}`}>
173
- {resource.coverImage ? (
174
- <div><img src={resource.coverImage} alt={resource.title} /></div>
175
- ) : (
176
- <div><FileTypeIcon type={resource.fileType} /></div>
177
- )}
178
- <div>
179
- <div>
180
- <span>{resource.fileType}</span>
181
- {resource.fileSize && <span>{resource.fileSize}</span>}
182
- </div>
183
- <h3>{resource.title}</h3>
184
- <p>{resource.category}</p>
185
- </div>
186
- </a>
187
- ```
188
-
189
- > **Styling note:** ResourceCard styling is created by the design skill. See `references/shared/STYLING.md` (Resource Card).
190
-
191
- ### 4. Resource Listing Page (`src/pages/resources/index.astro`)
192
-
193
- ```astro
194
- ---
195
- import Layout from "../../layouts/Layout.astro";
196
- import ResourceCard from "../../components/ResourceCard.astro";
197
- import CategoryFilter from "../../components/CategoryFilter.astro";
198
- import { queryResources } from "../../lib/resources";
199
-
200
- const activeCategory = Astro.url.searchParams.get("category");
201
- const allResources = await queryResources();
202
- const filtered = activeCategory
203
- ? allResources.filter((r) => r.category === activeCategory)
204
- : allResources;
205
- const categories = [...new Set(allResources.map((r) => r.category).filter(Boolean))];
206
- ---
207
-
208
- <Layout title="Resources">
209
- <main>
210
- <div>
211
- <h1>Resources</h1>
212
- <p>Download guides, templates, and documents.</p>
213
-
214
- <CategoryFilter categories={categories} activeCategory={activeCategory} basePath="/resources" />
215
-
216
- <div>
217
- {filtered.map((resource) => (
218
- <ResourceCard resource={resource} />
219
- ))}
220
- </div>
221
-
222
- {filtered.length === 0 && (
223
- <p>No resources found.</p>
224
- )}
225
- </div>
226
- </main>
227
- </Layout>
228
- ```
229
-
230
- > Reuses the same `CategoryFilter.astro` component from the portfolio use case. If building both, no need to create it twice.
231
-
232
- ### 5. Resource Detail Page (`src/pages/resources/[slug].astro`)
233
-
234
- ```astro
235
- ---
236
- import Layout from "../../layouts/Layout.astro";
237
- import ResourceCard from "../../components/ResourceCard.astro";
238
- import FileTypeIcon from "../../components/FileTypeIcon.astro";
239
- import { getResourceBySlug, queryRelatedResources } from "../../lib/resources";
240
-
241
- const { slug } = Astro.params;
242
- const resource = await getResourceBySlug(slug!);
243
- if (!resource) return Astro.redirect("/404");
244
-
245
- const related = await queryRelatedResources(resource.category, resource._id);
246
-
247
- const date = resource._createdDate
248
- ? new Date(resource._createdDate).toLocaleDateString("en-US", {
249
- year: "numeric",
250
- month: "long",
251
- day: "numeric",
252
- })
253
- : "";
254
- ---
255
-
256
- <Layout title={resource.title}>
257
- <main>
258
- <div>
259
- <a href="/resources">
260
- &larr; Back to resources
261
- </a>
262
-
263
- <div>
264
- <FileTypeIcon type={resource.fileType} />
265
- <div>
266
- <div>
267
- <span>{resource.fileType}</span>
268
- {resource.fileSize && (
269
- <span>{resource.fileSize}</span>
270
- )}
271
- </div>
272
- {date && <p>Added {date}</p>}
273
- </div>
274
- </div>
275
-
276
- <h1>{resource.title}</h1>
277
-
278
- {resource.coverImage && (
279
- <div>
280
- <img
281
- src={resource.coverImage}
282
- alt={resource.title}
283
- />
284
- </div>
285
- )}
286
-
287
- {resource.description && (
288
- <article set:html={resource.description} />
289
- )}
290
-
291
- {resource.fileUrl && (
292
- <a
293
- href={resource.fileUrl}
294
- download
295
- >
296
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
297
- Download {resource.fileType}
298
- </a>
299
- )}
300
-
301
- {related.length > 0 && (
302
- <section>
303
- <h2>Related Resources</h2>
304
- <div>
305
- {related.map((r) => (
306
- <ResourceCard resource={r} />
307
- ))}
308
- </div>
309
- </section>
310
- )}
311
- </div>
312
- </main>
313
- </Layout>
314
- ```
315
-
316
- Key details:
317
- - `<a download>` triggers browser download for the file
318
- - Related resources query pulls same-category items, excluding the current one
319
- - File type icon and badge prominently displayed
320
-
321
- ## Seed with Images
322
-
323
- After seeding resources via REST, generate cover images following `../../shared/IMAGE_GENERATION.md` and `../../cms/CMS_FOUNDATIONS.md` → "Seeding with Images".
324
-
325
- **Prompt template:**
326
-
327
- ```
328
- Cover image for [TITLE], a [FILE TYPE]. Abstract [BRAND AESTHETIC]. Color tones: [BRAND COLORS]. No text, no watermarks
329
- ```
330
-
331
- **Patch field:** `coverImage`
332
-
333
- Example patch:
334
-
335
- ```
336
- REST: PATCH https://www.wixapis.com/wix-data/v2/items/{resourceId}
337
- body: {
338
- "dataCollectionId": "Resources",
339
- "dataItem": {
340
- "data": {
341
- "coverImage": "<wixstatic-url>"
342
- }
343
- }
344
- }
345
- ```
346
-
347
- ## Testing
348
-
349
- Assumes the `seed` scope has already created the "Resources" collection and inserted items via REST (see `../../cms/CMS_FOUNDATIONS.md`) — 4+ resources across 2+ categories with different file types (PDF, DOC, ZIP) and `fileUrl` links (any downloadable URL for testing).
350
-
351
- 1. Run `npx @wix/cli@latest dev`
352
- 2. `/resources` — shows all resources with category filters and file type badges
353
- 3. Click a category — filters resources
354
- 4. Click a resource — detail page with download button and related resources
@@ -1,299 +0,0 @@
1
- # Recipe: Team / Staff Directory
2
-
3
- Build a team directory using `@wix/data` — staff cards grouped by department with individual profile pages. Use for about us, our team, meet the staff, or any people directory.
4
-
5
- > Read `CMS_FOUNDATIONS.md` (this folder — service module, query patterns, image resolution, elevation) for page-rendering patterns, and `../../cms/CMS_FOUNDATIONS.md` for REST-based seeding.
6
-
7
- ## Collection Schema
8
-
9
- The schema the `seed` scope creates via REST (see `../../cms/CMS_FOUNDATIONS.md`) — fields:
10
-
11
- | Field | Type | Purpose |
12
- |-------|------|---------|
13
- | `name` | Text | Full name |
14
- | `slug` | Text | URL-friendly identifier |
15
- | `role` | Text | Job title or role |
16
- | `department` | Text | Department or team (e.g., "Engineering", "Design") |
17
- | `bio` | Rich Text | Bio or description (HTML) |
18
- | `photo` | Image | Headshot (`wix:image://` — resolve with `media.getScaledToFillImageUrl()`) |
19
- | `email` | Text | Contact email |
20
- | `linkedIn` | URL | LinkedIn profile URL |
21
- | `twitter` | URL | Twitter/X profile URL |
22
- | `orderIndex` | Number | Manual sort order within department |
23
-
24
- ## Files to Create
25
-
26
- | File | Purpose |
27
- |------|---------|
28
- | `src/lib/team.ts` | Service module — queries, department grouping |
29
- | `src/pages/team/index.astro` | Department-sectioned directory |
30
- | `src/pages/team/[slug].astro` | Individual member profile |
31
- | `src/components/TeamMemberCard.astro` | Photo, name, role, social icons |
32
-
33
- ## Implementation
34
-
35
- ### 1. Team Service Module (`src/lib/team.ts`)
36
-
37
- ```typescript
38
- import { items } from "@wix/data";
39
- import { auth } from "@wix/essentials";
40
- import { media } from "@wix/sdk";
41
-
42
- const COLLECTION_ID = "Team";
43
-
44
- export interface TeamMember {
45
- _id: string;
46
- name: string;
47
- slug: string;
48
- role: string;
49
- department: string;
50
- bio?: string;
51
- photo?: string;
52
- email?: string;
53
- linkedIn?: string;
54
- twitter?: string;
55
- orderIndex: number;
56
- }
57
-
58
- function resolvePhoto(url: string | undefined): string | undefined {
59
- if (!url) return undefined;
60
- return media.getScaledToFillImageUrl(url, 400, 400, {});
61
- }
62
-
63
- function mapMember(item: Record<string, any>): TeamMember {
64
- return {
65
- _id: item._id,
66
- name: item.name ?? "",
67
- slug: item.slug ?? "",
68
- role: item.role ?? "",
69
- department: item.department ?? "",
70
- bio: item.bio,
71
- photo: resolvePhoto(item.photo),
72
- email: item.email,
73
- linkedIn: item.linkedIn,
74
- twitter: item.twitter,
75
- orderIndex: item.orderIndex ?? 0,
76
- };
77
- }
78
-
79
- export async function queryTeamMembers(): Promise<TeamMember[]> {
80
- const elevatedQuery = auth.elevate(items.query);
81
- const { items: results } = await elevatedQuery(COLLECTION_ID)
82
- .ascending("orderIndex")
83
- .limit(100)
84
- .find();
85
-
86
- return results.map(mapMember);
87
- }
88
-
89
- export async function getMemberBySlug(slug: string): Promise<TeamMember | null> {
90
- const elevatedQuery = auth.elevate(items.query);
91
- const { items: results } = await elevatedQuery(COLLECTION_ID)
92
- .eq("slug", slug)
93
- .limit(1)
94
- .find();
95
-
96
- const item = results[0];
97
- if (!item) return null;
98
- return mapMember(item);
99
- }
100
-
101
- export function groupByDepartment(members: TeamMember[]): Map<string, TeamMember[]> {
102
- return members.reduce((map, member) => {
103
- const dept = member.department || "Team";
104
- if (!map.has(dept)) map.set(dept, []);
105
- map.get(dept)!.push(member);
106
- return map;
107
- }, new Map<string, TeamMember[]>());
108
- }
109
- ```
110
-
111
- Key details:
112
- - `resolvePhoto()` uses 400x400 for square headshot crops
113
- - `groupByDepartment()` returns a `Map` preserving insertion order — departments appear in the order of their first member
114
- - Update `COLLECTION_ID` to match the exact collection name from the Wix dashboard (no namespace prefix for native collections)
115
-
116
- ### 2. Team Member Card (`src/components/TeamMemberCard.astro`)
117
-
118
- ```astro
119
- ---
120
- interface Props {
121
- member: {
122
- name: string;
123
- slug: string;
124
- role: string;
125
- photo?: string;
126
- email?: string;
127
- linkedIn?: string;
128
- twitter?: string;
129
- };
130
- }
131
-
132
- const { member } = Astro.props;
133
- ---
134
-
135
- <a href={`/team/${member.slug}`}>
136
- <div>
137
- {member.photo ? (
138
- <img src={member.photo} alt={member.name} />
139
- ) : (
140
- <div>{member.name.charAt(0)}</div>
141
- )}
142
- </div>
143
- <h3>{member.name}</h3>
144
- <p>{member.role}</p>
145
- <div>
146
- {member.email && (
147
- <a href={`mailto:${member.email}`} onclick="event.stopPropagation()">Email</a>
148
- )}
149
- {member.linkedIn && (
150
- <a href={member.linkedIn} target="_blank" rel="noopener noreferrer" onclick="event.stopPropagation()">LinkedIn</a>
151
- )}
152
- {member.twitter && (
153
- <a href={member.twitter} target="_blank" rel="noopener noreferrer" onclick="event.stopPropagation()">Twitter</a>
154
- )}
155
- </div>
156
- </a>
157
- ```
158
-
159
- > **Styling note:** TeamMemberCard styling is created by the design skill. See `references/shared/STYLING.md` (Team Member Card).
160
-
161
- Key details:
162
- - Inline SVG icons — no icon library dependency
163
- - Fallback initial letter when no photo
164
- - Social links use `onclick="event.stopPropagation()"` to prevent navigation to profile when clicking social icons
165
-
166
- ### 3. Team Directory Page (`src/pages/team/index.astro`)
167
-
168
- ```astro
169
- ---
170
- import Layout from "../../layouts/Layout.astro";
171
- import TeamMemberCard from "../../components/TeamMemberCard.astro";
172
- import { queryTeamMembers, groupByDepartment } from "../../lib/team";
173
-
174
- const members = await queryTeamMembers();
175
- const departments = groupByDepartment(members);
176
- ---
177
-
178
- <Layout title="Our Team">
179
- <main>
180
- <div>
181
- <h1>Our Team</h1>
182
-
183
- {[...departments.entries()].map(([dept, deptMembers]) => (
184
- <section>
185
- <h2>{dept}</h2>
186
- <div>
187
- {deptMembers.map((member) => (
188
- <TeamMemberCard member={member} />
189
- ))}
190
- </div>
191
- </section>
192
- ))}
193
-
194
- {members.length === 0 && (
195
- <p>No team members found.</p>
196
- )}
197
- </div>
198
- </main>
199
- </Layout>
200
- ```
201
-
202
- ### 4. Member Profile Page (`src/pages/team/[slug].astro`)
203
-
204
- ```astro
205
- ---
206
- import Layout from "../../layouts/Layout.astro";
207
- import { getMemberBySlug } from "../../lib/team";
208
-
209
- const { slug } = Astro.params;
210
- const member = await getMemberBySlug(slug!);
211
- if (!member) return Astro.redirect("/404");
212
- ---
213
-
214
- <Layout title={member.name}>
215
- <main>
216
- <div>
217
- <a href="/team">
218
- &larr; Back to team
219
- </a>
220
-
221
- <div>
222
- {member.photo && (
223
- <div>
224
- <img
225
- src={member.photo}
226
- alt={member.name}
227
- />
228
- </div>
229
- )}
230
- <div>
231
- <h1>{member.name}</h1>
232
- <p>{member.role}</p>
233
- {member.department && (
234
- <p>{member.department}</p>
235
- )}
236
- <div>
237
- {member.email && (
238
- <a href={`mailto:${member.email}`}>
239
- {member.email}
240
- </a>
241
- )}
242
- {member.linkedIn && (
243
- <a href={member.linkedIn} target="_blank" rel="noopener noreferrer">
244
- LinkedIn
245
- </a>
246
- )}
247
- {member.twitter && (
248
- <a href={member.twitter} target="_blank" rel="noopener noreferrer">
249
- Twitter
250
- </a>
251
- )}
252
- </div>
253
- </div>
254
- </div>
255
-
256
- {member.bio && (
257
- <article set:html={member.bio} />
258
- )}
259
- </div>
260
- </main>
261
- </Layout>
262
- ```
263
-
264
- ## Seed with Images
265
-
266
- > **Do not skip:** Team members without photos appear as initial-letter placeholders.
267
- > Always ask the user if they want to generate headshot images before moving on.
268
-
269
- After seeding team members via REST, generate headshot images following `../../shared/IMAGE_GENERATION.md` and `../../cms/CMS_FOUNDATIONS.md` → "Seeding with Images".
270
-
271
- **Prompt template:**
272
-
273
- ```
274
- Professional headshot portrait of [NAME], [ROLE] at [BUSINESS NAME]. [BRAND AESTHETIC]. Warm studio lighting, neutral background with [BRAND COLORS]. No text, no watermarks
275
- ```
276
-
277
- **Patch field:** `photo`
278
-
279
- Example: after generating and importing the image, patch the team member item:
280
-
281
- ```
282
- REST: PATCH https://www.wixapis.com/wix-data/v2/items/{memberId}
283
- body: {
284
- "dataCollectionId": "Team",
285
- "dataItem": {
286
- "data": {
287
- "photo": "<wixstatic-url>"
288
- }
289
- }
290
- }
291
- ```
292
-
293
- ## Testing
294
-
295
- Assumes the `seed` scope has already created the "Team" collection and inserted items via REST (see `../../cms/CMS_FOUNDATIONS.md`) — 4+ members across 2+ departments, with social links (and headshots after the image pass).
296
-
297
- 1. Run `npx @wix/cli@latest dev`
298
- 2. `/team` — shows members grouped by department
299
- 3. Click a member — profile page with photo, bio, and social links