@doswiftly/cli 0.1.1

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 (453) hide show
  1. package/README.md +357 -0
  2. package/bin/doswiftly.js +2 -0
  3. package/dist/commands/auth-github.d.ts +6 -0
  4. package/dist/commands/auth-github.d.ts.map +1 -0
  5. package/dist/commands/auth-github.js +89 -0
  6. package/dist/commands/auth-github.js.map +1 -0
  7. package/dist/commands/auth-token.d.ts +12 -0
  8. package/dist/commands/auth-token.d.ts.map +1 -0
  9. package/dist/commands/auth-token.js +43 -0
  10. package/dist/commands/auth-token.js.map +1 -0
  11. package/dist/commands/auth.d.ts +22 -0
  12. package/dist/commands/auth.d.ts.map +1 -0
  13. package/dist/commands/auth.js +348 -0
  14. package/dist/commands/auth.js.map +1 -0
  15. package/dist/commands/check.d.ts +5 -0
  16. package/dist/commands/check.d.ts.map +1 -0
  17. package/dist/commands/check.js +234 -0
  18. package/dist/commands/check.js.map +1 -0
  19. package/dist/commands/config.d.ts +3 -0
  20. package/dist/commands/config.d.ts.map +1 -0
  21. package/dist/commands/config.js +104 -0
  22. package/dist/commands/config.js.map +1 -0
  23. package/dist/commands/deploy.d.ts +37 -0
  24. package/dist/commands/deploy.d.ts.map +1 -0
  25. package/dist/commands/deploy.js +580 -0
  26. package/dist/commands/deploy.js.map +1 -0
  27. package/dist/commands/dev.d.ts +8 -0
  28. package/dist/commands/dev.d.ts.map +1 -0
  29. package/dist/commands/dev.js +83 -0
  30. package/dist/commands/dev.js.map +1 -0
  31. package/dist/commands/doctor.d.ts +5 -0
  32. package/dist/commands/doctor.d.ts.map +1 -0
  33. package/dist/commands/doctor.js +363 -0
  34. package/dist/commands/doctor.js.map +1 -0
  35. package/dist/commands/domain.d.ts +13 -0
  36. package/dist/commands/domain.d.ts.map +1 -0
  37. package/dist/commands/domain.js +128 -0
  38. package/dist/commands/domain.js.map +1 -0
  39. package/dist/commands/env.d.ts +25 -0
  40. package/dist/commands/env.d.ts.map +1 -0
  41. package/dist/commands/env.js +228 -0
  42. package/dist/commands/env.js.map +1 -0
  43. package/dist/commands/init.d.ts +11 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +1028 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/inspect.d.ts +12 -0
  48. package/dist/commands/inspect.d.ts.map +1 -0
  49. package/dist/commands/inspect.js +162 -0
  50. package/dist/commands/inspect.js.map +1 -0
  51. package/dist/commands/migrate.d.ts +18 -0
  52. package/dist/commands/migrate.d.ts.map +1 -0
  53. package/dist/commands/migrate.js +355 -0
  54. package/dist/commands/migrate.js.map +1 -0
  55. package/dist/commands/preview.d.ts +29 -0
  56. package/dist/commands/preview.d.ts.map +1 -0
  57. package/dist/commands/preview.js +199 -0
  58. package/dist/commands/preview.js.map +1 -0
  59. package/dist/commands/proxy.d.ts +9 -0
  60. package/dist/commands/proxy.d.ts.map +1 -0
  61. package/dist/commands/proxy.js +37 -0
  62. package/dist/commands/proxy.js.map +1 -0
  63. package/dist/commands/sdk.d.ts +5 -0
  64. package/dist/commands/sdk.d.ts.map +1 -0
  65. package/dist/commands/sdk.js +82 -0
  66. package/dist/commands/sdk.js.map +1 -0
  67. package/dist/commands/template.d.ts +107 -0
  68. package/dist/commands/template.d.ts.map +1 -0
  69. package/dist/commands/template.js +1309 -0
  70. package/dist/commands/template.js.map +1 -0
  71. package/dist/commands/types.d.ts +5 -0
  72. package/dist/commands/types.d.ts.map +1 -0
  73. package/dist/commands/types.js +82 -0
  74. package/dist/commands/types.js.map +1 -0
  75. package/dist/commands/update.d.ts +2 -0
  76. package/dist/commands/update.d.ts.map +1 -0
  77. package/dist/commands/update.js +103 -0
  78. package/dist/commands/update.js.map +1 -0
  79. package/dist/commands/upgrade.d.ts +18 -0
  80. package/dist/commands/upgrade.d.ts.map +1 -0
  81. package/dist/commands/upgrade.js +55 -0
  82. package/dist/commands/upgrade.js.map +1 -0
  83. package/dist/commands/verify.d.ts +5 -0
  84. package/dist/commands/verify.d.ts.map +1 -0
  85. package/dist/commands/verify.js +232 -0
  86. package/dist/commands/verify.js.map +1 -0
  87. package/dist/commands/whoami.d.ts +5 -0
  88. package/dist/commands/whoami.d.ts.map +1 -0
  89. package/dist/commands/whoami.js +60 -0
  90. package/dist/commands/whoami.js.map +1 -0
  91. package/dist/config/types.d.ts +173 -0
  92. package/dist/config/types.d.ts.map +1 -0
  93. package/dist/config/types.js +48 -0
  94. package/dist/config/types.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +416 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/lib/api-url.d.ts +14 -0
  100. package/dist/lib/api-url.d.ts.map +1 -0
  101. package/dist/lib/api-url.js +24 -0
  102. package/dist/lib/api-url.js.map +1 -0
  103. package/dist/lib/api.d.ts +67 -0
  104. package/dist/lib/api.d.ts.map +1 -0
  105. package/dist/lib/api.js +36 -0
  106. package/dist/lib/api.js.map +1 -0
  107. package/dist/lib/config.d.ts +39 -0
  108. package/dist/lib/config.d.ts.map +1 -0
  109. package/dist/lib/config.js +195 -0
  110. package/dist/lib/config.js.map +1 -0
  111. package/dist/lib/env-storage.d.ts +140 -0
  112. package/dist/lib/env-storage.d.ts.map +1 -0
  113. package/dist/lib/env-storage.js +464 -0
  114. package/dist/lib/env-storage.js.map +1 -0
  115. package/dist/lib/errors.d.ts +61 -0
  116. package/dist/lib/errors.d.ts.map +1 -0
  117. package/dist/lib/errors.js +204 -0
  118. package/dist/lib/errors.js.map +1 -0
  119. package/dist/lib/i18n.d.ts +99 -0
  120. package/dist/lib/i18n.d.ts.map +1 -0
  121. package/dist/lib/i18n.js +184 -0
  122. package/dist/lib/i18n.js.map +1 -0
  123. package/dist/lib/logger.d.ts +95 -0
  124. package/dist/lib/logger.d.ts.map +1 -0
  125. package/dist/lib/logger.js +168 -0
  126. package/dist/lib/logger.js.map +1 -0
  127. package/dist/lib/package-manager.d.ts +91 -0
  128. package/dist/lib/package-manager.d.ts.map +1 -0
  129. package/dist/lib/package-manager.js +205 -0
  130. package/dist/lib/package-manager.js.map +1 -0
  131. package/dist/lib/proxy-server.d.ts +24 -0
  132. package/dist/lib/proxy-server.d.ts.map +1 -0
  133. package/dist/lib/proxy-server.js +173 -0
  134. package/dist/lib/proxy-server.js.map +1 -0
  135. package/dist/lib/select-with-back.d.ts +34 -0
  136. package/dist/lib/select-with-back.d.ts.map +1 -0
  137. package/dist/lib/select-with-back.js +94 -0
  138. package/dist/lib/select-with-back.js.map +1 -0
  139. package/dist/lib/shared-api-client.d.ts +40 -0
  140. package/dist/lib/shared-api-client.d.ts.map +1 -0
  141. package/dist/lib/shared-api-client.js +92 -0
  142. package/dist/lib/shared-api-client.js.map +1 -0
  143. package/dist/lib/wizard-engine.d.ts +128 -0
  144. package/dist/lib/wizard-engine.d.ts.map +1 -0
  145. package/dist/lib/wizard-engine.js +168 -0
  146. package/dist/lib/wizard-engine.js.map +1 -0
  147. package/package.json +85 -0
  148. package/templates/storefront-minimal/.env.example +10 -0
  149. package/templates/storefront-minimal/.github/workflows/build-template.yml +109 -0
  150. package/templates/storefront-minimal/app/globals.css +18 -0
  151. package/templates/storefront-minimal/app/layout.tsx +26 -0
  152. package/templates/storefront-minimal/app/page.tsx +93 -0
  153. package/templates/storefront-minimal/lib/graphql-client.ts +23 -0
  154. package/templates/storefront-minimal/next.config.ts +15 -0
  155. package/templates/storefront-minimal/open-next.config.ts +3 -0
  156. package/templates/storefront-minimal/package.json +30 -0
  157. package/templates/storefront-minimal/postcss.config.mjs +5 -0
  158. package/templates/storefront-minimal/tailwind.config.ts +14 -0
  159. package/templates/storefront-minimal/tsconfig.json +27 -0
  160. package/templates/storefront-minimal/wrangler.toml +9 -0
  161. package/templates/storefront-nextjs/.env.example +68 -0
  162. package/templates/storefront-nextjs/.github/workflows/build-template.yml +109 -0
  163. package/templates/storefront-nextjs/.github/workflows/deploy.yml +25 -0
  164. package/templates/storefront-nextjs/.github/workflows/preview.yml +22 -0
  165. package/templates/storefront-nextjs/README.md +520 -0
  166. package/templates/storefront-nextjs/app/account/orders/page.tsx +216 -0
  167. package/templates/storefront-nextjs/app/account/page.tsx +167 -0
  168. package/templates/storefront-nextjs/app/auth/login/page.tsx +135 -0
  169. package/templates/storefront-nextjs/app/auth/register/page.tsx +228 -0
  170. package/templates/storefront-nextjs/app/cart/page.tsx +263 -0
  171. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +200 -0
  172. package/templates/storefront-nextjs/app/categories/page.tsx +58 -0
  173. package/templates/storefront-nextjs/app/checkout/page.tsx +351 -0
  174. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +158 -0
  175. package/templates/storefront-nextjs/app/collections/page.tsx +61 -0
  176. package/templates/storefront-nextjs/app/globals.css +98 -0
  177. package/templates/storefront-nextjs/app/layout.tsx +39 -0
  178. package/templates/storefront-nextjs/app/page.tsx +136 -0
  179. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +119 -0
  180. package/templates/storefront-nextjs/app/products/page.tsx +107 -0
  181. package/templates/storefront-nextjs/app/search/page.tsx +127 -0
  182. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +94 -0
  183. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +77 -0
  184. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +29 -0
  185. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +217 -0
  186. package/templates/storefront-nextjs/components/commerce/pagination.tsx +62 -0
  187. package/templates/storefront-nextjs/components/commerce/product-actions.tsx +135 -0
  188. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +109 -0
  189. package/templates/storefront-nextjs/components/commerce/product-price.tsx +375 -0
  190. package/templates/storefront-nextjs/components/commerce/search-input.tsx +178 -0
  191. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +64 -0
  192. package/templates/storefront-nextjs/components/commerce/variant-selector.tsx +210 -0
  193. package/templates/storefront-nextjs/components/layout/footer.tsx +107 -0
  194. package/templates/storefront-nextjs/components/layout/header.tsx +104 -0
  195. package/templates/storefront-nextjs/components/providers.tsx +62 -0
  196. package/templates/storefront-nextjs/lib/auth/routes.ts +52 -0
  197. package/templates/storefront-nextjs/lib/currency.tsx +140 -0
  198. package/templates/storefront-nextjs/lib/format.ts +159 -0
  199. package/templates/storefront-nextjs/lib/graphql-queries.ts +629 -0
  200. package/templates/storefront-nextjs/lib/hooks.ts +30 -0
  201. package/templates/storefront-nextjs/middleware.ts +80 -0
  202. package/templates/storefront-nextjs/next.config.ts +37 -0
  203. package/templates/storefront-nextjs/open-next.config.ts +3 -0
  204. package/templates/storefront-nextjs/package.dev.json +30 -0
  205. package/templates/storefront-nextjs/package.json +32 -0
  206. package/templates/storefront-nextjs/package.json.template +32 -0
  207. package/templates/storefront-nextjs/postcss.config.mjs +8 -0
  208. package/templates/storefront-nextjs/tailwind.config.ts +111 -0
  209. package/templates/storefront-nextjs/tsconfig.json +27 -0
  210. package/templates/storefront-nextjs/wrangler.toml +9 -0
  211. package/templates/storefront-nextjs-shadcn/.env.example +68 -0
  212. package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +109 -0
  213. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +25 -0
  214. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +22 -0
  215. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +282 -0
  216. package/templates/storefront-nextjs-shadcn/CLAUDE.md +96 -0
  217. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +190 -0
  218. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +263 -0
  219. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +135 -0
  220. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +142 -0
  221. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +448 -0
  222. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +307 -0
  223. package/templates/storefront-nextjs-shadcn/README.md +195 -0
  224. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +245 -0
  225. package/templates/storefront-nextjs-shadcn/app/about/page.tsx +34 -0
  226. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +215 -0
  227. package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +484 -0
  228. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +128 -0
  229. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/tracking/page.tsx +206 -0
  230. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +80 -0
  231. package/templates/storefront-nextjs-shadcn/app/account/page.tsx +107 -0
  232. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +195 -0
  233. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +87 -0
  234. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +125 -0
  235. package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +131 -0
  236. package/templates/storefront-nextjs-shadcn/app/auth/login/page.tsx +24 -0
  237. package/templates/storefront-nextjs-shadcn/app/auth/register/page.tsx +20 -0
  238. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +323 -0
  239. package/templates/storefront-nextjs-shadcn/app/blog/page.tsx +159 -0
  240. package/templates/storefront-nextjs-shadcn/app/brands/[slug]/page.tsx +170 -0
  241. package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +73 -0
  242. package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +165 -0
  243. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +78 -0
  244. package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +75 -0
  245. package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +1752 -0
  246. package/templates/storefront-nextjs-shadcn/app/checkout/success/[orderId]/page.tsx +256 -0
  247. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +74 -0
  248. package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +75 -0
  249. package/templates/storefront-nextjs-shadcn/app/contact/page.tsx +114 -0
  250. package/templates/storefront-nextjs-shadcn/app/error.tsx +90 -0
  251. package/templates/storefront-nextjs-shadcn/app/globals.css +125 -0
  252. package/templates/storefront-nextjs-shadcn/app/layout.tsx +57 -0
  253. package/templates/storefront-nextjs-shadcn/app/not-found.tsx +68 -0
  254. package/templates/storefront-nextjs-shadcn/app/page.tsx +21 -0
  255. package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +246 -0
  256. package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +343 -0
  257. package/templates/storefront-nextjs-shadcn/app/products/page.tsx +25 -0
  258. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +192 -0
  259. package/templates/storefront-nextjs-shadcn/app/returns/page.tsx +77 -0
  260. package/templates/storefront-nextjs-shadcn/app/robots.ts +53 -0
  261. package/templates/storefront-nextjs-shadcn/app/search/page.tsx +16 -0
  262. package/templates/storefront-nextjs-shadcn/app/search/search-client.tsx +47 -0
  263. package/templates/storefront-nextjs-shadcn/app/shipping/page.tsx +62 -0
  264. package/templates/storefront-nextjs-shadcn/app/sitemap.ts +144 -0
  265. package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +179 -0
  266. package/templates/storefront-nextjs-shadcn/codegen.ts +51 -0
  267. package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +348 -0
  268. package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +144 -0
  269. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +258 -0
  270. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +107 -0
  271. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +132 -0
  272. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +188 -0
  273. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +305 -0
  274. package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +240 -0
  275. package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +177 -0
  276. package/templates/storefront-nextjs-shadcn/components/blog/index.ts +8 -0
  277. package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +119 -0
  278. package/templates/storefront-nextjs-shadcn/components/brand/brand-grid.tsx +64 -0
  279. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +140 -0
  280. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +48 -0
  281. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +112 -0
  282. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +84 -0
  283. package/templates/storefront-nextjs-shadcn/components/cart/index.ts +17 -0
  284. package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +121 -0
  285. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +162 -0
  286. package/templates/storefront-nextjs-shadcn/components/checkout/index.ts +25 -0
  287. package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +187 -0
  288. package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +160 -0
  289. package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +154 -0
  290. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +225 -0
  291. package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +62 -0
  292. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +158 -0
  293. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +174 -0
  294. package/templates/storefront-nextjs-shadcn/components/commerce/variant-selector.tsx +210 -0
  295. package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +97 -0
  296. package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +187 -0
  297. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +151 -0
  298. package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +166 -0
  299. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +245 -0
  300. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +246 -0
  301. package/templates/storefront-nextjs-shadcn/components/discount/index.ts +19 -0
  302. package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +113 -0
  303. package/templates/storefront-nextjs-shadcn/components/error/index.ts +7 -0
  304. package/templates/storefront-nextjs-shadcn/components/filters/attribute-filter.tsx +153 -0
  305. package/templates/storefront-nextjs-shadcn/components/filters/checkbox-group-filter.tsx +167 -0
  306. package/templates/storefront-nextjs-shadcn/components/filters/color-swatch-filter.tsx +176 -0
  307. package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +220 -0
  308. package/templates/storefront-nextjs-shadcn/components/filters/index.ts +36 -0
  309. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +193 -0
  310. package/templates/storefront-nextjs-shadcn/components/filters/toggle-filter.tsx +132 -0
  311. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +321 -0
  312. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +309 -0
  313. package/templates/storefront-nextjs-shadcn/components/gift-card/index.ts +24 -0
  314. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +72 -0
  315. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +107 -0
  316. package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +85 -0
  317. package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +34 -0
  318. package/templates/storefront-nextjs-shadcn/components/home/index.ts +8 -0
  319. package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +108 -0
  320. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +133 -0
  321. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +341 -0
  322. package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +128 -0
  323. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +147 -0
  324. package/templates/storefront-nextjs-shadcn/components/layout/index.ts +9 -0
  325. package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +211 -0
  326. package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +95 -0
  327. package/templates/storefront-nextjs-shadcn/components/layout/theme-switcher.tsx +192 -0
  328. package/templates/storefront-nextjs-shadcn/components/loyalty/index.ts +11 -0
  329. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +93 -0
  330. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +177 -0
  331. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +250 -0
  332. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +217 -0
  333. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-badge.tsx +106 -0
  334. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +131 -0
  335. package/templates/storefront-nextjs-shadcn/components/order/delivery-estimate.tsx +196 -0
  336. package/templates/storefront-nextjs-shadcn/components/order/index.ts +11 -0
  337. package/templates/storefront-nextjs-shadcn/components/order/order-tracking.tsx +200 -0
  338. package/templates/storefront-nextjs-shadcn/components/order/shipment-card.tsx +407 -0
  339. package/templates/storefront-nextjs-shadcn/components/order/tracking-status.tsx +222 -0
  340. package/templates/storefront-nextjs-shadcn/components/order/tracking-timeline.tsx +205 -0
  341. package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +161 -0
  342. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +250 -0
  343. package/templates/storefront-nextjs-shadcn/components/product/discount-badge.tsx +196 -0
  344. package/templates/storefront-nextjs-shadcn/components/product/index.ts +41 -0
  345. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +147 -0
  346. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +217 -0
  347. package/templates/storefront-nextjs-shadcn/components/product/product-gallery.tsx +143 -0
  348. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +83 -0
  349. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +155 -0
  350. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +158 -0
  351. package/templates/storefront-nextjs-shadcn/components/product/product-quantity-selector.tsx +111 -0
  352. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +238 -0
  353. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +58 -0
  354. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +169 -0
  355. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +220 -0
  356. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +338 -0
  357. package/templates/storefront-nextjs-shadcn/components/product/review-summary.tsx +143 -0
  358. package/templates/storefront-nextjs-shadcn/components/product/sale-countdown.tsx +166 -0
  359. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +213 -0
  360. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +57 -0
  361. package/templates/storefront-nextjs-shadcn/components/product/stock-indicator.tsx +91 -0
  362. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +103 -0
  363. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +8 -0
  364. package/templates/storefront-nextjs-shadcn/components/providers/query-provider.tsx +260 -0
  365. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +13 -0
  366. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +26 -0
  367. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +608 -0
  368. package/templates/storefront-nextjs-shadcn/components/returns/return-status-card.tsx +554 -0
  369. package/templates/storefront-nextjs-shadcn/components/search/index.ts +8 -0
  370. package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +140 -0
  371. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +58 -0
  372. package/templates/storefront-nextjs-shadcn/components/search/search-suggestions.tsx +43 -0
  373. package/templates/storefront-nextjs-shadcn/components/seo/index.ts +12 -0
  374. package/templates/storefront-nextjs-shadcn/components/seo/json-ld.tsx +56 -0
  375. package/templates/storefront-nextjs-shadcn/components/seo/product-json-ld.ts +167 -0
  376. package/templates/storefront-nextjs-shadcn/components/shipping/index.ts +16 -0
  377. package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +337 -0
  378. package/templates/storefront-nextjs-shadcn/components/ui/accordion.tsx +153 -0
  379. package/templates/storefront-nextjs-shadcn/components/ui/alert.tsx +59 -0
  380. package/templates/storefront-nextjs-shadcn/components/ui/badge.tsx +34 -0
  381. package/templates/storefront-nextjs-shadcn/components/ui/button.tsx +51 -0
  382. package/templates/storefront-nextjs-shadcn/components/ui/card.tsx +77 -0
  383. package/templates/storefront-nextjs-shadcn/components/ui/checkbox.tsx +30 -0
  384. package/templates/storefront-nextjs-shadcn/components/ui/dialog.tsx +137 -0
  385. package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +207 -0
  386. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +67 -0
  387. package/templates/storefront-nextjs-shadcn/components/ui/input.tsx +65 -0
  388. package/templates/storefront-nextjs-shadcn/components/ui/label.tsx +26 -0
  389. package/templates/storefront-nextjs-shadcn/components/ui/pagination.tsx +205 -0
  390. package/templates/storefront-nextjs-shadcn/components/ui/radio-group.tsx +44 -0
  391. package/templates/storefront-nextjs-shadcn/components/ui/select.tsx +160 -0
  392. package/templates/storefront-nextjs-shadcn/components/ui/separator.tsx +28 -0
  393. package/templates/storefront-nextjs-shadcn/components/ui/skeleton.tsx +20 -0
  394. package/templates/storefront-nextjs-shadcn/components/ui/spinner.tsx +82 -0
  395. package/templates/storefront-nextjs-shadcn/components/ui/tabs.tsx +119 -0
  396. package/templates/storefront-nextjs-shadcn/components/ui/toast.tsx +96 -0
  397. package/templates/storefront-nextjs-shadcn/components/wishlist/index.ts +9 -0
  398. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +148 -0
  399. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +47 -0
  400. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +165 -0
  401. package/templates/storefront-nextjs-shadcn/components.json +19 -0
  402. package/templates/storefront-nextjs-shadcn/generated/.gitkeep +2 -0
  403. package/templates/storefront-nextjs-shadcn/graphql/.gitkeep +31 -0
  404. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +168 -0
  405. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +160 -0
  406. package/templates/storefront-nextjs-shadcn/hooks/index.ts +9 -0
  407. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +310 -0
  408. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +286 -0
  409. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +110 -0
  410. package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.test.ts +173 -0
  411. package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.ts +298 -0
  412. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +220 -0
  413. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +57 -0
  414. package/templates/storefront-nextjs-shadcn/lib/config.ts +46 -0
  415. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +254 -0
  416. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +464 -0
  417. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +328 -0
  418. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +295 -0
  419. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +27 -0
  420. package/templates/storefront-nextjs-shadcn/lib/format.test.ts +397 -0
  421. package/templates/storefront-nextjs-shadcn/lib/format.ts +226 -0
  422. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +109 -0
  423. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +1183 -0
  424. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +267 -0
  425. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +30 -0
  426. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +89 -0
  427. package/templates/storefront-nextjs-shadcn/lib/utils.ts +6 -0
  428. package/templates/storefront-nextjs-shadcn/next.config.ts +47 -0
  429. package/templates/storefront-nextjs-shadcn/open-next.config.ts +3 -0
  430. package/templates/storefront-nextjs-shadcn/package.dev.json +30 -0
  431. package/templates/storefront-nextjs-shadcn/package.json +60 -0
  432. package/templates/storefront-nextjs-shadcn/package.json.template +46 -0
  433. package/templates/storefront-nextjs-shadcn/postcss.config.mjs +8 -0
  434. package/templates/storefront-nextjs-shadcn/proxy.ts +80 -0
  435. package/templates/storefront-nextjs-shadcn/public/icons/payment/apple-pay.svg +8 -0
  436. package/templates/storefront-nextjs-shadcn/public/icons/payment/bank-transfer.svg +10 -0
  437. package/templates/storefront-nextjs-shadcn/public/icons/payment/blik.svg +6 -0
  438. package/templates/storefront-nextjs-shadcn/public/icons/payment/cash-on-delivery.svg +11 -0
  439. package/templates/storefront-nextjs-shadcn/public/icons/payment/google-pay.svg +11 -0
  440. package/templates/storefront-nextjs-shadcn/public/icons/payment/mastercard.svg +7 -0
  441. package/templates/storefront-nextjs-shadcn/public/icons/payment/paypal.svg +7 -0
  442. package/templates/storefront-nextjs-shadcn/public/icons/payment/payu.svg +7 -0
  443. package/templates/storefront-nextjs-shadcn/public/icons/payment/przelewy24.svg +7 -0
  444. package/templates/storefront-nextjs-shadcn/public/icons/payment/stripe.svg +4 -0
  445. package/templates/storefront-nextjs-shadcn/public/icons/payment/visa.svg +5 -0
  446. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +66 -0
  447. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +56 -0
  448. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +184 -0
  449. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +103 -0
  450. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +291 -0
  451. package/templates/storefront-nextjs-shadcn/tailwind.config.ts +111 -0
  452. package/templates/storefront-nextjs-shadcn/tsconfig.json +27 -0
  453. package/templates/storefront-nextjs-shadcn/wrangler.toml +9 -0
@@ -0,0 +1,58 @@
1
+ import Link from "next/link";
2
+ import { useCategories } from "@doswiftly/commerce-sdk/graphql/server";
3
+
4
+ export default async function CategoriesPage() {
5
+ // Fetch all root categories
6
+ const { categories } = await useCategories();
7
+
8
+ return (
9
+ <div className="container mx-auto px-4 py-8">
10
+ {/* Page Header */}
11
+ <div className="mb-8">
12
+ <h1 className="text-3xl font-bold text-gray-900">Categories</h1>
13
+ <p className="mt-2 text-gray-600">Browse products by category</p>
14
+ </div>
15
+
16
+ {/* Categories Grid */}
17
+ <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 lg:gap-6">
18
+ {categories.length === 0 ? (
19
+ <div className="col-span-full py-12 text-center text-gray-500">
20
+ No categories found
21
+ </div>
22
+ ) : (
23
+ categories.map((category) => (
24
+ <Link
25
+ key={category.id}
26
+ href={`/categories/${category.slug}`}
27
+ className="group relative overflow-hidden rounded-lg"
28
+ >
29
+ <div className="aspect-square bg-gray-100">
30
+ {category.image?.url ? (
31
+ <img
32
+ src={category.image.url}
33
+ alt={category.image.altText || category.name}
34
+ className="h-full w-full object-cover transition group-hover:scale-105"
35
+ />
36
+ ) : (
37
+ <div className="flex h-full items-center justify-center bg-gradient-to-br from-gray-100 to-gray-200">
38
+ <span className="text-4xl text-gray-400">🏷️</span>
39
+ </div>
40
+ )}
41
+ </div>
42
+ <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
43
+ <div className="absolute bottom-0 left-0 right-0 p-4">
44
+ <h2 className="font-bold text-white">{category.name}</h2>
45
+ {category.productCount > 0 && (
46
+ <p className="text-sm text-white/80">
47
+ {category.productCount}{" "}
48
+ {category.productCount === 1 ? "product" : "products"}
49
+ </p>
50
+ )}
51
+ </div>
52
+ </Link>
53
+ ))
54
+ )}
55
+ </div>
56
+ </div>
57
+ );
58
+ }
@@ -0,0 +1,351 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import Link from 'next/link';
5
+
6
+ interface CheckoutForm {
7
+ email: string;
8
+ firstName: string;
9
+ lastName: string;
10
+ address: string;
11
+ city: string;
12
+ postalCode: string;
13
+ country: string;
14
+ phone: string;
15
+ }
16
+
17
+ export default function CheckoutPage() {
18
+ const [step, setStep] = useState<'shipping' | 'payment' | 'confirmation'>('shipping');
19
+ const [form, setForm] = useState<CheckoutForm>({
20
+ email: '',
21
+ firstName: '',
22
+ lastName: '',
23
+ address: '',
24
+ city: '',
25
+ postalCode: '',
26
+ country: 'PL',
27
+ phone: '',
28
+ });
29
+
30
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
31
+ const { name, value } = e.target;
32
+ setForm((prev) => ({ ...prev, [name]: value }));
33
+ };
34
+
35
+ const handleSubmit = async (e: React.FormEvent) => {
36
+ e.preventDefault();
37
+ if (step === 'shipping') {
38
+ setStep('payment');
39
+ } else if (step === 'payment') {
40
+ // Process payment
41
+ setStep('confirmation');
42
+ }
43
+ };
44
+
45
+ // Order summary (placeholder)
46
+ const orderSummary = {
47
+ subtotal: 9999,
48
+ shipping: 999,
49
+ total: 10998,
50
+ items: 1,
51
+ };
52
+
53
+ if (step === 'confirmation') {
54
+ return (
55
+ <div className="container mx-auto px-4 py-16 text-center">
56
+ <div className="mx-auto max-w-md">
57
+ <div className="mb-6 text-6xl">✅</div>
58
+ <h1 className="mb-4 text-3xl font-bold text-gray-900">
59
+ Order Confirmed!
60
+ </h1>
61
+ <p className="mb-8 text-gray-600">
62
+ Thank you for your order. We&apos;ve sent a confirmation email to{' '}
63
+ <strong>{form.email}</strong>.
64
+ </p>
65
+ <p className="mb-8 text-sm text-gray-500">
66
+ Order #: ORD-{Date.now().toString(36).toUpperCase()}
67
+ </p>
68
+ <Link href="/products" className="btn btn-primary">
69
+ Continue Shopping
70
+ </Link>
71
+ </div>
72
+ </div>
73
+ );
74
+ }
75
+
76
+ return (
77
+ <div className="container mx-auto px-4 py-8">
78
+ <h1 className="mb-8 text-3xl font-bold text-gray-900">Checkout</h1>
79
+
80
+ {/* Progress Steps */}
81
+ <div className="mb-8 flex items-center justify-center gap-4">
82
+ <div className={`flex items-center gap-2 ${step === 'shipping' ? 'text-primary' : 'text-gray-400'}`}>
83
+ <span className="flex h-8 w-8 items-center justify-center rounded-full border-2 border-current">
84
+ 1
85
+ </span>
86
+ <span className="font-medium">Shipping</span>
87
+ </div>
88
+ <div className="h-px w-12 bg-gray-300" />
89
+ <div className={`flex items-center gap-2 ${step === 'payment' ? 'text-primary' : 'text-gray-400'}`}>
90
+ <span className="flex h-8 w-8 items-center justify-center rounded-full border-2 border-current">
91
+ 2
92
+ </span>
93
+ <span className="font-medium">Payment</span>
94
+ </div>
95
+ </div>
96
+
97
+ <div className="grid gap-8 lg:grid-cols-3">
98
+ {/* Form */}
99
+ <div className="lg:col-span-2">
100
+ <form onSubmit={handleSubmit} className="card">
101
+ {step === 'shipping' && (
102
+ <>
103
+ <h2 className="mb-6 text-lg font-semibold text-gray-900">
104
+ Shipping Information
105
+ </h2>
106
+
107
+ <div className="space-y-4">
108
+ <div>
109
+ <label className="mb-1 block text-sm font-medium text-gray-700">
110
+ Email
111
+ </label>
112
+ <input
113
+ type="email"
114
+ name="email"
115
+ value={form.email}
116
+ onChange={handleInputChange}
117
+ className="input"
118
+ required
119
+ />
120
+ </div>
121
+
122
+ <div className="grid gap-4 sm:grid-cols-2">
123
+ <div>
124
+ <label className="mb-1 block text-sm font-medium text-gray-700">
125
+ First Name
126
+ </label>
127
+ <input
128
+ type="text"
129
+ name="firstName"
130
+ value={form.firstName}
131
+ onChange={handleInputChange}
132
+ className="input"
133
+ required
134
+ />
135
+ </div>
136
+ <div>
137
+ <label className="mb-1 block text-sm font-medium text-gray-700">
138
+ Last Name
139
+ </label>
140
+ <input
141
+ type="text"
142
+ name="lastName"
143
+ value={form.lastName}
144
+ onChange={handleInputChange}
145
+ className="input"
146
+ required
147
+ />
148
+ </div>
149
+ </div>
150
+
151
+ <div>
152
+ <label className="mb-1 block text-sm font-medium text-gray-700">
153
+ Address
154
+ </label>
155
+ <input
156
+ type="text"
157
+ name="address"
158
+ value={form.address}
159
+ onChange={handleInputChange}
160
+ className="input"
161
+ required
162
+ />
163
+ </div>
164
+
165
+ <div className="grid gap-4 sm:grid-cols-3">
166
+ <div>
167
+ <label className="mb-1 block text-sm font-medium text-gray-700">
168
+ City
169
+ </label>
170
+ <input
171
+ type="text"
172
+ name="city"
173
+ value={form.city}
174
+ onChange={handleInputChange}
175
+ className="input"
176
+ required
177
+ />
178
+ </div>
179
+ <div>
180
+ <label className="mb-1 block text-sm font-medium text-gray-700">
181
+ Postal Code
182
+ </label>
183
+ <input
184
+ type="text"
185
+ name="postalCode"
186
+ value={form.postalCode}
187
+ onChange={handleInputChange}
188
+ className="input"
189
+ required
190
+ />
191
+ </div>
192
+ <div>
193
+ <label className="mb-1 block text-sm font-medium text-gray-700">
194
+ Country
195
+ </label>
196
+ <select
197
+ name="country"
198
+ value={form.country}
199
+ onChange={handleInputChange}
200
+ className="input"
201
+ required
202
+ >
203
+ <option value="PL">Poland</option>
204
+ <option value="DE">Germany</option>
205
+ <option value="GB">United Kingdom</option>
206
+ <option value="US">United States</option>
207
+ </select>
208
+ </div>
209
+ </div>
210
+
211
+ <div>
212
+ <label className="mb-1 block text-sm font-medium text-gray-700">
213
+ Phone
214
+ </label>
215
+ <input
216
+ type="tel"
217
+ name="phone"
218
+ value={form.phone}
219
+ onChange={handleInputChange}
220
+ className="input"
221
+ />
222
+ </div>
223
+ </div>
224
+
225
+ <button type="submit" className="btn btn-primary mt-6 w-full">
226
+ Continue to Payment
227
+ </button>
228
+ </>
229
+ )}
230
+
231
+ {step === 'payment' && (
232
+ <>
233
+ <h2 className="mb-6 text-lg font-semibold text-gray-900">
234
+ Payment Method
235
+ </h2>
236
+
237
+ <div className="space-y-4">
238
+ <div className="rounded-lg border border-primary bg-primary/5 p-4">
239
+ <label className="flex items-center gap-3">
240
+ <input
241
+ type="radio"
242
+ name="paymentMethod"
243
+ value="card"
244
+ defaultChecked
245
+ className="h-4 w-4 text-primary"
246
+ />
247
+ <span className="font-medium">Credit/Debit Card</span>
248
+ </label>
249
+ <div className="mt-4 space-y-4 pl-7">
250
+ <div>
251
+ <label className="mb-1 block text-sm font-medium text-gray-700">
252
+ Card Number
253
+ </label>
254
+ <input
255
+ type="text"
256
+ placeholder="1234 5678 9012 3456"
257
+ className="input"
258
+ />
259
+ </div>
260
+ <div className="grid gap-4 sm:grid-cols-2">
261
+ <div>
262
+ <label className="mb-1 block text-sm font-medium text-gray-700">
263
+ Expiry Date
264
+ </label>
265
+ <input
266
+ type="text"
267
+ placeholder="MM/YY"
268
+ className="input"
269
+ />
270
+ </div>
271
+ <div>
272
+ <label className="mb-1 block text-sm font-medium text-gray-700">
273
+ CVV
274
+ </label>
275
+ <input
276
+ type="text"
277
+ placeholder="123"
278
+ className="input"
279
+ />
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </div>
284
+
285
+ <div className="rounded-lg border border-gray-200 p-4">
286
+ <label className="flex items-center gap-3">
287
+ <input
288
+ type="radio"
289
+ name="paymentMethod"
290
+ value="blik"
291
+ className="h-4 w-4 text-primary"
292
+ />
293
+ <span className="font-medium">BLIK</span>
294
+ </label>
295
+ </div>
296
+ </div>
297
+
298
+ <div className="mt-6 flex gap-4">
299
+ <button
300
+ type="button"
301
+ onClick={() => setStep('shipping')}
302
+ className="btn btn-outline flex-1"
303
+ >
304
+ Back
305
+ </button>
306
+ <button type="submit" className="btn btn-primary flex-1">
307
+ Place Order
308
+ </button>
309
+ </div>
310
+ </>
311
+ )}
312
+ </form>
313
+ </div>
314
+
315
+ {/* Order Summary */}
316
+ <div className="lg:col-span-1">
317
+ <div className="card sticky top-24">
318
+ <h2 className="mb-4 text-lg font-semibold text-gray-900">
319
+ Order Summary
320
+ </h2>
321
+
322
+ <div className="space-y-3 text-sm">
323
+ <div className="flex justify-between">
324
+ <span className="text-gray-600">
325
+ Items ({orderSummary.items})
326
+ </span>
327
+ <span className="text-gray-900">
328
+ ${(orderSummary.subtotal / 100).toFixed(2)}
329
+ </span>
330
+ </div>
331
+ <div className="flex justify-between">
332
+ <span className="text-gray-600">Shipping</span>
333
+ <span className="text-gray-900">
334
+ ${(orderSummary.shipping / 100).toFixed(2)}
335
+ </span>
336
+ </div>
337
+ <div className="border-t border-gray-200 pt-3">
338
+ <div className="flex justify-between font-semibold">
339
+ <span className="text-gray-900">Total</span>
340
+ <span className="text-primary">
341
+ ${(orderSummary.total / 100).toFixed(2)}
342
+ </span>
343
+ </div>
344
+ </div>
345
+ </div>
346
+ </div>
347
+ </div>
348
+ </div>
349
+ </div>
350
+ );
351
+ }
@@ -0,0 +1,158 @@
1
+ import Link from "next/link";
2
+ import { notFound } from "next/navigation";
3
+ import {
4
+ useCollection,
5
+ useProducts,
6
+ } from "@doswiftly/commerce-sdk/graphql/server";
7
+ import { Pagination } from "@/components/commerce/pagination";
8
+
9
+ interface CollectionPageProps {
10
+ params: Promise<{ slug: string }>;
11
+ searchParams: Promise<{ after?: string; before?: string }>;
12
+ }
13
+
14
+ export default async function CollectionPage({
15
+ params,
16
+ searchParams,
17
+ }: CollectionPageProps) {
18
+ const { slug } = await params;
19
+ const { after, before } = await searchParams;
20
+
21
+ // Fetch collection details using handle
22
+ const collectionData = await useCollection({ handle: slug });
23
+ const collection = collectionData.collection;
24
+
25
+ if (!collection) {
26
+ notFound();
27
+ }
28
+
29
+ // Fetch products for this collection using query filter
30
+ const { products, pageInfo } = await useProducts({
31
+ first: 12,
32
+ after,
33
+ query: `collection:${collection.handle}`, // Filter by collection handle
34
+ });
35
+
36
+ return (
37
+ <div className="container mx-auto px-4 py-8">
38
+ {/* Breadcrumb */}
39
+ <nav className="mb-4 text-sm">
40
+ <ol className="flex items-center gap-2">
41
+ <li>
42
+ <Link href="/" className="text-gray-500 hover:text-gray-700">
43
+ Home
44
+ </Link>
45
+ </li>
46
+ <li className="text-gray-400">/</li>
47
+ <li>
48
+ <Link
49
+ href="/collections"
50
+ className="text-gray-500 hover:text-gray-700"
51
+ >
52
+ Collections
53
+ </Link>
54
+ </li>
55
+ <li className="text-gray-400">/</li>
56
+ <li className="text-gray-900">{collection.title}</li>
57
+ </ol>
58
+ </nav>
59
+
60
+ {/* Collection Header */}
61
+ <div className="mb-8">
62
+ {collection.image?.url && (
63
+ <div className="relative mb-6 aspect-[21/9] overflow-hidden rounded-lg">
64
+ <img
65
+ src={collection.image.url}
66
+ alt={collection.image.altText || collection.title}
67
+ className="h-full w-full object-cover"
68
+ />
69
+ <div className="absolute inset-0 bg-black/30" />
70
+ <div className="absolute inset-0 flex flex-col items-center justify-center text-white">
71
+ <h1 className="text-4xl font-bold">{collection.title}</h1>
72
+ {collection.description && (
73
+ <p className="mt-2 max-w-2xl text-center text-lg text-white/90">
74
+ {collection.description}
75
+ </p>
76
+ )}
77
+ </div>
78
+ </div>
79
+ )}
80
+ {!collection.image?.url && (
81
+ <div className="mb-6">
82
+ <h1 className="text-3xl font-bold text-gray-900">
83
+ {collection.title}
84
+ </h1>
85
+ {collection.description && (
86
+ <p className="mt-2 text-gray-600">{collection.description}</p>
87
+ )}
88
+ </div>
89
+ )}
90
+ </div>
91
+
92
+ {/* Products Grid */}
93
+ <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 lg:gap-6">
94
+ {products.length === 0 ? (
95
+ <div className="col-span-full py-12 text-center text-gray-500">
96
+ No products in this collection
97
+ </div>
98
+ ) : (
99
+ products.map((product) => {
100
+ const price = product.priceRange?.minVariantPrice;
101
+ const compareAtPrice = product.compareAtPriceRange?.minVariantPrice;
102
+ const hasDiscount =
103
+ compareAtPrice &&
104
+ price &&
105
+ parseFloat(compareAtPrice.amount) > parseFloat(price.amount);
106
+
107
+ return (
108
+ <Link
109
+ key={product.id}
110
+ href={`/products/${product.handle}`}
111
+ className="group"
112
+ >
113
+ <div className="relative aspect-square overflow-hidden rounded-lg bg-gray-100">
114
+ {product.featuredImage?.url ? (
115
+ <img
116
+ src={product.featuredImage.url}
117
+ alt={product.featuredImage.altText || product.title}
118
+ className="h-full w-full object-cover transition group-hover:scale-105"
119
+ />
120
+ ) : (
121
+ <div className="flex h-full items-center justify-center">
122
+ <span className="text-4xl text-gray-400">📷</span>
123
+ </div>
124
+ )}
125
+ </div>
126
+ <div className="mt-3">
127
+ <h3 className="text-sm font-medium text-gray-900 group-hover:text-gray-700">
128
+ {product.title}
129
+ </h3>
130
+ {price && (
131
+ <div className="mt-1 flex items-center gap-2">
132
+ <span className="text-sm font-medium text-gray-900">
133
+ {price.currencyCode} {price.amount}
134
+ </span>
135
+ {hasDiscount && compareAtPrice && (
136
+ <span className="text-sm text-gray-500 line-through">
137
+ {compareAtPrice.currencyCode} {compareAtPrice.amount}
138
+ </span>
139
+ )}
140
+ </div>
141
+ )}
142
+ </div>
143
+ </Link>
144
+ );
145
+ })
146
+ )}
147
+ </div>
148
+
149
+ {/* Pagination */}
150
+ <Pagination
151
+ hasMore={pageInfo.hasNextPage}
152
+ endCursor={pageInfo.endCursor}
153
+ currentCursor={after}
154
+ totalShown={products.length}
155
+ />
156
+ </div>
157
+ );
158
+ }
@@ -0,0 +1,61 @@
1
+ import Link from "next/link";
2
+ import { useCollections } from "@doswiftly/commerce-sdk/graphql/server";
3
+
4
+ export default async function CollectionsPage() {
5
+ // Fetch all collections
6
+ const { collections } = await useCollections({ first: 50 });
7
+
8
+ return (
9
+ <div className="container mx-auto px-4 py-8">
10
+ {/* Page Header */}
11
+ <div className="mb-8">
12
+ <h1 className="text-3xl font-bold text-gray-900">Collections</h1>
13
+ <p className="mt-2 text-gray-600">
14
+ Browse our curated product collections
15
+ </p>
16
+ </div>
17
+
18
+ {/* Collections Grid */}
19
+ <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
20
+ {collections.length === 0 ? (
21
+ <div className="col-span-full py-12 text-center text-gray-500">
22
+ No collections found
23
+ </div>
24
+ ) : (
25
+ collections.map((collection) => (
26
+ <Link
27
+ key={collection.id}
28
+ href={`/collections/${collection.handle}`}
29
+ className="group relative overflow-hidden rounded-lg"
30
+ >
31
+ <div className="aspect-[4/3] bg-gray-100">
32
+ {collection.image?.url ? (
33
+ <img
34
+ src={collection.image.url}
35
+ alt={collection.image.altText || collection.title}
36
+ className="h-full w-full object-cover transition group-hover:scale-105"
37
+ />
38
+ ) : (
39
+ <div className="flex h-full items-center justify-center bg-gradient-to-br from-gray-100 to-gray-200">
40
+ <span className="text-4xl text-gray-400">📦</span>
41
+ </div>
42
+ )}
43
+ </div>
44
+ <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
45
+ <div className="absolute bottom-0 left-0 right-0 p-6">
46
+ <h2 className="text-xl font-bold text-white">
47
+ {collection.title}
48
+ </h2>
49
+ {collection.description && (
50
+ <p className="mt-1 line-clamp-2 text-sm text-white/80">
51
+ {collection.description}
52
+ </p>
53
+ )}
54
+ </div>
55
+ </Link>
56
+ ))
57
+ )}
58
+ </div>
59
+ </div>
60
+ );
61
+ }