@wix/agent-skills 1.20.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +71 -113
  3. package/skills/wix-app/references/APP_TOOLS.md +2 -1
  4. package/skills/wix-app/references/BACKEND_EVENT.md +3 -3
  5. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +41 -152
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +4 -4
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +11 -25
  8. package/skills/wix-app/references/DATA_COLLECTION.md +16 -219
  9. package/skills/wix-app/references/SDK_MODULE_MAP.md +44 -0
  10. package/skills/wix-app/references/SITE_PLUGIN.md +36 -190
  11. package/skills/wix-app/references/app-tools/TOOLS.md +3 -1
  12. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +21 -0
  13. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +182 -0
  14. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +97 -0
  15. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +184 -0
  16. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +203 -0
  17. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +44 -0
  18. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +17 -0
  19. package/skills/wix-app/references/dashboard-page/QUERY_AND_PAGING.md +182 -0
  20. package/skills/wix-app/references/dashboard-page/TABLE_STATE.md +133 -0
  21. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +10 -5
  22. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +4 -18
  23. package/skills/wix-app/references/data-collection/LIFECYCLE.md +68 -0
  24. package/skills/wix-app/references/data-collection/PERMISSIONS.md +47 -0
  25. package/skills/wix-app/references/data-collection/SCHEMA.md +181 -0
  26. package/skills/wix-app/references/data-collection/WIX_DATA.md +38 -66
  27. package/skills/wix-app/references/site-plugin/EXAMPLES.md +1 -1
  28. package/skills/wix-headless-fast/SKILL.md +144 -221
  29. package/skills/wix-headless-fast/cold-start/bootstrap.mjs +156 -0
  30. package/skills/wix-headless-fast/{entry/skill.md → cold-start/cold-start.md} +15 -15
  31. package/skills/wix-headless-fast/guides/existing-site.md +76 -0
  32. package/skills/wix-headless-fast/guides/reference-mode.md +97 -0
  33. package/skills/wix-headless-fast/install/AGENTS.md +35 -0
  34. package/skills/wix-headless-fast/install/agents-md.mjs +39 -0
  35. package/skills/wix-headless-fast/install/attach.mjs +161 -86
  36. package/skills/wix-headless-fast/install/deploy.mjs +21 -60
  37. package/skills/wix-headless-fast/install/lock.mjs +55 -0
  38. package/skills/wix-headless-fast/install/setup.mjs +259 -0
  39. package/skills/wix-headless-fast/install/templates.mjs +168 -0
  40. package/skills/wix-manage/references/ecommerce/pricing-promotions/ecom-pricing-create-coupon.md +10 -19
  41. package/skills/wix-manage/references/events/create-wix-event.md +5 -1
  42. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +27 -0
  43. package/skills/wix-manage/references/google-ads/manage-campaign-success-guide.md +83 -37
  44. package/skills/wix-headless-fast/install/fast-path.mjs +0 -181
  45. package/skills/wix-headless-fast/references/blog/INSTRUCTIONS.md +0 -301
  46. package/skills/wix-headless-fast/references/blog/app/components/blog/BlogFeedView.tsx +0 -136
  47. package/skills/wix-headless-fast/references/blog/app/components/blog/PostView.tsx +0 -112
  48. package/skills/wix-headless-fast/references/blog/app/components/blog/RichContent.tsx +0 -42
  49. package/skills/wix-headless-fast/references/blog/app/hooks/blog/useBlogFeed.ts +0 -31
  50. package/skills/wix-headless-fast/references/blog/app/hooks/blog/usePost.ts +0 -22
  51. package/skills/wix-headless-fast/references/blog/app/wix/blog/blog-feed-store.ts +0 -137
  52. package/skills/wix-headless-fast/references/blog/app/wix/blog/post-store.ts +0 -78
  53. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts-core.ts +0 -117
  54. package/skills/wix-headless-fast/references/blog/app/wix/blog/posts.ts +0 -52
  55. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy-core.ts +0 -47
  56. package/skills/wix-headless-fast/references/blog/app/wix/blog/taxonomy.ts +0 -58
  57. package/skills/wix-headless-fast/references/blog/app/wix/blog/types.ts +0 -62
  58. package/skills/wix-headless-fast/references/blog/app-astro/layouts/SiteLayout.astro +0 -40
  59. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog/[...slug].astro +0 -97
  60. package/skills/wix-headless-fast/references/blog/app-astro/pages/blog.astro +0 -24
  61. package/skills/wix-headless-fast/references/blog/lock/astro/package-lock.json +0 -16156
  62. package/skills/wix-headless-fast/references/blog/rest/posts.ts +0 -42
  63. package/skills/wix-headless-fast/references/blog/rest/taxonomy.ts +0 -62
  64. package/skills/wix-headless-fast/references/blog/seed/SEED.md +0 -81
  65. package/skills/wix-headless-fast/references/blog/seed/seed-blog.mjs +0 -287
  66. package/skills/wix-headless-fast/references/bookings/INSTRUCTIONS.md +0 -275
  67. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServiceBookingView.tsx +0 -144
  68. package/skills/wix-headless-fast/references/bookings/app/components/bookings/ServicesView.tsx +0 -119
  69. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useBookingFlow.ts +0 -32
  70. package/skills/wix-headless-fast/references/bookings/app/hooks/bookings/useServices.ts +0 -23
  71. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-core.ts +0 -218
  72. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking-flow-store.ts +0 -169
  73. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/booking.ts +0 -121
  74. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-core.ts +0 -92
  75. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services-store.ts +0 -90
  76. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/services.ts +0 -57
  77. package/skills/wix-headless-fast/references/bookings/app/wix/bookings/types.ts +0 -72
  78. package/skills/wix-headless-fast/references/bookings/app-astro/layouts/SiteLayout.astro +0 -40
  79. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services/[slug].astro +0 -76
  80. package/skills/wix-headless-fast/references/bookings/app-astro/pages/services.astro +0 -22
  81. package/skills/wix-headless-fast/references/bookings/lock/astro/package-lock.json +0 -11962
  82. package/skills/wix-headless-fast/references/bookings/rest/booking.ts +0 -113
  83. package/skills/wix-headless-fast/references/bookings/rest/services.ts +0 -55
  84. package/skills/wix-headless-fast/references/bookings/seed/SEED.md +0 -71
  85. package/skills/wix-headless-fast/references/bookings/seed/seed-bookings.mjs +0 -302
  86. package/skills/wix-headless-fast/references/cms/INSTRUCTIONS.md +0 -353
  87. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useCollection.ts +0 -50
  88. package/skills/wix-headless-fast/references/cms/app/hooks/cms/useItem.ts +0 -37
  89. package/skills/wix-headless-fast/references/cms/app/wix/cms/collection-store.ts +0 -158
  90. package/skills/wix-headless-fast/references/cms/app/wix/cms/item-store.ts +0 -93
  91. package/skills/wix-headless-fast/references/cms/app/wix/cms/items-core.ts +0 -177
  92. package/skills/wix-headless-fast/references/cms/app/wix/cms/items.ts +0 -123
  93. package/skills/wix-headless-fast/references/cms/app/wix/cms/types.ts +0 -75
  94. package/skills/wix-headless-fast/references/cms/app-astro/layouts/SiteLayout.astro +0 -41
  95. package/skills/wix-headless-fast/references/cms/lock/astro/package-lock.json +0 -11262
  96. package/skills/wix-headless-fast/references/cms/rest/items.ts +0 -125
  97. package/skills/wix-headless-fast/references/cms/seed/SEED.md +0 -112
  98. package/skills/wix-headless-fast/references/cms/seed/seed-cms.mjs +0 -324
  99. package/skills/wix-headless-fast/references/events/INSTRUCTIONS.md +0 -305
  100. package/skills/wix-headless-fast/references/events/app/components/events/EventConfirmationView.tsx +0 -66
  101. package/skills/wix-headless-fast/references/events/app/components/events/EventRegistrationView.tsx +0 -178
  102. package/skills/wix-headless-fast/references/events/app/components/events/EventsView.tsx +0 -118
  103. package/skills/wix-headless-fast/references/events/app/hooks/events/useEventRegistration.ts +0 -35
  104. package/skills/wix-headless-fast/references/events/app/hooks/events/useEvents.ts +0 -24
  105. package/skills/wix-headless-fast/references/events/app/wix/events/events-core.ts +0 -130
  106. package/skills/wix-headless-fast/references/events/app/wix/events/events-store.ts +0 -97
  107. package/skills/wix-headless-fast/references/events/app/wix/events/events.ts +0 -55
  108. package/skills/wix-headless-fast/references/events/app/wix/events/registration-core.ts +0 -113
  109. package/skills/wix-headless-fast/references/events/app/wix/events/registration-store.ts +0 -156
  110. package/skills/wix-headless-fast/references/events/app/wix/events/registration.ts +0 -97
  111. package/skills/wix-headless-fast/references/events/app/wix/events/types.ts +0 -61
  112. package/skills/wix-headless-fast/references/events/app-astro/layouts/SiteLayout.astro +0 -40
  113. package/skills/wix-headless-fast/references/events/app-astro/pages/event-confirmation.astro +0 -12
  114. package/skills/wix-headless-fast/references/events/app-astro/pages/events/[slug].astro +0 -80
  115. package/skills/wix-headless-fast/references/events/app-astro/pages/events.astro +0 -21
  116. package/skills/wix-headless-fast/references/events/lock/astro/package-lock.json +0 -11884
  117. package/skills/wix-headless-fast/references/events/rest/events.ts +0 -57
  118. package/skills/wix-headless-fast/references/events/rest/registration.ts +0 -83
  119. package/skills/wix-headless-fast/references/events/seed/SEED.md +0 -95
  120. package/skills/wix-headless-fast/references/events/seed/seed-events.mjs +0 -276
  121. package/skills/wix-headless-fast/references/forms/INSTRUCTIONS.md +0 -338
  122. package/skills/wix-headless-fast/references/forms/app/hooks/forms/useWixForm.ts +0 -85
  123. package/skills/wix-headless-fast/references/forms/app/wix/forms/form-store.ts +0 -332
  124. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms-core.ts +0 -238
  125. package/skills/wix-headless-fast/references/forms/app/wix/forms/forms.ts +0 -54
  126. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions-core.ts +0 -216
  127. package/skills/wix-headless-fast/references/forms/app/wix/forms/submissions.ts +0 -59
  128. package/skills/wix-headless-fast/references/forms/app/wix/forms/types.ts +0 -135
  129. package/skills/wix-headless-fast/references/forms/lock/astro/package-lock.json +0 -10593
  130. package/skills/wix-headless-fast/references/forms/rest/forms.ts +0 -34
  131. package/skills/wix-headless-fast/references/forms/rest/submissions.ts +0 -56
  132. package/skills/wix-headless-fast/references/forms/seed/SEED.md +0 -116
  133. package/skills/wix-headless-fast/references/forms/seed/seed-forms.mjs +0 -327
  134. package/skills/wix-headless-fast/references/members/INSTRUCTIONS.md +0 -314
  135. package/skills/wix-headless-fast/references/members/app/components/members/AccountView.tsx +0 -60
  136. package/skills/wix-headless-fast/references/members/app/components/members/LoginForm.tsx +0 -155
  137. package/skills/wix-headless-fast/references/members/app/components/members/MemberMenu.tsx +0 -78
  138. package/skills/wix-headless-fast/references/members/app/components/members/RequireAuth.tsx +0 -47
  139. package/skills/wix-headless-fast/references/members/app/hooks/members/useMember.ts +0 -66
  140. package/skills/wix-headless-fast/references/members/app/wix/members/auth-core.ts +0 -105
  141. package/skills/wix-headless-fast/references/members/app/wix/members/auth.ts +0 -59
  142. package/skills/wix-headless-fast/references/members/app/wix/members/client.ts +0 -53
  143. package/skills/wix-headless-fast/references/members/app/wix/members/member-store.ts +0 -122
  144. package/skills/wix-headless-fast/references/members/app/wix/members/members-core.ts +0 -43
  145. package/skills/wix-headless-fast/references/members/app/wix/members/members.ts +0 -29
  146. package/skills/wix-headless-fast/references/members/app/wix/members/types.ts +0 -21
  147. package/skills/wix-headless-fast/references/members/app-astro/layouts/SiteLayout.astro +0 -42
  148. package/skills/wix-headless-fast/references/members/app-astro/pages/account.astro +0 -10
  149. package/skills/wix-headless-fast/references/members/app-astro/pages/login.astro +0 -11
  150. package/skills/wix-headless-fast/references/members/lock/astro/package-lock.json +0 -10329
  151. package/skills/wix-headless-fast/references/members/rest/auth.ts +0 -215
  152. package/skills/wix-headless-fast/references/members/rest/members.ts +0 -26
  153. package/skills/wix-headless-fast/references/members/seed/SEED.md +0 -39
  154. package/skills/wix-headless-fast/references/members/seed/seed-members.mjs +0 -94
  155. package/skills/wix-headless-fast/references/portfolio/INSTRUCTIONS.md +0 -313
  156. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionProjectsView.tsx +0 -110
  157. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/CollectionsView.tsx +0 -90
  158. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/GalleryMedia.tsx +0 -35
  159. package/skills/wix-headless-fast/references/portfolio/app/components/portfolio/ProjectDetailView.tsx +0 -85
  160. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollectionProjects.ts +0 -32
  161. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useCollections.ts +0 -21
  162. package/skills/wix-headless-fast/references/portfolio/app/hooks/portfolio/useProjectDetail.ts +0 -31
  163. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collection-projects-store.ts +0 -82
  164. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/collections-store.ts +0 -58
  165. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio-core.ts +0 -177
  166. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/portfolio.ts +0 -78
  167. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/project-detail-store.ts +0 -81
  168. package/skills/wix-headless-fast/references/portfolio/app/wix/portfolio/types.ts +0 -55
  169. package/skills/wix-headless-fast/references/portfolio/app-astro/layouts/SiteLayout.astro +0 -40
  170. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio/[slug].astro +0 -30
  171. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/portfolio.astro +0 -21
  172. package/skills/wix-headless-fast/references/portfolio/app-astro/pages/projects/[slug].astro +0 -29
  173. package/skills/wix-headless-fast/references/portfolio/lock/astro/package-lock.json +0 -10197
  174. package/skills/wix-headless-fast/references/portfolio/rest/portfolio.ts +0 -75
  175. package/skills/wix-headless-fast/references/portfolio/seed/SEED.md +0 -86
  176. package/skills/wix-headless-fast/references/portfolio/seed/seed-portfolio.mjs +0 -258
  177. package/skills/wix-headless-fast/references/pricing-plans/INSTRUCTIONS.md +0 -294
  178. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlanDetailView.tsx +0 -47
  179. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/PlansView.tsx +0 -101
  180. package/skills/wix-headless-fast/references/pricing-plans/app/components/pricing-plans/SubscribeButton.tsx +0 -41
  181. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlanPurchase.ts +0 -16
  182. package/skills/wix-headless-fast/references/pricing-plans/app/hooks/pricing-plans/usePlans.ts +0 -22
  183. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plan-purchase-store.ts +0 -54
  184. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-core.ts +0 -106
  185. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans-store.ts +0 -64
  186. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/plans.ts +0 -27
  187. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase-core.ts +0 -43
  188. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/purchase.ts +0 -22
  189. package/skills/wix-headless-fast/references/pricing-plans/app/wix/pricing-plans/types.ts +0 -30
  190. package/skills/wix-headless-fast/references/pricing-plans/app-astro/layouts/SiteLayout.astro +0 -41
  191. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans/[slug].astro +0 -40
  192. package/skills/wix-headless-fast/references/pricing-plans/app-astro/pages/plans.astro +0 -21
  193. package/skills/wix-headless-fast/references/pricing-plans/lock/astro/package-lock.json +0 -11226
  194. package/skills/wix-headless-fast/references/pricing-plans/rest/plans.ts +0 -31
  195. package/skills/wix-headless-fast/references/pricing-plans/rest/purchase.ts +0 -20
  196. package/skills/wix-headless-fast/references/pricing-plans/seed/SEED.md +0 -79
  197. package/skills/wix-headless-fast/references/pricing-plans/seed/seed-pricing-plans.mjs +0 -279
  198. package/skills/wix-headless-fast/references/restaurants/INSTRUCTIONS.md +0 -358
  199. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/MenuView.tsx +0 -142
  200. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartButton.tsx +0 -26
  201. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/OrderCartDrawer.tsx +0 -121
  202. package/skills/wix-headless-fast/references/restaurants/app/components/restaurants/ReservationView.tsx +0 -155
  203. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useMenus.ts +0 -34
  204. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useOrderCart.ts +0 -43
  205. package/skills/wix-headless-fast/references/restaurants/app/hooks/restaurants/useReservation.ts +0 -34
  206. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-core.ts +0 -155
  207. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu-store.ts +0 -89
  208. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/menu.ts +0 -71
  209. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/order-store.ts +0 -103
  210. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering-core.ts +0 -124
  211. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/ordering.ts +0 -185
  212. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservation-store.ts +0 -193
  213. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations-core.ts +0 -94
  214. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/reservations.ts +0 -74
  215. package/skills/wix-headless-fast/references/restaurants/app/wix/restaurants/types.ts +0 -168
  216. package/skills/wix-headless-fast/references/restaurants/app-astro/layouts/SiteLayout.astro +0 -47
  217. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/menu.astro +0 -22
  218. package/skills/wix-headless-fast/references/restaurants/app-astro/pages/reservations.astro +0 -12
  219. package/skills/wix-headless-fast/references/restaurants/lock/astro/package-lock.json +0 -12560
  220. package/skills/wix-headless-fast/references/restaurants/rest/menu.ts +0 -60
  221. package/skills/wix-headless-fast/references/restaurants/rest/ordering.ts +0 -169
  222. package/skills/wix-headless-fast/references/restaurants/rest/reservations.ts +0 -68
  223. package/skills/wix-headless-fast/references/restaurants/seed/SEED.md +0 -89
  224. package/skills/wix-headless-fast/references/restaurants/seed/seed-restaurants.mjs +0 -479
  225. package/skills/wix-headless-fast/references/shared/CONTENT.md +0 -22
  226. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +0 -73
  227. package/skills/wix-headless-fast/references/shared/DESIGN.md +0 -26
  228. package/skills/wix-headless-fast/references/shared/SUPPLIED-CONTENT.md +0 -23
  229. package/skills/wix-headless-fast/references/shared/app/styles/global.css +0 -52
  230. package/skills/wix-headless-fast/references/shared/app/wix/config.ts +0 -15
  231. package/skills/wix-headless-fast/references/shared/app/wix/media.ts +0 -81
  232. package/skills/wix-headless-fast/references/shared/app/wix/money.ts +0 -24
  233. package/skills/wix-headless-fast/references/shared/app/wix/sdk.ts +0 -89
  234. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app/wix/media-upload/client.ts +0 -46
  235. package/skills/wix-headless-fast/references/shared/capabilities/media-upload/app-astro/pages/api/wix/media-upload.ts +0 -46
  236. package/skills/wix-headless-fast/references/shared/rest/client.ts +0 -155
  237. package/skills/wix-headless-fast/references/shared/rest/config.ts +0 -3
  238. package/skills/wix-headless-fast/references/shared/rest/media.ts +0 -65
  239. package/skills/wix-headless-fast/references/shared/seed/images.mjs +0 -145
  240. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +0 -608
  241. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartButton.tsx +0 -26
  242. package/skills/wix-headless-fast/references/storefront/app/components/storefront/CartDrawer.tsx +0 -155
  243. package/skills/wix-headless-fast/references/storefront/app/components/storefront/FilterPanel.tsx +0 -266
  244. package/skills/wix-headless-fast/references/storefront/app/components/storefront/OptionPicker.tsx +0 -95
  245. package/skills/wix-headless-fast/references/storefront/app/components/storefront/QuickAdd.tsx +0 -136
  246. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useCart.ts +0 -48
  247. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useProductDetail.ts +0 -39
  248. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +0 -34
  249. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-core.ts +0 -121
  250. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +0 -107
  251. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart.ts +0 -138
  252. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog-core.ts +0 -309
  253. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +0 -133
  254. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/product-detail-store.ts +0 -147
  255. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/shop-store.ts +0 -289
  256. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/types.ts +0 -167
  257. package/skills/wix-headless-fast/references/storefront/app-astro/layouts/SiteLayout.astro +0 -65
  258. package/skills/wix-headless-fast/references/storefront/lock/astro/package-lock.json +0 -12247
  259. package/skills/wix-headless-fast/references/storefront/rest/cart.ts +0 -132
  260. package/skills/wix-headless-fast/references/storefront/rest/catalog.ts +0 -123
  261. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +0 -124
  262. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +0 -525
@@ -1,313 +0,0 @@
1
- # Portfolio — playbook
2
-
3
- The portfolio machinery ships as files — collections, projects, the per-project media gallery
4
- (image AND video items), the state machines behind every surface, typed end-to-end. Portfolio is
5
- **read-only**: no cart, no checkout, no `@wix/ecom`. **The presentation is yours**: you design and
6
- implement the collection card, the project card + grid, the project-detail gallery, and the home
7
- page on the shipped hooks/DTOs, plus the brand. You never write read logic; you never skip designing.
8
-
9
- ## The file map (deployed into `src/`)
10
-
11
- **On Astro and React the shipped files are tested and work as they are** — this table and the
12
- contracts below are everything you need to use them, so don't spend the run reading their source;
13
- wire them and build your surfaces. Reading them is the right move when something is off (a runtime
14
- error, a field this playbook doesn't cover) or when the brief wants a behaviour they don't offer —
15
- then read the file that owns it and change or extend it. On `lib`, `static`, and a port the
16
- components don't deploy at all, and each wiring section below opens with the files to read before
17
- writing their equivalents. Files you edit: `SiteLayout.astro`, `styles/global.css`, and the three
18
- pages' island imports. Files you **create**: your gallery, collection, and project-detail islands
19
- (skeletons below), plus your home page.
20
-
21
- | file | what it is |
22
- |---|---|
23
- | `wix/config.ts` · `wix/sdk.ts` | shared auth seam (deploy configures it — nothing to set by hand) |
24
- | `wix/media.ts` · `wix/money.ts` | `imgAttrs(url, sizes, ratio?)` — every `<img>` attribute for a DTO image (`src`, `srcSet`, `sizes`, lazy): `<img {...imgAttrs(c.imageUrl, "33vw", 0.75)} alt={c.title} />`; `imgSrc()` / `imgSrcSet()` underneath, already used by everything shipped |
25
- | `wix/portfolio/types.ts` | the DTOs (`CollectionSummary`, `ProjectSummary`, `ProjectDetail`, `ProjectDetailRow`, `GalleryItem`) — contracts inlined below |
26
- | `wix/portfolio/portfolio.ts` | `fetchCollections`, `fetchCollectionBySlug`, `fetchProjects`, `fetchProjectBySlug`, `fetchProjectGallery` — the transport; the rules and DTO mappers (hidden filter, dashboard order, cover fallback, media kinds, `mediaElement`) are in `portfolio-core.ts` beside it (shared with the REST layer) |
27
- | `wix/portfolio/collections-store.ts` · `collection-projects-store.ts` · `project-detail-store.ts` | the gallery, collection-page, and project-page state machines, framework-free (`createCollectionsStore()`, `createCollectionProjectsStore(slug)`, `createProjectDetailStore(slug)` — `getState`/`subscribe`/`start`/`stop`, one instance per surface); the hooks below bind them to React, every other stack uses them directly |
28
- | `hooks/portfolio/useCollections.ts` | React binding of `collections-store.ts` — contract below |
29
- | `hooks/portfolio/useCollectionProjects.ts` | React binding of `collection-projects-store.ts`: one collection + its projects, by slug — contract below |
30
- | `hooks/portfolio/useProjectDetail.ts` | React binding of `project-detail-store.ts`: one project + its media gallery, by slug — contract below |
31
- | `components/portfolio/GalleryMedia.tsx` | one gallery item as its one element — `<video>` with poster for a video item, `<img>` for an image item, nothing for an unrenderable one; `GalleryLink` wraps it in the owner's link when set — **wire as-is** in your project surface (`<GalleryLink item={i}><GalleryMedia item={i} /></GalleryLink>`) |
32
- | `components/portfolio/CollectionsView.tsx` (+ `CollectionCard`) · `CollectionProjectsView.tsx` (+ `ProjectCard`) · `ProjectDetailView.tsx` | **REFERENCE implementations** — correct, plain; build your own instead of shipping them |
33
- | `styles/global.css` | **the design system**: Tailwind v4 + the `@theme` token block (colors, radii, fonts). Everything, shipped and yours, styles from these tokens |
34
-
35
- Astro stack additionally gets:
36
-
37
- | file | what it is |
38
- |---|---|
39
- | `layouts/SiteLayout.astro` | the site chrome — **yours to brand**: header, footer, nav. Keep the `<slot name="seo-tags" />` and the global.css import. If another vertical is also deployed, its layout won — add a Portfolio nav link there |
40
- | `pages/portfolio.astro` | SSR collections gallery — **keep the frontmatter**, swap the island import to YOUR component |
41
- | `pages/portfolio/[slug].astro` | SSR collection page (header + projects) — **keep the frontmatter**, swap the island import |
42
- | `pages/projects/[slug].astro` | SSR project detail + gallery — **keep the frontmatter**, swap the island import. Portfolio has no Wix SEO item type, so these pages carry plain `<title>`/`<meta>` from the DTO (no `wixMetadata`/`<SEO.Tags>`) |
43
-
44
- ## What you build — the design job
45
-
46
- 1. **The collection card + gallery surface** — your tile (cover, title, description) and rhythm,
47
- with skeletons while loading and an honest empty state — on `useCollections`.
48
- 2. **The project card + collection page** — the collection header and your project grid — on
49
- `useCollectionProjects` (route a not-found state off `notFound`, never off a transient null).
50
- 3. **The project-detail surface** — title/description, the `details` rows (text or link, as
51
- given), and the media gallery through the shipped `GalleryMedia`; empty gallery → the project
52
- cover when it exists, else an honest empty note — on `useProjectDetail`.
53
- 4. **The home page** — hero, featured collections or projects (fetch in frontmatter → your
54
- components), brand story.
55
-
56
- Plus the **theme** (`@theme` block, one edit) and the **chrome** (`SiteLayout`, one pass).
57
-
58
- ### What a complete portfolio shows (recommended defaults)
59
-
60
- Defaults for a brief that says nothing about them; the prompt wins where it differs. Look at the
61
- content before designing (how many collections, covers, project count, media mix) and design for
62
- this portfolio, not for a stereotype of its field. Then, by default:
63
-
64
- - **Home:** what the work is and one path into it in the first screen; real collections or
65
- projects under truthful headings; a collection tile links to `/portfolio/<slug>` and shows that
66
- collection's own cover.
67
- - **Gallery (`/portfolio`):** a real collection card — cover, title — in the first screen;
68
- loading, empty, and error states that look different.
69
- - **Collection page:** the collection's title and description as the header, then only its
70
- projects; a slug that resolves to nothing shows the not-found state alone — no header or empty
71
- grid around it.
72
- - **Project page:** title, description, and the `details` rows before the gallery; gallery items
73
- in dashboard order, each through `GalleryMedia`, captions from `item.title` when present; on a
74
- phone a gallery image is a bounded band, not a full-height hero.
75
- - **Images:** every DTO image through `imgAttrs` (a `src`, a `srcSet`, and `sizes` in one spread;
76
- an empty `imageUrl` gives `{}` — render your placeholder then).
77
- - **Copy:** nothing the owner didn't supply — no invented clients, awards, or dates; no Wix IDs or
78
- technical words in visible text.
79
-
80
- ### The contracts your components consume (tested and work as they are; read when something is off or the brief wants more)
81
-
82
- ```ts
83
- // CollectionSummary (tiles): { id, slug, title, description, imageUrl /* "" when none */ }
84
- // ProjectSummary (tiles): { id, slug, title, description, imageUrl /* cover or video poster */,
85
- // collectionIds: string[] }
86
- // ProjectDetail adds: details: [{ label, text, url|null, target|null /* url set → link row */ }]
87
- // GalleryItem: { id, kind: "image"|"video", title, description,
88
- // imageUrl /* image, or the video's poster; may be "" */,
89
- // videoUrl /* video only, else null */, linkUrl|null, linkTarget|null }
90
-
91
- // useCollections({ initialCollections? }) →
92
- // { collections: CollectionSummary[]|null /* null = loading → skeletons */, error }
93
-
94
- // useCollectionProjects(slug, { initialCollection?, initialProjects? }) →
95
- // { collection: CollectionSummary|null, // null while loading AND when notFound
96
- // notFound, // the real 404 signal
97
- // projects: ProjectSummary[]|null, // null = loading → skeletons
98
- // error }
99
-
100
- // useProjectDetail(slug, { initialProject?, initialItems? }) →
101
- // { project: ProjectDetail|null, notFound,
102
- // items: GalleryItem[]|null, // dashboard order; null = loading
103
- // error }
104
-
105
- // <GalleryMedia item={i} className? /> renders i as ONE element by kind (video+poster / img /
106
- // nothing); <GalleryLink item={i}>…</GalleryLink> wraps in the owner's link when linkUrl is set.
107
- ```
108
-
109
- ### The pages and islands you create — skeletons
110
-
111
- The class names here are the Astro/React spelling of layout rules that hold on every stack; on a
112
- stack where the components don't deploy (`lib`, `static`, a port), keep the rule and write it in
113
- your own CSS. The three pages ship with their frontmatter (fetch → DTO props → island, guarded
114
- against an SSR throw, a real 404 on a missing slug) — keep it, and point the island import at
115
- yours. Hooks first, branches after (an early return above a hook changes hook order between
116
- renders and React throws). Render every state totally; nothing in a render path may throw.
117
-
118
- ```tsx
119
- // src/components/portfolio/Gallery.tsx — YOU build it; pages/portfolio.astro mounts it.
120
- import { useCollections } from "../../hooks/portfolio/useCollections";
121
- import { imgAttrs } from "../../wix/media";
122
- import type { CollectionSummary } from "../../wix/portfolio/types";
123
-
124
- export default function Gallery(props: { initialCollections?: CollectionSummary[] }) {
125
- const { collections, error } = useCollections(props);
126
- // …you implement the render:
127
- // • error → a short inline message
128
- // • collections === null → skeleton tiles; [] → your honest empty state
129
- // • else YOUR grid of YOUR tiles: <a href={`/portfolio/${c.slug}`}> around the cover
130
- // (<img {...imgAttrs(c.imageUrl, "(min-width: 1024px) 33vw, 50vw", 0.75)} alt={c.title} />,
131
- // your placeholder when imageUrl is ""), title, description; the title WRAPS (`min-w-0`,
132
- // `break-words`), never `truncate`
133
- }
134
- ```
135
-
136
- ```tsx
137
- // src/components/portfolio/CollectionPage.tsx — YOU build it; pages/portfolio/[slug].astro mounts it.
138
- import { useCollectionProjects } from "../../hooks/portfolio/useCollectionProjects";
139
- import type { CollectionSummary, ProjectSummary } from "../../wix/portfolio/types";
140
-
141
- export default function CollectionPage(props: { slug: string; initialCollection?: CollectionSummary; initialProjects?: ProjectSummary[] }) {
142
- const { collection, notFound, projects, error } = useCollectionProjects(props.slug, props);
143
- // …you implement the render. Handle in order:
144
- // notFound → the not-found state ALONE (no header, no empty grid around it)
145
- // header: collection.title and description (a skeleton line while collection is null)
146
- // error → inline message; projects === null → skeleton tiles; [] → your empty state
147
- // else YOUR grid of YOUR project tiles linking to `/projects/${p.slug}` (cover via imgAttrs)
148
- }
149
- ```
150
-
151
- ```tsx
152
- // src/components/portfolio/ProjectPage.tsx — YOU build it; pages/projects/[slug].astro mounts it.
153
- import { useProjectDetail } from "../../hooks/portfolio/useProjectDetail";
154
- import { GalleryLink, GalleryMedia } from "./GalleryMedia";
155
- import { imgAttrs } from "../../wix/media";
156
- import type { GalleryItem, ProjectDetail } from "../../wix/portfolio/types";
157
-
158
- export default function ProjectPage(props: { slug: string; initialProject?: ProjectDetail; initialItems?: GalleryItem[] }) {
159
- const { project, notFound, items, error } = useProjectDetail(props.slug, props);
160
- // …you implement the render. Handle in order:
161
- // notFound → "doesn't exist (anymore)"; !project → a loading placeholder
162
- // else: title, description, then project.details as a definition list — a row with url is a
163
- // link (target as given), else plain text; never invent a row
164
- // items === null → a skeleton; [] → the cover (imgAttrs) when project.imageUrl, else an honest
165
- // empty note; else each item as
166
- // <figure><GalleryLink item={i}><GalleryMedia item={i} className="…" /></GalleryLink>
167
- // {i.title && <figcaption>{i.title}</figcaption>}</figure> — never your own <img>/<video>
168
- // branch (the shipped one owns kind, poster, and the unrenderable case)
169
- // on a phone the media column is a bounded band (`max-h-[70vh]`, `object-contain`)
170
- }
171
- ```
172
-
173
- ### The reference files for stacks where the components don't deploy
174
-
175
- On `lib`, `static`, and a port, nothing under `components/` or `hooks/` arrives. The state machines
176
- behind the hooks do arrive — `wix/portfolio/collections-store.ts`, `collection-projects-store.ts`,
177
- `project-detail-store.ts` — so you never rewrite them: create a store per surface, `subscribe`,
178
- render from `getState()`. Their `*State` interfaces are the render contract; read those. The one
179
- rendering rule worth reading before writing your gallery:
180
-
181
- 1. `components/portfolio/GalleryMedia.tsx` — the kind branch as working code, and the rule it
182
- renders, `mediaElement(item)` in `wix/portfolio/portfolio-core.ts`, which ships on every stack:
183
- it returns `{ tag: "video", attrs }`, `{ tag: "img", attrs }`, or null — create the element
184
- from it (`document.createElement(el.tag)` + `setAttribute` per entry) instead of branching on
185
- `kind` yourself.
186
-
187
- All under `references/portfolio/app/`.
188
-
189
- ### Wiring — Astro (default)
190
-
191
- 1. Set the `@theme` tokens (one edit); brand `SiteLayout.astro` (one pass — merge into the
192
- existing layout instead if another vertical is deployed).
193
- 2. Write your islands under `src/components/portfolio/` (new names — don't overwrite the
194
- references) per the skeletons above; swap the island imports in `pages/portfolio.astro`,
195
- `pages/portfolio/[slug].astro`, and `pages/projects/[slug].astro`. Islands are `client:load`
196
- with the SSR props. Author your surfaces in as few messages as possible — batch multiple Writes
197
- per message.
198
- 3. Write `pages/index.astro` (home) — it exists from the scaffold; Read it before overwriting.
199
-
200
- ### Wiring — another JS framework (`--stack lib`: Vue, Svelte, Solid, plain Vite)
201
-
202
- Read the reference files listed above before writing any surface.
203
-
204
- `deploy.mjs portfolio --stack lib` put the data layer in `src/wix/` and nothing else: `sdk.ts`
205
- (the visitor client, configured with the public client id), `media.ts`, `money.ts`, and
206
- `wix/portfolio/` — `portfolio.ts`, `types.ts`, the `portfolio-core.ts` rules, and the three stores.
207
- None of it is React. The hooks and components don't ship on this stack; the stores replace the
208
- hooks, and you write the components in your framework to the contracts on this page:
209
-
210
- - bind the stores with your framework's external-store primitive (Vue: `shallowRef` updated in
211
- `subscribe`; Svelte: `readable(store.getState(), (set) => store.subscribe(() => set(store.getState())))`;
212
- Solid: a signal set in `subscribe`). `createCollectionsStore(options)` per gallery,
213
- `createCollectionProjectsStore(slug, options)` per collection page,
214
- `createProjectDetailStore(slug, options)` per project page — `start()` when mounted, `stop()`
215
- when unmounted. State in, exactly the hooks' contracts above;
216
- - gallery items through `mediaElement(item)` from `portfolio-core.ts`; images through
217
- `imgAttrs` from `media.ts`.
218
-
219
- Routes `/portfolio`, `/portfolio/:slug` (`fetchCollectionBySlug`, null → your 404),
220
- `/projects/:slug` (`fetchProjectBySlug`, null → your 404); dev server on 4321; a static build goes
221
- through `npx @wix/cli@latest release` with `site.outputDirectory` pointing at the build folder, an
222
- SSR build is hosted by you. Page titles and descriptions from the DTO (Portfolio has no SEO item type).
223
-
224
- ### Wiring — static site (`--stack static`, no bundler)
225
-
226
- Read the reference files listed above before writing any surface.
227
-
228
- `deploy.mjs portfolio --stack static --out site` put the REST layer in `site/js/wix/` (browser ESM,
229
- the `.ts` beside each `.js` for reading). Everything the visitor loads lives under `site/` — pages,
230
- styles, `js/` — and `wix.config.json`'s `site.outputDirectory` is `"./site"`; the project root
231
- (config, plan, seed output) is never the upload. Same function names and DTOs as the table above,
232
- so the contracts on this page hold unchanged: `fetchCollections`, `fetchCollectionBySlug`,
233
- `fetchProjects`, `fetchProjectBySlug`, `fetchProjectGallery` from `./js/wix/portfolio.js`. The
234
- state machines ship too: `createCollectionsStore` from `./js/wix/collections-store.js`,
235
- `createCollectionProjectsStore` from `./js/wix/collection-projects-store.js`,
236
- `createProjectDetailStore` from `./js/wix/project-detail-store.js` (`start()` once the page is up;
237
- `notFound` is the 404 signal), `mediaElement` from `./js/wix/portfolio-core.js` (the gallery item
238
- → element rule), and `imgAttrs` from `./js/wix/media.js` (attribute names as HTML spells them —
239
- `setAttribute` per entry). No components ship — you write the rendering in plain JS: one render
240
- function per surface that reads `getState()`, called from `subscribe`. Wix static hosting serves
241
- files, not directories: pages are `portfolio.html`, `collection.html?slug=…`,
242
- `project.html?slug=…`; name the file and link to it. Set `document.title` and the meta description
243
- from the DTO (`collection.title`/`description`, `project.title`/`description`) once the store
244
- populates — Portfolio has no `seoData`. The visitor token persists in `localStorage` on its own;
245
- never mint per page. `npx @wix/cli@latest release` uploads `site/`.
246
-
247
- ### Wiring — server-rendered, another language (Flask, Laravel, Rails, …)
248
-
249
- Read the reference files listed above before writing any surface.
250
-
251
- Run `deploy.mjs portfolio --stack static` in the project folder anyway: `js/wix/` is the readable
252
- spec. This vertical is reads only, so everything renders on the server: port `js/wix/portfolio.ts`
253
- and `portfolio-core.ts` to your language — the same five functions returning the same DTO shapes
254
- as dicts, one anonymous visitor token per process (mint and refresh per `client.ts`) — and render
255
- gallery, collection, and project pages in your templates to the contracts above, so titles are in
256
- the HTML; `<title>`/`<meta>` from the DTO. Carry the URLs and bodies over as they are (the list
257
- calls are `GET` with `paging.limit`; the slug lookups `POST …/query` with
258
- `{ query: { filter: { slug }, cursorPaging: { limit: 1 } } }`). The gallery's kind rule is
259
- `mediaElement` — port it, don't re-derive it. Nothing here runs in the browser unless you want
260
- client-side loading; then the static wiring above applies. Routes stay `/portfolio`,
261
- `/portfolio/<slug>`, `/projects/<slug>`.
262
-
263
- **Pre-rendered (Frozen-Flask, Pelican, any static-site generator) → Wix-hosted.** Same port for
264
- the reads, run at build time with one anonymous token; the generator must emit a page for every
265
- collection (`fetchCollections()`) and every project (`fetchProjects()`) — both return one page of
266
- up to 100 in list order, the same as the SDK path; a portfolio larger than that walks
267
- `pagingMetadataV2.cursors.next` on the list response (add it to your port when you hit it). Run
268
- `deploy.mjs portfolio --stack static --out <build dir>` only if a page loads anything client-side;
269
- point `site.outputDirectory` at the build folder, `wix release`. Pages sit at different depths
270
- (`/`, `/portfolio/…`, `/projects/…`): give the templates one base path to any `js/wix/` import (a
271
- template variable, or root-relative `/js/wix/…`), never a relative `./js/wix/` — it breaks one
272
- level down. Close with the live URL, the rebuild + release command, and one line for the owner:
273
- dashboard edits reach the site when that command runs.
274
-
275
- ### Wiring — React SPA (Vite etc.)
276
-
277
- Import `./styles/global.css` once at the app entry (needs `@tailwindcss/vite` in the vite plugins —
278
- deploy added the dep). Routes: `/portfolio` → your gallery on `useCollections()`; `/portfolio/:slug`
279
- → your collection page on `useCollectionProjects(slug)`; `/projects/:slug` → your detail surface on
280
- `useProjectDetail(slug)` (the hooks fetch client-side when no `initial*` is passed; route the 404
281
- view off `notFound`). Deploy wrote the public client id into `wix/config.ts`; nothing else to configure.
282
-
283
- ## Hard rules
284
-
285
- - **Reads only through the shipped exports** — they filter `hidden`, sort collections by the
286
- owner's `sortOrder` (projects have none — list order), and resolve every `wix:image://` /
287
- `wix:video://` value. Never hand-build a `wixstatic.com` URL, never render a raw media string
288
- into `src`.
289
- - **This vertical sells nothing** — no cart, no checkout, no `@wix/ecom`/`@wix/redirects`
290
- imports. A "contact about this project" CTA is a link, not a purchase flow.
291
- - **Route not-found off `notFound`**, and surface `error` — a transient `null` is loading, not a 404.
292
- - **Render `details` rows as given** (text or link per row); don't invent metadata.
293
- - **Gallery items render through `GalleryMedia`** (or `mediaElement` where it doesn't deploy) —
294
- never your own branch on `kind`.
295
- - Where the shipped components deploy (Astro, React): theme via the `@theme` tokens, and your
296
- markup uses Tailwind utilities on the same tokens — one design system across shipped and written
297
- code. No parallel theme files, no hardcoded palette values. Where they don't (`lib`, `static`, a
298
- port): style with whatever your stack does well, on one token set of your own.
299
- - Live data or an honest empty state — never mock collections, projects, or media.
300
- - **Call every hook before any conditional return.** Hooks first, branches after.
301
-
302
- ## Point the user to their dashboard
303
-
304
- Give the owner the dashboard link — the deploy step's JSON printed `dashboardUrl`; append
305
- `/wix-portfolio/projects` for Portfolio management (Projects and Collections are tabs on that one
306
- page: Projects adds projects and their media galleries; Collections groups them).
307
-
308
- ## Seeding
309
-
310
- Per `seed/SEED.md` — plain-data `plan.json` into `seed-portfolio.mjs` from the project root. Seed
311
- collections + projects that exercise the UI (covers on everything, 2–3 gallery images per project,
312
- `details` rows on a couple of projects). A fresh install ships sample content — seeding never
313
- deletes it; ask the owner before any cleanup.
@@ -1,110 +0,0 @@
1
- // REFERENCE collection page: collection header + its projects grid on the @theme tokens.
2
- // Correct and complete; per the skill's model you design and build your own on
3
- // useCollectionProjects (ProjectCard is reusable for an all-work grid or a home strip).
4
- import type { ComponentType, ReactNode } from "react";
5
- import { useCollectionProjects } from "../../hooks/portfolio/useCollectionProjects";
6
- import { imgAttrs } from "../../wix/media";
7
- import type { CollectionSummary, ProjectSummary } from "../../wix/portfolio/types";
8
-
9
- export interface LinkLikeProps {
10
- href: string;
11
- className?: string;
12
- children?: ReactNode;
13
- }
14
-
15
- const PlainLink = ({ href, className, children }: LinkLikeProps) => (
16
- <a href={href} className={className}>
17
- {children}
18
- </a>
19
- );
20
-
21
- export interface ProjectCardProps {
22
- project: ProjectSummary;
23
- projectHref?: (slug: string) => string;
24
- LinkComponent?: ComponentType<LinkLikeProps>;
25
- }
26
-
27
- export function ProjectCard({
28
- project,
29
- projectHref = (slug) => `/projects/${slug}`,
30
- LinkComponent = PlainLink,
31
- }: ProjectCardProps) {
32
- return (
33
- <LinkComponent href={projectHref(project.slug)} className="group block no-underline">
34
- <div className="relative aspect-[4/3] overflow-hidden rounded-lg bg-secondary">
35
- {project.imageUrl && (
36
- <img
37
- {...imgAttrs(project.imageUrl, "(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw", 0.75)}
38
- alt={project.title}
39
- className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]"
40
- />
41
- )}
42
- </div>
43
- <p className="mt-3 text-sm font-medium text-foreground">{project.title}</p>
44
- {project.description && (
45
- <p className="mt-0.5 text-xs text-muted-foreground">{project.description}</p>
46
- )}
47
- </LinkComponent>
48
- );
49
- }
50
-
51
- export interface CollectionProjectsViewProps {
52
- slug: string;
53
- initialCollection?: CollectionSummary;
54
- initialProjects?: ProjectSummary[];
55
- emptyMessage?: string;
56
- projectHref?: ProjectCardProps["projectHref"];
57
- LinkComponent?: ComponentType<LinkLikeProps>;
58
- CardComponent?: ComponentType<ProjectCardProps>;
59
- }
60
-
61
- export default function CollectionProjectsView({
62
- slug,
63
- initialCollection,
64
- initialProjects,
65
- emptyMessage = "No projects in this collection yet.",
66
- projectHref,
67
- LinkComponent,
68
- CardComponent = ProjectCard,
69
- }: CollectionProjectsViewProps) {
70
- const { collection, notFound, projects, error } = useCollectionProjects(slug, {
71
- initialCollection,
72
- initialProjects,
73
- });
74
-
75
- if (notFound) {
76
- return <p className="py-16 text-center text-muted-foreground">Collection not found.</p>;
77
- }
78
-
79
- return (
80
- <div>
81
- <header className="mb-8">
82
- <h1 className="text-2xl font-semibold tracking-tight">
83
- {collection ? collection.title : <span className="inline-block h-7 w-48 animate-pulse rounded bg-secondary" />}
84
- </h1>
85
- {collection?.description && (
86
- <p className="mt-2 max-w-2xl text-muted-foreground">{collection.description}</p>
87
- )}
88
- </header>
89
- {error && <p className="mb-4 text-sm text-red-600">{error}</p>}
90
- {projects === null ? (
91
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3" aria-busy="true">
92
- {Array.from({ length: 6 }, (_, i) => (
93
- <div key={i}>
94
- <div className="aspect-[4/3] animate-pulse rounded-lg bg-secondary" />
95
- <div className="mt-3 h-3.5 w-2/3 animate-pulse rounded bg-secondary" />
96
- </div>
97
- ))}
98
- </div>
99
- ) : projects.length === 0 ? (
100
- <p className="py-16 text-center text-muted-foreground">{emptyMessage}</p>
101
- ) : (
102
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
103
- {projects.map((p) => (
104
- <CardComponent key={p.id} project={p} projectHref={projectHref} LinkComponent={LinkComponent} />
105
- ))}
106
- </div>
107
- )}
108
- </div>
109
- );
110
- }
@@ -1,90 +0,0 @@
1
- // REFERENCE gallery surface: collections grid on the @theme tokens.
2
- // Correct and complete; per the skill's model you design and build your own on useCollections.
3
- import type { ComponentType, ReactNode } from "react";
4
- import { useCollections } from "../../hooks/portfolio/useCollections";
5
- import { imgAttrs } from "../../wix/media";
6
- import type { CollectionSummary } from "../../wix/portfolio/types";
7
-
8
- export interface LinkLikeProps {
9
- href: string;
10
- className?: string;
11
- children?: ReactNode;
12
- }
13
-
14
- const PlainLink = ({ href, className, children }: LinkLikeProps) => (
15
- <a href={href} className={className}>
16
- {children}
17
- </a>
18
- );
19
-
20
- export interface CollectionCardProps {
21
- collection: CollectionSummary;
22
- collectionHref?: (slug: string) => string;
23
- LinkComponent?: ComponentType<LinkLikeProps>;
24
- }
25
-
26
- export function CollectionCard({
27
- collection,
28
- collectionHref = (slug) => `/portfolio/${slug}`,
29
- LinkComponent = PlainLink,
30
- }: CollectionCardProps) {
31
- return (
32
- <LinkComponent href={collectionHref(collection.slug)} className="group block no-underline">
33
- <div className="relative aspect-[4/3] overflow-hidden rounded-lg bg-secondary">
34
- {collection.imageUrl && (
35
- <img
36
- {...imgAttrs(collection.imageUrl, "(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw", 0.75)}
37
- alt={collection.title}
38
- className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.03]"
39
- />
40
- )}
41
- </div>
42
- <p className="mt-3 text-sm font-medium text-foreground">{collection.title}</p>
43
- {collection.description && (
44
- <p className="mt-0.5 text-xs text-muted-foreground">{collection.description}</p>
45
- )}
46
- </LinkComponent>
47
- );
48
- }
49
-
50
- export interface CollectionsViewProps {
51
- initialCollections?: CollectionSummary[];
52
- emptyMessage?: string;
53
- collectionHref?: CollectionCardProps["collectionHref"];
54
- LinkComponent?: ComponentType<LinkLikeProps>;
55
- CardComponent?: ComponentType<CollectionCardProps>;
56
- }
57
-
58
- export default function CollectionsView({
59
- initialCollections,
60
- emptyMessage = "No collections yet — check back soon.",
61
- collectionHref,
62
- LinkComponent,
63
- CardComponent = CollectionCard,
64
- }: CollectionsViewProps) {
65
- const { collections, error } = useCollections({ initialCollections });
66
-
67
- return (
68
- <div>
69
- {error && <p className="mb-4 text-sm text-red-600">{error}</p>}
70
- {collections === null ? (
71
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3" aria-busy="true">
72
- {Array.from({ length: 6 }, (_, i) => (
73
- <div key={i}>
74
- <div className="aspect-[4/3] animate-pulse rounded-lg bg-secondary" />
75
- <div className="mt-3 h-3.5 w-2/3 animate-pulse rounded bg-secondary" />
76
- </div>
77
- ))}
78
- </div>
79
- ) : collections.length === 0 ? (
80
- <p className="py-16 text-center text-muted-foreground">{emptyMessage}</p>
81
- ) : (
82
- <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
83
- {collections.map((c) => (
84
- <CardComponent key={c.id} collection={c} collectionHref={collectionHref} LinkComponent={LinkComponent} />
85
- ))}
86
- </div>
87
- )}
88
- </div>
89
- );
90
- }
@@ -1,35 +0,0 @@
1
- // SHIPPED — wire as-is. One gallery item as its one element: a <video> with poster for a video
2
- // item, an <img> for an image item, null when nothing is renderable (never a broken tag, never
3
- // an <img> for a video). The branching rule is `mediaElement` in wix/portfolio/portfolio-core.ts,
4
- // shared with every other stack; this is its React spelling. Wrapped in a link when the owner
5
- // attached one. `className` styles the media element itself.
6
- import type { ReactNode } from "react";
7
- import { mediaElement } from "../../wix/portfolio/portfolio-core";
8
- import type { GalleryItem } from "../../wix/portfolio/types";
9
-
10
- export interface GalleryMediaProps {
11
- item: GalleryItem;
12
- className?: string;
13
- }
14
-
15
- export function GalleryMedia({ item, className }: GalleryMediaProps) {
16
- const el = mediaElement(item);
17
- if (!el) return null;
18
- if (el.tag === "video") {
19
- return <video src={el.attrs.src} poster={el.attrs.poster} controls playsInline className={className} />;
20
- }
21
- return <img src={el.attrs.src} alt={el.attrs.alt} loading="lazy" decoding="async" className={className} />;
22
- }
23
-
24
- /** The item's outbound link when the owner set one, else the children as they are. */
25
- export function GalleryLink({ item, children }: { item: GalleryItem; children: ReactNode }) {
26
- return item.linkUrl ? (
27
- <a href={item.linkUrl} target={item.linkTarget ?? undefined} rel="noopener">
28
- {children}
29
- </a>
30
- ) : (
31
- <>{children}</>
32
- );
33
- }
34
-
35
- export default GalleryMedia;
@@ -1,85 +0,0 @@
1
- // REFERENCE project detail: header, details[] rows (text or link), media gallery (image AND
2
- // video items) on the @theme tokens. Correct and complete; per the skill's model you design
3
- // and build your own on useProjectDetail. The gallery items render through the SHIPPED
4
- // GalleryMedia (kind branching, poster, link wrap) — keep that in whatever you build.
5
- import { useProjectDetail } from "../../hooks/portfolio/useProjectDetail";
6
- import { imgAttrs } from "../../wix/media";
7
- import type { GalleryItem, ProjectDetail } from "../../wix/portfolio/types";
8
- import { GalleryLink, GalleryMedia } from "./GalleryMedia";
9
-
10
- export interface ProjectDetailViewProps {
11
- slug: string;
12
- initialProject?: ProjectDetail;
13
- initialItems?: GalleryItem[];
14
- }
15
-
16
- export default function ProjectDetailView({ slug, initialProject, initialItems }: ProjectDetailViewProps) {
17
- const { project, notFound, items, error } = useProjectDetail(slug, { initialProject, initialItems });
18
-
19
- if (notFound) {
20
- return <p className="py-16 text-center text-muted-foreground">Project not found.</p>;
21
- }
22
- if (!project) {
23
- return (
24
- <div aria-busy="true">
25
- <div className="h-7 w-64 animate-pulse rounded bg-secondary" />
26
- <div className="mt-6 aspect-[4/3] animate-pulse rounded-lg bg-secondary" />
27
- </div>
28
- );
29
- }
30
-
31
- return (
32
- <article>
33
- <header className="mb-8 max-w-2xl">
34
- <h1 className="text-2xl font-semibold tracking-tight">{project.title}</h1>
35
- {project.description && (
36
- <p className="mt-2 leading-relaxed text-muted-foreground">{project.description}</p>
37
- )}
38
- {project.details.length > 0 && (
39
- <dl className="mt-5 grid grid-cols-[auto_1fr] items-baseline gap-x-6 gap-y-1.5">
40
- {project.details.map((d, i) => (
41
- <div key={i} className="contents">
42
- <dt className="text-sm text-muted-foreground">{d.label}</dt>
43
- <dd className="m-0 text-sm text-foreground">
44
- {d.url ? (
45
- <a href={d.url} target={d.target ?? undefined} rel="noopener" className="underline">
46
- {d.text}
47
- </a>
48
- ) : (
49
- d.text
50
- )}
51
- </dd>
52
- </div>
53
- ))}
54
- </dl>
55
- )}
56
- </header>
57
- {error && <p className="mb-4 text-sm text-red-600">{error}</p>}
58
- {items === null ? (
59
- <div className="flex flex-col gap-6" aria-busy="true">
60
- <div className="aspect-[4/3] animate-pulse rounded-lg bg-secondary" />
61
- </div>
62
- ) : items.length === 0 ? (
63
- // No gallery items — the cover is the project's only real media; text-only otherwise.
64
- project.imageUrl ? (
65
- <img {...imgAttrs(project.imageUrl, "(min-width: 1024px) 64rem, 100vw", 0.75)} alt={project.title} className="block w-full rounded-lg" />
66
- ) : (
67
- <p className="py-16 text-center text-muted-foreground">No media in this project yet.</p>
68
- )
69
- ) : (
70
- <div className="flex flex-col gap-6">
71
- {items.map((item) => (
72
- <figure key={item.id} className="m-0">
73
- <GalleryLink item={item}>
74
- <GalleryMedia item={item} className="block w-full rounded-lg bg-secondary" />
75
- </GalleryLink>
76
- {item.title && (
77
- <figcaption className="mt-1.5 text-sm text-muted-foreground">{item.title}</figcaption>
78
- )}
79
- </figure>
80
- ))}
81
- </div>
82
- )}
83
- </article>
84
- );
85
- }