@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,256 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { useSearchParams } from "next/navigation";
5
+ import { CheckCircle, Package, Mail, ArrowRight, Clock, Building2, Copy, Check } from "lucide-react";
6
+ import Link from "next/link";
7
+ import { Button } from "@/components/ui/button";
8
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
9
+ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
10
+ import { toast } from "sonner";
11
+
12
+ interface OrderSuccessPageProps {
13
+ params: Promise<{ orderId: string }>;
14
+ }
15
+
16
+ export default function OrderSuccessPage({ params }: OrderSuccessPageProps) {
17
+ const [orderId, setOrderId] = useState<string>("");
18
+ const [copied, setCopied] = useState(false);
19
+ const searchParams = useSearchParams();
20
+
21
+ // Get payment type from URL params
22
+ const paymentType = searchParams.get("payment");
23
+ const isBankTransfer = paymentType === "bank_transfer";
24
+ const isPendingPayment = searchParams.get("status") === "pending";
25
+
26
+ useEffect(() => {
27
+ params.then(({ orderId }) => setOrderId(orderId));
28
+ }, [params]);
29
+
30
+ const copyToClipboard = async (text: string) => {
31
+ try {
32
+ await navigator.clipboard.writeText(text);
33
+ setCopied(true);
34
+ toast.success("Skopiowano do schowka");
35
+ setTimeout(() => setCopied(false), 2000);
36
+ } catch {
37
+ toast.error("Nie udało się skopiować");
38
+ }
39
+ };
40
+
41
+ // Mock bank transfer details - in production, these would come from backend
42
+ const bankTransferDetails = {
43
+ bankName: "Bank XYZ",
44
+ accountNumber: "PL12 3456 7890 1234 5678 9012 3456",
45
+ recipientName: "DoSwiftly Sp. z o.o.",
46
+ transferTitle: `Zamówienie ${orderId}`,
47
+ amount: "---", // Would be fetched from order
48
+ };
49
+
50
+ return (
51
+ <div className="container mx-auto px-4 py-16">
52
+ <div className="mx-auto max-w-2xl text-center">
53
+ {/* Success Icon */}
54
+ <div className="mb-6 flex justify-center">
55
+ <div className={`rounded-full p-4 ${isPendingPayment ? "bg-yellow-100" : "bg-green-100"}`}>
56
+ {isPendingPayment ? (
57
+ <Clock className="h-12 w-12 text-yellow-600" />
58
+ ) : (
59
+ <CheckCircle className="h-12 w-12 text-green-600" />
60
+ )}
61
+ </div>
62
+ </div>
63
+
64
+ {/* Heading */}
65
+ <h1 className="mb-2 text-3xl font-bold">
66
+ {isPendingPayment ? "Zamówienie oczekuje na płatność" : "Dziękujemy za zamówienie!"}
67
+ </h1>
68
+ <p className="mb-8 text-muted-foreground">
69
+ {isPendingPayment
70
+ ? "Po otrzymaniu płatności rozpoczniemy realizację zamówienia."
71
+ : "Twoje zamówienie zostało potwierdzone i wkrótce zostanie wysłane."}
72
+ </p>
73
+
74
+ {/* Order Number */}
75
+ <Card className="mb-8">
76
+ <CardHeader>
77
+ <CardTitle className="text-lg">Potwierdzenie zamówienia</CardTitle>
78
+ </CardHeader>
79
+ <CardContent>
80
+ <div className="space-y-4">
81
+ <div className="flex items-center justify-between border-b pb-4">
82
+ <span className="text-muted-foreground">Numer zamówienia</span>
83
+ <span className="font-mono font-medium">{orderId || "..."}</span>
84
+ </div>
85
+
86
+ <div className="grid gap-4 sm:grid-cols-2">
87
+ <div className="flex items-start gap-3">
88
+ <Mail className="mt-1 h-5 w-5 text-muted-foreground" />
89
+ <div className="text-left">
90
+ <p className="font-medium">Email potwierdzający</p>
91
+ <p className="text-sm text-muted-foreground">
92
+ Wysłaliśmy potwierdzenie ze szczegółami zamówienia.
93
+ </p>
94
+ </div>
95
+ </div>
96
+
97
+ <div className="flex items-start gap-3">
98
+ <Package className="mt-1 h-5 w-5 text-muted-foreground" />
99
+ <div className="text-left">
100
+ <p className="font-medium">Śledzenie przesyłki</p>
101
+ <p className="text-sm text-muted-foreground">
102
+ Otrzymasz numer śledzenia, gdy paczka zostanie wysłana.
103
+ </p>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ </CardContent>
109
+ </Card>
110
+
111
+ {/* Bank Transfer Instructions */}
112
+ {isBankTransfer && (
113
+ <Alert className="mb-8 text-left">
114
+ <Building2 className="h-4 w-4" />
115
+ <AlertTitle>Dane do przelewu bankowego</AlertTitle>
116
+ <AlertDescription className="mt-4 space-y-3">
117
+ <div className="grid gap-3">
118
+ <div className="flex items-center justify-between">
119
+ <span className="text-sm text-muted-foreground">Bank</span>
120
+ <span className="font-medium">{bankTransferDetails.bankName}</span>
121
+ </div>
122
+ <div className="flex items-center justify-between gap-2">
123
+ <span className="text-sm text-muted-foreground">Numer konta</span>
124
+ <div className="flex items-center gap-2">
125
+ <span className="font-mono text-sm">{bankTransferDetails.accountNumber}</span>
126
+ <Button
127
+ variant="ghost"
128
+ size="icon"
129
+ className="h-6 w-6"
130
+ onClick={() => copyToClipboard(bankTransferDetails.accountNumber)}
131
+ >
132
+ {copied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
133
+ </Button>
134
+ </div>
135
+ </div>
136
+ <div className="flex items-center justify-between">
137
+ <span className="text-sm text-muted-foreground">Odbiorca</span>
138
+ <span className="font-medium">{bankTransferDetails.recipientName}</span>
139
+ </div>
140
+ <div className="flex items-center justify-between gap-2">
141
+ <span className="text-sm text-muted-foreground">Tytuł przelewu</span>
142
+ <div className="flex items-center gap-2">
143
+ <span className="font-medium">{bankTransferDetails.transferTitle}</span>
144
+ <Button
145
+ variant="ghost"
146
+ size="icon"
147
+ className="h-6 w-6"
148
+ onClick={() => copyToClipboard(bankTransferDetails.transferTitle)}
149
+ >
150
+ {copied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
151
+ </Button>
152
+ </div>
153
+ </div>
154
+ </div>
155
+ <p className="mt-4 text-sm text-muted-foreground">
156
+ Realizacja zamówienia rozpocznie się po zaksięgowaniu wpłaty (zazwyczaj 1-2 dni robocze).
157
+ </p>
158
+ </AlertDescription>
159
+ </Alert>
160
+ )}
161
+
162
+ {/* What's Next */}
163
+ <Card className="mb-8">
164
+ <CardHeader>
165
+ <CardTitle className="text-lg">Co dalej?</CardTitle>
166
+ </CardHeader>
167
+ <CardContent>
168
+ <ol className="space-y-3 text-left">
169
+ {isBankTransfer ? (
170
+ <>
171
+ <li className="flex items-start gap-3">
172
+ <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-xs font-medium text-primary-foreground">
173
+ 1
174
+ </span>
175
+ <div>
176
+ <p className="font-medium">Wykonaj przelew</p>
177
+ <p className="text-sm text-muted-foreground">
178
+ Prześlij płatność na podane powyżej konto bankowe.
179
+ </p>
180
+ </div>
181
+ </li>
182
+ <li className="flex items-start gap-3">
183
+ <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground">
184
+ 2
185
+ </span>
186
+ <div>
187
+ <p className="font-medium">Potwierdzenie płatności</p>
188
+ <p className="text-sm text-muted-foreground">
189
+ Po zaksięgowaniu wpłaty otrzymasz email z potwierdzeniem.
190
+ </p>
191
+ </div>
192
+ </li>
193
+ </>
194
+ ) : (
195
+ <li className="flex items-start gap-3">
196
+ <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary text-xs font-medium text-primary-foreground">
197
+ 1
198
+ </span>
199
+ <div>
200
+ <p className="font-medium">Przetwarzanie zamówienia</p>
201
+ <p className="text-sm text-muted-foreground">
202
+ Przygotowujemy Twoje zamówienie do wysyłki.
203
+ </p>
204
+ </div>
205
+ </li>
206
+ )}
207
+ <li className="flex items-start gap-3">
208
+ <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground">
209
+ {isBankTransfer ? 3 : 2}
210
+ </span>
211
+ <div>
212
+ <p className="font-medium">Wysyłka</p>
213
+ <p className="text-sm text-muted-foreground">
214
+ Po wysłaniu otrzymasz email z numerem śledzenia przesyłki.
215
+ </p>
216
+ </div>
217
+ </li>
218
+ <li className="flex items-start gap-3">
219
+ <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground">
220
+ {isBankTransfer ? 4 : 3}
221
+ </span>
222
+ <div>
223
+ <p className="font-medium">Dostawa</p>
224
+ <p className="text-sm text-muted-foreground">
225
+ Paczka zostanie dostarczona pod wskazany adres.
226
+ </p>
227
+ </div>
228
+ </li>
229
+ </ol>
230
+ </CardContent>
231
+ </Card>
232
+
233
+ {/* Actions */}
234
+ <div className="flex flex-col gap-4 sm:flex-row sm:justify-center">
235
+ <Button asChild>
236
+ <Link href="/products">
237
+ Kontynuuj zakupy
238
+ <ArrowRight className="ml-2 h-4 w-4" />
239
+ </Link>
240
+ </Button>
241
+ <Button variant="outline" asChild>
242
+ <Link href="/account/orders">Moje zamówienia</Link>
243
+ </Button>
244
+ </div>
245
+
246
+ {/* Help */}
247
+ <p className="mt-8 text-sm text-muted-foreground">
248
+ Potrzebujesz pomocy?{" "}
249
+ <Link href="/contact" className="text-primary underline underline-offset-4">
250
+ Skontaktuj się z nami
251
+ </Link>
252
+ </p>
253
+ </div>
254
+ </div>
255
+ );
256
+ }
@@ -0,0 +1,74 @@
1
+ "use client";
2
+
3
+ import { useParams } from "next/navigation";
4
+ import { ProductGrid } from "@/components/product/product-grid";
5
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
6
+ import { Skeleton } from "@/components/ui/skeleton";
7
+ import { useCollection } from "@/lib/graphql/hooks";
8
+
9
+ export default function CollectionPage() {
10
+ const params = useParams();
11
+ const handle = params.handle as string;
12
+
13
+ // Fetch collection using GraphQL
14
+ const { data, isLoading, error } = useCollection(handle);
15
+
16
+ const collection = data?.collection;
17
+ const products = collection?.products?.edges?.map((edge: any) => edge.node) ?? [];
18
+
19
+ if (isLoading) {
20
+ return (
21
+ <div className="container mx-auto px-4 py-8">
22
+ <Breadcrumbs className="mb-6" />
23
+ <div className="mb-8">
24
+ <Skeleton className="h-10 w-64 mb-4" />
25
+ <Skeleton className="h-6 w-96" />
26
+ </div>
27
+ <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
28
+ {Array.from({ length: 8 }).map((_, i) => (
29
+ <Skeleton key={i} className="aspect-square w-full" />
30
+ ))}
31
+ </div>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ if (error || !collection) {
37
+ return (
38
+ <div className="container mx-auto px-4 py-8">
39
+ <Breadcrumbs className="mb-6" />
40
+ <div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
41
+ <h1 className="text-2xl font-bold text-foreground mb-2">
42
+ Collection Not Found
43
+ </h1>
44
+ <p className="text-muted-foreground">
45
+ The collection you're looking for doesn't exist.
46
+ </p>
47
+ </div>
48
+ </div>
49
+ );
50
+ }
51
+
52
+ return (
53
+ <div className="container mx-auto px-4 py-8">
54
+ <Breadcrumbs className="mb-6" />
55
+
56
+ {/* Collection Header */}
57
+ <div className="mb-8">
58
+ <h1 className="text-3xl font-bold text-foreground">{collection.title}</h1>
59
+ {collection.description && (
60
+ <p className="mt-2 text-muted-foreground">{collection.description}</p>
61
+ )}
62
+ </div>
63
+
64
+ {/* Products Grid */}
65
+ <ProductGrid
66
+ products={products}
67
+ columns={4}
68
+ priorityCount={8}
69
+ showBadges
70
+ emptyMessage="No products in this collection"
71
+ />
72
+ </div>
73
+ );
74
+ }
@@ -0,0 +1,75 @@
1
+ import { Metadata } from "next";
2
+ import Link from "next/link";
3
+ import { Card } from "@/components/ui/card";
4
+ import { fetchCollections } from "@/lib/graphql/server";
5
+
6
+ export const metadata: Metadata = {
7
+ title: "Collections",
8
+ description: "Browse our curated collections of products",
9
+ };
10
+
11
+ // Enable ISR with 60 second revalidation
12
+ export const revalidate = 60;
13
+
14
+ export default async function CollectionsPage() {
15
+ // Fetch collections from GraphQL API (already normalized to flat array)
16
+ const { collections } = await fetchCollections({ first: 20 });
17
+
18
+ // Defensive check for empty/undefined response
19
+ const collectionList = collections || [];
20
+
21
+ return (
22
+ <div className="container mx-auto px-4 py-8">
23
+ <div className="mb-8">
24
+ <h1 className="text-3xl font-bold text-foreground">Collections</h1>
25
+ <p className="mt-2 text-muted-foreground">
26
+ Browse our curated collections of products
27
+ </p>
28
+ </div>
29
+
30
+ {collectionList.length === 0 ? (
31
+ <div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
32
+ <p className="text-muted-foreground">No collections available yet</p>
33
+ </div>
34
+ ) : (
35
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
36
+ {collectionList.map((collection) => (
37
+ <Link
38
+ key={collection.id}
39
+ href={`/collections/${collection.handle}`}
40
+ className="group"
41
+ >
42
+ <Card className="overflow-hidden transition-shadow hover:shadow-lg">
43
+ <div className="aspect-video bg-muted relative overflow-hidden">
44
+ {collection.image?.url ? (
45
+ <img
46
+ src={collection.image.url}
47
+ alt={collection.image.altText || collection.title}
48
+ className="h-full w-full object-cover transition-transform group-hover:scale-105"
49
+ />
50
+ ) : (
51
+ <div className="flex h-full items-center justify-center text-muted-foreground">
52
+ <span className="text-4xl font-bold opacity-20">
53
+ {collection.title.charAt(0)}
54
+ </span>
55
+ </div>
56
+ )}
57
+ </div>
58
+ <div className="p-6">
59
+ <h2 className="text-xl font-semibold text-foreground group-hover:text-primary transition-colors">
60
+ {collection.title}
61
+ </h2>
62
+ {collection.description && (
63
+ <p className="mt-2 text-sm text-muted-foreground line-clamp-2">
64
+ {collection.description}
65
+ </p>
66
+ )}
67
+ </div>
68
+ </Card>
69
+ </Link>
70
+ ))}
71
+ </div>
72
+ )}
73
+ </div>
74
+ );
75
+ }
@@ -0,0 +1,114 @@
1
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
2
+ import { Mail, Phone, MapPin } from "lucide-react";
3
+ import { Button } from "@/components/ui/button";
4
+ import { Input } from "@/components/ui/input";
5
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
6
+
7
+ export default function ContactPage() {
8
+ return (
9
+ <div className="container mx-auto px-4 py-8">
10
+ <Breadcrumbs className="mb-6" />
11
+
12
+ <div className="mx-auto max-w-4xl">
13
+ <h1 className="mb-6 text-4xl font-bold text-foreground">Contact Us</h1>
14
+ <p className="mb-8 text-lg text-muted-foreground">
15
+ Have a question? We'd love to hear from you. Send us a message and we'll respond as soon as possible.
16
+ </p>
17
+
18
+ <div className="grid gap-8 md:grid-cols-3">
19
+ {/* Contact Info */}
20
+ <div className="space-y-6">
21
+ <Card>
22
+ <CardHeader>
23
+ <CardTitle className="flex items-center gap-2 text-base">
24
+ <Mail className="h-5 w-5" />
25
+ Email
26
+ </CardTitle>
27
+ </CardHeader>
28
+ <CardContent>
29
+ <p className="text-sm text-muted-foreground">
30
+ support@example.com
31
+ </p>
32
+ </CardContent>
33
+ </Card>
34
+
35
+ <Card>
36
+ <CardHeader>
37
+ <CardTitle className="flex items-center gap-2 text-base">
38
+ <Phone className="h-5 w-5" />
39
+ Phone
40
+ </CardTitle>
41
+ </CardHeader>
42
+ <CardContent>
43
+ <p className="text-sm text-muted-foreground">
44
+ +48 123 456 789
45
+ </p>
46
+ </CardContent>
47
+ </Card>
48
+
49
+ <Card>
50
+ <CardHeader>
51
+ <CardTitle className="flex items-center gap-2 text-base">
52
+ <MapPin className="h-5 w-5" />
53
+ Address
54
+ </CardTitle>
55
+ </CardHeader>
56
+ <CardContent>
57
+ <p className="text-sm text-muted-foreground">
58
+ 123 Main Street<br />
59
+ Warsaw, Poland
60
+ </p>
61
+ </CardContent>
62
+ </Card>
63
+ </div>
64
+
65
+ {/* Contact Form */}
66
+ <Card className="md:col-span-2">
67
+ <CardHeader>
68
+ <CardTitle>Send us a message</CardTitle>
69
+ </CardHeader>
70
+ <CardContent>
71
+ <form className="space-y-4">
72
+ <div className="grid gap-4 sm:grid-cols-2">
73
+ <div className="space-y-2">
74
+ <label htmlFor="name" className="text-sm font-medium">
75
+ Name
76
+ </label>
77
+ <Input id="name" placeholder="Your name" required />
78
+ </div>
79
+ <div className="space-y-2">
80
+ <label htmlFor="email" className="text-sm font-medium">
81
+ Email
82
+ </label>
83
+ <Input id="email" type="email" placeholder="your@email.com" required />
84
+ </div>
85
+ </div>
86
+ <div className="space-y-2">
87
+ <label htmlFor="subject" className="text-sm font-medium">
88
+ Subject
89
+ </label>
90
+ <Input id="subject" placeholder="How can we help?" required />
91
+ </div>
92
+ <div className="space-y-2">
93
+ <label htmlFor="message" className="text-sm font-medium">
94
+ Message
95
+ </label>
96
+ <textarea
97
+ id="message"
98
+ rows={6}
99
+ className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
100
+ placeholder="Your message..."
101
+ required
102
+ />
103
+ </div>
104
+ <Button type="submit" className="w-full">
105
+ Send Message
106
+ </Button>
107
+ </form>
108
+ </CardContent>
109
+ </Card>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ );
114
+ }
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Error Page - Global error handling for runtime errors
5
+ *
6
+ * Displays when an unhandled error occurs in the application.
7
+ * Provides retry and navigation options.
8
+ *
9
+ * Requirements: 11.1
10
+ */
11
+
12
+ import { useEffect } from 'react';
13
+ import Link from 'next/link';
14
+ import { AlertTriangle, RefreshCcw, Home, ShoppingBag } from 'lucide-react';
15
+ import { Button } from '@/components/ui/button';
16
+ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
17
+
18
+ interface ErrorPageProps {
19
+ error: Error & { digest?: string };
20
+ reset: () => void;
21
+ }
22
+
23
+ export default function ErrorPage({ error, reset }: ErrorPageProps) {
24
+ useEffect(() => {
25
+ // Log error to console in development
26
+ if (process.env.NODE_ENV === 'development') {
27
+ console.error('[Error Page]', error);
28
+ }
29
+ // TODO: Log error to error tracking service (e.g., Sentry)
30
+ }, [error]);
31
+
32
+ return (
33
+ <div className="container mx-auto flex min-h-[60vh] items-center justify-center px-4 py-16">
34
+ <Card className="w-full max-w-md text-center">
35
+ <CardHeader>
36
+ <div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-destructive/10">
37
+ <AlertTriangle className="h-8 w-8 text-destructive" />
38
+ </div>
39
+ <CardTitle className="text-2xl">Wystąpił błąd</CardTitle>
40
+ <CardDescription className="text-base">
41
+ Przepraszamy, wystąpił nieoczekiwany problem. Spróbuj odświeżyć stronę lub wróć do strony głównej.
42
+ </CardDescription>
43
+ </CardHeader>
44
+ <CardContent className="space-y-4">
45
+ {/* Error details in development */}
46
+ {process.env.NODE_ENV === 'development' && (
47
+ <div className="rounded-md bg-muted p-3 text-left text-xs">
48
+ <p className="font-medium text-destructive">{error.message}</p>
49
+ {error.digest && (
50
+ <p className="mt-1 text-muted-foreground">Digest: {error.digest}</p>
51
+ )}
52
+ </div>
53
+ )}
54
+
55
+ {/* Action buttons */}
56
+ <div className="flex flex-col gap-3">
57
+ <Button onClick={reset} className="w-full">
58
+ <RefreshCcw className="mr-2 h-4 w-4" />
59
+ Spróbuj ponownie
60
+ </Button>
61
+
62
+ <div className="flex gap-3">
63
+ <Button variant="outline" asChild className="flex-1">
64
+ <Link href="/">
65
+ <Home className="mr-2 h-4 w-4" />
66
+ Strona główna
67
+ </Link>
68
+ </Button>
69
+ <Button variant="outline" asChild className="flex-1">
70
+ <Link href="/products">
71
+ <ShoppingBag className="mr-2 h-4 w-4" />
72
+ Produkty
73
+ </Link>
74
+ </Button>
75
+ </div>
76
+ </div>
77
+
78
+ {/* Help text */}
79
+ <p className="text-sm text-muted-foreground">
80
+ Jeśli problem się powtarza,{' '}
81
+ <Link href="/contact" className="text-primary underline underline-offset-4">
82
+ skontaktuj się z nami
83
+ </Link>
84
+ .
85
+ </p>
86
+ </CardContent>
87
+ </Card>
88
+ </div>
89
+ );
90
+ }