@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,159 @@
1
+ /**
2
+ * Blog Listing Page
3
+ *
4
+ * Lists all published blog posts with filtering and pagination.
5
+ */
6
+
7
+ import { Suspense } from 'react';
8
+ import { Metadata } from 'next';
9
+ import { BookOpen } from 'lucide-react';
10
+ import { Breadcrumbs } from '@/components/layout/breadcrumbs';
11
+ import { Skeleton } from '@/components/ui/skeleton';
12
+ import { BlogCard } from '@/components/blog/blog-card';
13
+ import { BlogSidebar } from '@/components/blog/blog-sidebar';
14
+
15
+ export const metadata: Metadata = {
16
+ title: 'Blog',
17
+ description: 'Przeczytaj nasze najnowsze artykuły i poradniki.',
18
+ };
19
+
20
+ // Mock data - replace with actual GraphQL fetch
21
+ const mockPosts = [
22
+ {
23
+ id: '1',
24
+ title: 'Jak wybrać idealny produkt dla siebie',
25
+ slug: 'jak-wybrac-idealny-produkt',
26
+ excerpt: 'Praktyczny poradnik, który pomoże Ci podjąć najlepszą decyzję zakupową.',
27
+ featuredImage: null,
28
+ author: {
29
+ id: '1',
30
+ name: 'Jan Kowalski',
31
+ avatar: null,
32
+ },
33
+ category: {
34
+ id: '1',
35
+ name: 'Poradniki',
36
+ slug: 'poradniki',
37
+ },
38
+ publishedAt: '2024-01-15T10:00:00Z',
39
+ readingTime: 5,
40
+ viewCount: 120,
41
+ isFeatured: true,
42
+ },
43
+ {
44
+ id: '2',
45
+ title: 'Trendy na rok 2024',
46
+ slug: 'trendy-2024',
47
+ excerpt: 'Odkryj, co będzie modne w nadchodzącym roku.',
48
+ featuredImage: null,
49
+ author: {
50
+ id: '1',
51
+ name: 'Jan Kowalski',
52
+ avatar: null,
53
+ },
54
+ category: {
55
+ id: '2',
56
+ name: 'Trendy',
57
+ slug: 'trendy',
58
+ },
59
+ publishedAt: '2024-01-10T10:00:00Z',
60
+ readingTime: 8,
61
+ viewCount: 250,
62
+ isFeatured: false,
63
+ },
64
+ ];
65
+
66
+ const mockCategories = [
67
+ { id: '1', name: 'Poradniki', slug: 'poradniki', postCount: 12 },
68
+ { id: '2', name: 'Trendy', slug: 'trendy', postCount: 8 },
69
+ { id: '3', name: 'Nowości', slug: 'nowosci', postCount: 15 },
70
+ ];
71
+
72
+ const mockTags = [
73
+ { id: '1', name: 'Tips', slug: 'tips', postCount: 5 },
74
+ { id: '2', name: 'Tutorial', slug: 'tutorial', postCount: 3 },
75
+ { id: '3', name: 'News', slug: 'news', postCount: 7 },
76
+ ];
77
+
78
+ export default function BlogPage() {
79
+ const posts = mockPosts;
80
+ const categories = mockCategories;
81
+ const tags = mockTags;
82
+ const featuredPost = posts.find((p) => p.isFeatured);
83
+ const regularPosts = posts.filter((p) => !p.isFeatured);
84
+
85
+ return (
86
+ <div className="container py-8">
87
+ <Breadcrumbs
88
+ items={[
89
+ { label: 'Strona główna', href: '/' },
90
+ { label: 'Blog' },
91
+ ]}
92
+ />
93
+
94
+ <div className="mt-6 mb-8">
95
+ <h1 className="text-3xl font-bold tracking-tight flex items-center gap-3">
96
+ <BookOpen className="h-8 w-8" />
97
+ Blog
98
+ </h1>
99
+ <p className="text-muted-foreground mt-2">
100
+ Najnowsze artykuły, poradniki i aktualności
101
+ </p>
102
+ </div>
103
+
104
+ <div className="grid grid-cols-1 lg:grid-cols-4 gap-8">
105
+ {/* Main Content */}
106
+ <div className="lg:col-span-3 space-y-8">
107
+ {/* Featured Post */}
108
+ {featuredPost && (
109
+ <section>
110
+ <h2 className="text-lg font-semibold mb-4">Wyróżniony artykuł</h2>
111
+ <BlogCard post={featuredPost} variant="featured" />
112
+ </section>
113
+ )}
114
+
115
+ {/* Recent Posts Grid */}
116
+ <section>
117
+ <h2 className="text-lg font-semibold mb-4">Ostatnie wpisy</h2>
118
+ {posts.length > 0 ? (
119
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
120
+ {regularPosts.map((post) => (
121
+ <BlogCard key={post.id} post={post} />
122
+ ))}
123
+ </div>
124
+ ) : (
125
+ <p className="text-muted-foreground text-center py-12">
126
+ Brak wpisów do wyświetlenia.
127
+ </p>
128
+ )}
129
+ </section>
130
+ </div>
131
+
132
+ {/* Sidebar */}
133
+ <div className="lg:col-span-1">
134
+ <BlogSidebar
135
+ categories={categories}
136
+ tags={tags}
137
+ recentPosts={posts.slice(0, 3)}
138
+ />
139
+ </div>
140
+ </div>
141
+ </div>
142
+ );
143
+ }
144
+
145
+ function BlogPostsSkeleton() {
146
+ return (
147
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
148
+ {Array.from({ length: 4 }).map((_, i) => (
149
+ <div key={i} className="space-y-4">
150
+ <Skeleton className="aspect-[16/10] w-full" />
151
+ <Skeleton className="h-4 w-20" />
152
+ <Skeleton className="h-6 w-full" />
153
+ <Skeleton className="h-4 w-full" />
154
+ <Skeleton className="h-4 w-2/3" />
155
+ </div>
156
+ ))}
157
+ </div>
158
+ );
159
+ }
@@ -0,0 +1,170 @@
1
+ "use client";
2
+
3
+ import { useParams } from "next/navigation";
4
+ import Image from "next/image";
5
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
6
+ import { BrandLogo } from "@/components/brand/brand-card";
7
+
8
+ export default function BrandDetailPage() {
9
+ const params = useParams();
10
+ const slug = params.slug as string;
11
+
12
+ // TODO: Fetch brand and products from backend using GraphQL
13
+ const brand = {
14
+ id: "1",
15
+ name: "Nike",
16
+ slug: "nike",
17
+ description:
18
+ "Nike, Inc. is an American multinational corporation that is engaged in the design, development, manufacturing, and worldwide marketing and sales of footwear, apparel, equipment, accessories, and services.",
19
+ logoUrl: "https://via.placeholder.com/400x200?text=Nike+Logo",
20
+ website: "https://www.nike.com",
21
+ founded: "1964",
22
+ headquarters: "Beaverton, Oregon, USA",
23
+ };
24
+
25
+ // TODO: Fetch products for this brand
26
+ const products = [
27
+ {
28
+ id: "1",
29
+ title: "Air Max 90",
30
+ handle: "air-max-90",
31
+ price: "499.99",
32
+ currency: "PLN",
33
+ imageUrl: "https://via.placeholder.com/300x300?text=Product+1",
34
+ },
35
+ {
36
+ id: "2",
37
+ title: "Air Force 1",
38
+ handle: "air-force-1",
39
+ price: "399.99",
40
+ currency: "PLN",
41
+ imageUrl: "https://via.placeholder.com/300x300?text=Product+2",
42
+ },
43
+ {
44
+ id: "3",
45
+ title: "React Infinity",
46
+ handle: "react-infinity",
47
+ price: "599.99",
48
+ currency: "PLN",
49
+ imageUrl: "https://via.placeholder.com/300x300?text=Product+3",
50
+ },
51
+ ];
52
+
53
+ return (
54
+ <div className="container mx-auto px-4 py-8">
55
+ <Breadcrumbs className="mb-6" />
56
+
57
+ {/* Brand Header */}
58
+ <div className="mb-12 rounded-lg border border-border bg-background p-8">
59
+ <div className="flex flex-col items-center gap-8 md:flex-row">
60
+ {/* Brand Logo */}
61
+ <div className="flex-shrink-0">
62
+ <div className="relative h-32 w-64 rounded-lg bg-muted p-4">
63
+ {brand.logoUrl ? (
64
+ <Image
65
+ src={brand.logoUrl}
66
+ alt={`${brand.name} logo`}
67
+ fill
68
+ className="object-contain"
69
+ sizes="256px"
70
+ />
71
+ ) : (
72
+ <div className="flex h-full items-center justify-center">
73
+ <span className="text-4xl font-bold text-muted-foreground">
74
+ {brand.name}
75
+ </span>
76
+ </div>
77
+ )}
78
+ </div>
79
+ </div>
80
+
81
+ {/* Brand Info */}
82
+ <div className="flex-1">
83
+ <h1 className="text-4xl font-bold text-foreground mb-4">
84
+ {brand.name}
85
+ </h1>
86
+ <p className="text-lg text-muted-foreground mb-6">
87
+ {brand.description}
88
+ </p>
89
+
90
+ <div className="grid gap-4 text-sm md:grid-cols-3">
91
+ {brand.founded && (
92
+ <div>
93
+ <span className="font-medium text-foreground">Founded:</span>
94
+ <p className="text-muted-foreground">{brand.founded}</p>
95
+ </div>
96
+ )}
97
+ {brand.headquarters && (
98
+ <div>
99
+ <span className="font-medium text-foreground">
100
+ Headquarters:
101
+ </span>
102
+ <p className="text-muted-foreground">{brand.headquarters}</p>
103
+ </div>
104
+ )}
105
+ {brand.website && (
106
+ <div>
107
+ <span className="font-medium text-foreground">Website:</span>
108
+ <a
109
+ href={brand.website}
110
+ target="_blank"
111
+ rel="noopener noreferrer"
112
+ className="text-primary hover:underline"
113
+ >
114
+ Visit Website
115
+ </a>
116
+ </div>
117
+ )}
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </div>
122
+
123
+ {/* Products Section */}
124
+ <div>
125
+ <h2 className="text-3xl font-bold text-foreground mb-6">
126
+ Products by {brand.name}
127
+ </h2>
128
+
129
+ {products.length === 0 ? (
130
+ <div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
131
+ <p className="text-muted-foreground">
132
+ No products available from this brand
133
+ </p>
134
+ </div>
135
+ ) : (
136
+ <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
137
+ {products.map((product) => (
138
+ <a
139
+ key={product.id}
140
+ href={`/products/${product.handle}`}
141
+ className="group rounded-lg border border-border bg-background overflow-hidden transition-shadow hover:shadow-lg"
142
+ >
143
+ <div className="relative aspect-square overflow-hidden bg-muted">
144
+ <Image
145
+ src={product.imageUrl}
146
+ alt={product.title}
147
+ fill
148
+ className="object-cover transition-transform group-hover:scale-105"
149
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 25vw"
150
+ />
151
+ </div>
152
+ <div className="p-4">
153
+ <h3 className="font-semibold text-foreground group-hover:text-primary transition-colors">
154
+ {product.title}
155
+ </h3>
156
+ <p className="mt-2 text-lg font-bold text-foreground">
157
+ {new Intl.NumberFormat("pl-PL", {
158
+ style: "currency",
159
+ currency: product.currency,
160
+ }).format(parseFloat(product.price))}
161
+ </p>
162
+ </div>
163
+ </a>
164
+ ))}
165
+ </div>
166
+ )}
167
+ </div>
168
+ </div>
169
+ );
170
+ }
@@ -0,0 +1,73 @@
1
+ "use client";
2
+
3
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
4
+ import { BrandGrid, type BrandCardProps } from "@/components/brand/brand-grid";
5
+
6
+ export default function BrandsPage() {
7
+ // TODO: Fetch brands from backend using GraphQL
8
+ const brands: BrandCardProps[] = [
9
+ {
10
+ id: "1",
11
+ name: "Nike",
12
+ slug: "nike",
13
+ description: "Just Do It - Athletic footwear and apparel",
14
+ logoUrl: "https://via.placeholder.com/200x200?text=Nike",
15
+ productCount: 156,
16
+ },
17
+ {
18
+ id: "2",
19
+ name: "Adidas",
20
+ slug: "adidas",
21
+ description: "Impossible is Nothing - Sports equipment and clothing",
22
+ logoUrl: "https://via.placeholder.com/200x200?text=Adidas",
23
+ productCount: 142,
24
+ },
25
+ {
26
+ id: "3",
27
+ name: "Apple",
28
+ slug: "apple",
29
+ description: "Think Different - Consumer electronics and software",
30
+ logoUrl: "https://via.placeholder.com/200x200?text=Apple",
31
+ productCount: 89,
32
+ },
33
+ {
34
+ id: "4",
35
+ name: "Samsung",
36
+ slug: "samsung",
37
+ description: "Inspire the World, Create the Future",
38
+ logoUrl: "https://via.placeholder.com/200x200?text=Samsung",
39
+ productCount: 124,
40
+ },
41
+ {
42
+ id: "5",
43
+ name: "Sony",
44
+ slug: "sony",
45
+ description: "Be Moved - Electronics and entertainment",
46
+ logoUrl: "https://via.placeholder.com/200x200?text=Sony",
47
+ productCount: 98,
48
+ },
49
+ {
50
+ id: "6",
51
+ name: "Microsoft",
52
+ slug: "microsoft",
53
+ description: "Empowering us all - Software and hardware",
54
+ logoUrl: "https://via.placeholder.com/200x200?text=Microsoft",
55
+ productCount: 67,
56
+ },
57
+ ];
58
+
59
+ return (
60
+ <div className="container mx-auto px-4 py-8">
61
+ <Breadcrumbs className="mb-6" />
62
+
63
+ <div className="mb-8">
64
+ <h1 className="text-4xl font-bold text-foreground">All Brands</h1>
65
+ <p className="mt-2 text-lg text-muted-foreground">
66
+ Shop by your favorite brands
67
+ </p>
68
+ </div>
69
+
70
+ <BrandGrid brands={brands} />
71
+ </div>
72
+ );
73
+ }
@@ -0,0 +1,165 @@
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+ import { useCartStore } from "@/stores/cart-store";
5
+ import { useCartSync } from "@/hooks/use-cart-sync";
6
+ import { useCartActions } from "@/hooks/use-cart-actions";
7
+ import { useCartDiscountCodesUpdate } from "@/lib/graphql/hooks";
8
+ import { CartItem } from "@/components/cart/cart-item";
9
+ import { CartSummary } from "@/components/cart/cart-summary";
10
+ import { PromoCodeInput } from "@/components/cart/promo-code-input";
11
+ import { EmptyCart } from "@/components/ui/empty-state";
12
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
13
+ import { Button } from "@/components/ui/button";
14
+ import { ArrowLeft, Loader2 } from "lucide-react";
15
+
16
+ export default function CartPage() {
17
+ // Server cart data (source of truth)
18
+ const {
19
+ items,
20
+ totalQuantity,
21
+ subtotal,
22
+ total,
23
+ currency,
24
+ discountCodes,
25
+ totalDiscount,
26
+ isLoading,
27
+ } = useCartSync();
28
+
29
+ // Actions that mutate via GraphQL
30
+ const { updateQuantity, removeFromCart } = useCartActions();
31
+
32
+ // Discount mutation (with React Query cache invalidation)
33
+ const discountMutation = useCartDiscountCodesUpdate();
34
+
35
+ // Loading state
36
+ if (isLoading) {
37
+ return (
38
+ <div className="container mx-auto px-4 py-16">
39
+ <div className="flex items-center justify-center">
40
+ <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
41
+ </div>
42
+ </div>
43
+ );
44
+ }
45
+
46
+ const handleCheckout = () => {
47
+ window.location.href = "/checkout";
48
+ };
49
+
50
+ const handleApplyPromo = async (code: string) => {
51
+ try {
52
+ const cartId = useCartStore.getState().cartId;
53
+ if (!cartId) {
54
+ return { success: false, message: "Your cart is empty" };
55
+ }
56
+
57
+ const result = await discountMutation.mutateAsync({
58
+ cartId,
59
+ discountCodes: [...discountCodes, code],
60
+ });
61
+
62
+ const payload = result.cartDiscountCodesUpdate;
63
+
64
+ if (payload?.userErrors?.length > 0) {
65
+ return {
66
+ success: false,
67
+ message: payload.userErrors[0].message,
68
+ };
69
+ }
70
+
71
+ if (!payload?.cart) {
72
+ return {
73
+ success: false,
74
+ message: "Failed to apply promo code",
75
+ };
76
+ }
77
+
78
+ return { success: true, message: "Promo code applied!" };
79
+ } catch (error) {
80
+ return {
81
+ success: false,
82
+ message: "Failed to apply promo code",
83
+ };
84
+ }
85
+ };
86
+
87
+ const handleRemovePromo = async () => {
88
+ try {
89
+ const cartId = useCartStore.getState().cartId;
90
+ if (!cartId) return;
91
+
92
+ await discountMutation.mutateAsync({
93
+ cartId,
94
+ discountCodes: [],
95
+ });
96
+ } catch (error) {
97
+ // Silently handle — cart query will refetch and show correct state
98
+ }
99
+ };
100
+
101
+ if (items.length === 0) {
102
+ return (
103
+ <div className="container mx-auto px-4 py-16">
104
+ <EmptyCart onContinueShopping={() => (window.location.href = "/products")} />
105
+ </div>
106
+ );
107
+ }
108
+
109
+ const appliedCode = discountCodes.length > 0 ? discountCodes[0] : undefined;
110
+
111
+ return (
112
+ <div className="container mx-auto px-4 py-8">
113
+ <Breadcrumbs className="mb-6" />
114
+
115
+ <div className="mb-8 flex items-center justify-between">
116
+ <h1 className="text-3xl font-bold text-foreground">Shopping Cart</h1>
117
+ <Button variant="ghost" asChild>
118
+ <Link href="/products">
119
+ <ArrowLeft className="mr-2 h-4 w-4" />
120
+ Continue Shopping
121
+ </Link>
122
+ </Button>
123
+ </div>
124
+
125
+ <div className="grid gap-8 lg:grid-cols-3">
126
+ {/* Cart Items */}
127
+ <div className="lg:col-span-2">
128
+ <div className="divide-y divide-border rounded-lg border border-border">
129
+ {items.map((item) => (
130
+ <div key={item.lineId} className="p-4">
131
+ <CartItem
132
+ item={item}
133
+ onUpdateQuantity={updateQuantity}
134
+ onRemove={removeFromCart}
135
+ />
136
+ </div>
137
+ ))}
138
+ </div>
139
+ </div>
140
+
141
+ {/* Summary */}
142
+ <div className="lg:col-span-1">
143
+ <div className="sticky top-4 space-y-4 rounded-lg border border-border bg-muted/50 p-6">
144
+ <h2 className="text-lg font-semibold text-foreground">Order Summary</h2>
145
+
146
+ <PromoCodeInput
147
+ onApply={handleApplyPromo}
148
+ appliedCode={appliedCode}
149
+ onRemove={handleRemovePromo}
150
+ />
151
+
152
+ <CartSummary
153
+ subtotal={subtotal}
154
+ total={total}
155
+ totalDiscount={totalDiscount}
156
+ currencyCode={currency}
157
+ itemCount={totalQuantity}
158
+ onCheckout={handleCheckout}
159
+ />
160
+ </div>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ );
165
+ }
@@ -0,0 +1,78 @@
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 { useProducts } from "@/lib/graphql/hooks";
8
+
9
+ export default function CategoryPage() {
10
+ const params = useParams();
11
+ const slug = params.slug as string;
12
+
13
+ // Fetch products for this category using GraphQL query
14
+ const { data, isLoading, error } = useProducts({
15
+ first: 20,
16
+ query: `category:${slug}`,
17
+ });
18
+
19
+ const products = data?.products ?? [];
20
+
21
+ if (isLoading) {
22
+ return (
23
+ <div className="container mx-auto px-4 py-8">
24
+ <Breadcrumbs className="mb-6" />
25
+ <div className="mb-8">
26
+ <Skeleton className="h-10 w-64 mb-4" />
27
+ <Skeleton className="h-6 w-96" />
28
+ </div>
29
+ <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
30
+ {Array.from({ length: 8 }).map((_, i) => (
31
+ <Skeleton key={i} className="aspect-square w-full" />
32
+ ))}
33
+ </div>
34
+ </div>
35
+ );
36
+ }
37
+
38
+ if (error) {
39
+ return (
40
+ <div className="container mx-auto px-4 py-8">
41
+ <Breadcrumbs className="mb-6" />
42
+ <div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
43
+ <h1 className="text-2xl font-bold text-foreground mb-2">
44
+ Category Not Found
45
+ </h1>
46
+ <p className="text-muted-foreground">
47
+ The category you're looking for doesn't exist.
48
+ </p>
49
+ </div>
50
+ </div>
51
+ );
52
+ }
53
+
54
+ return (
55
+ <div className="container mx-auto px-4 py-8">
56
+ <Breadcrumbs className="mb-6" />
57
+
58
+ {/* Category Header */}
59
+ <div className="mb-8">
60
+ <h1 className="text-3xl font-bold text-foreground capitalize">
61
+ {slug.replace(/-/g, " ")}
62
+ </h1>
63
+ <p className="mt-2 text-muted-foreground">
64
+ Browse products in this category
65
+ </p>
66
+ </div>
67
+
68
+ {/* Products Grid */}
69
+ <ProductGrid
70
+ products={products}
71
+ columns={4}
72
+ priorityCount={8}
73
+ showBadges
74
+ emptyMessage="No products in this category"
75
+ />
76
+ </div>
77
+ );
78
+ }