@doswiftly/cli 0.1.18 → 0.1.20

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 (277) hide show
  1. package/README.md +23 -323
  2. package/dist/commands/check.js +1 -1
  3. package/dist/commands/check.js.map +1 -1
  4. package/dist/commands/deploy.d.ts +20 -0
  5. package/dist/commands/deploy.d.ts.map +1 -1
  6. package/dist/commands/deploy.js +249 -17
  7. package/dist/commands/deploy.js.map +1 -1
  8. package/dist/commands/doctor.js +3 -3
  9. package/dist/commands/doctor.js.map +1 -1
  10. package/dist/commands/init.js +4 -4
  11. package/dist/commands/sdk.js +5 -5
  12. package/dist/commands/sdk.js.map +1 -1
  13. package/dist/commands/template.js +4 -4
  14. package/dist/commands/template.js.map +1 -1
  15. package/dist/commands/types.js +5 -5
  16. package/dist/commands/types.js.map +1 -1
  17. package/dist/commands/verify.js +2 -2
  18. package/dist/commands/verify.js.map +1 -1
  19. package/dist/lib/package-manager.d.ts +1 -1
  20. package/dist/lib/package-manager.js +1 -1
  21. package/package.json +4 -4
  22. package/templates/storefront-minimal/.github/workflows/build-template.yml +10 -0
  23. package/templates/storefront-minimal/wrangler.toml +11 -0
  24. package/templates/storefront-nextjs/.github/workflows/build-template.yml +10 -0
  25. package/templates/storefront-nextjs/README.md +16 -12
  26. package/templates/storefront-nextjs/app/account/orders/page.tsx +2 -2
  27. package/templates/storefront-nextjs/app/account/page.tsx +2 -2
  28. package/templates/storefront-nextjs/app/auth/login/page.tsx +1 -1
  29. package/templates/storefront-nextjs/app/auth/register/page.tsx +1 -1
  30. package/templates/storefront-nextjs/app/cart/page.tsx +1 -1
  31. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +2 -2
  32. package/templates/storefront-nextjs/app/categories/page.tsx +1 -1
  33. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +1 -1
  34. package/templates/storefront-nextjs/app/collections/page.tsx +1 -1
  35. package/templates/storefront-nextjs/app/page.tsx +1 -1
  36. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +1 -1
  37. package/templates/storefront-nextjs/app/products/page.tsx +2 -2
  38. package/templates/storefront-nextjs/app/search/page.tsx +1 -1
  39. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +1 -1
  40. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +1 -1
  41. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +1 -1
  42. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +2 -2
  43. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +1 -1
  44. package/templates/storefront-nextjs/components/commerce/product-price.tsx +1 -1
  45. package/templates/storefront-nextjs/components/commerce/search-input.tsx +1 -1
  46. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +1 -1
  47. package/templates/storefront-nextjs/components/providers.tsx +1 -1
  48. package/templates/storefront-nextjs/lib/currency.tsx +3 -3
  49. package/templates/storefront-nextjs/lib/format.ts +1 -1
  50. package/templates/storefront-nextjs/lib/graphql-queries.ts +3 -3
  51. package/templates/storefront-nextjs/package.dev.json +1 -1
  52. package/templates/storefront-nextjs/package.json +1 -1
  53. package/templates/storefront-nextjs/package.json.template +1 -1
  54. package/templates/storefront-nextjs/wrangler.toml +11 -0
  55. package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +10 -0
  56. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +47 -0
  57. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +47 -0
  58. package/templates/storefront-nextjs-shadcn/CLAUDE.md +172 -35
  59. package/templates/storefront-nextjs-shadcn/README.md +29 -162
  60. package/templates/storefront-nextjs-shadcn/app/{about → [locale]/about}/page.tsx +17 -14
  61. package/templates/storefront-nextjs-shadcn/app/[locale]/account/addresses/page.tsx +226 -0
  62. package/templates/storefront-nextjs-shadcn/app/[locale]/account/error.tsx +46 -0
  63. package/templates/storefront-nextjs-shadcn/app/[locale]/account/loading.tsx +19 -0
  64. package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/loyalty/page.tsx +89 -193
  65. package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/[id]/loading.tsx +60 -0
  66. package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/[id]/page.tsx +119 -0
  67. package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/[id]/tracking/page.tsx +27 -25
  68. package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/page.tsx +101 -0
  69. package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/page.tsx +9 -7
  70. package/templates/storefront-nextjs-shadcn/app/[locale]/account/settings/page.tsx +208 -0
  71. package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/forgot-password/page.tsx +24 -17
  72. package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/login/page.tsx +5 -2
  73. package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/register/page.tsx +5 -2
  74. package/templates/storefront-nextjs-shadcn/app/[locale]/blog/[slug]/loading.tsx +17 -0
  75. package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/[slug]/page.tsx +44 -3
  76. package/templates/storefront-nextjs-shadcn/app/[locale]/blog/loading.tsx +19 -0
  77. package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/page.tsx +2 -1
  78. package/templates/storefront-nextjs-shadcn/app/[locale]/cart/loading.tsx +26 -0
  79. package/templates/storefront-nextjs-shadcn/app/{cart → [locale]/cart}/page.tsx +20 -13
  80. package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/category-products-client.tsx +58 -0
  81. package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/loading.tsx +32 -0
  82. package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/page.tsx +95 -0
  83. package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/page.tsx +21 -12
  84. package/templates/storefront-nextjs-shadcn/app/[locale]/checkout/error.tsx +43 -0
  85. package/templates/storefront-nextjs-shadcn/app/[locale]/checkout/loading.tsx +31 -0
  86. package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/page.tsx +334 -253
  87. package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/success/[orderId]/page.tsx +36 -34
  88. package/templates/storefront-nextjs-shadcn/app/[locale]/collections/[handle]/loading.tsx +19 -0
  89. package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/[handle]/page.tsx +6 -4
  90. package/templates/storefront-nextjs-shadcn/app/[locale]/collections/loading.tsx +18 -0
  91. package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/page.tsx +20 -12
  92. package/templates/storefront-nextjs-shadcn/app/{contact → [locale]/contact}/page.tsx +24 -21
  93. package/templates/storefront-nextjs-shadcn/app/{error.tsx → [locale]/error.tsx} +13 -8
  94. package/templates/storefront-nextjs-shadcn/app/[locale]/layout.tsx +92 -0
  95. package/templates/storefront-nextjs-shadcn/app/{not-found.tsx → [locale]/not-found.tsx} +13 -18
  96. package/templates/storefront-nextjs-shadcn/app/{page.tsx → [locale]/page.tsx} +8 -4
  97. package/templates/storefront-nextjs-shadcn/app/[locale]/products/[slug]/error.tsx +43 -0
  98. package/templates/storefront-nextjs-shadcn/app/[locale]/products/[slug]/loading.tsx +29 -0
  99. package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/page.tsx +17 -14
  100. package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/product-client.tsx +18 -62
  101. package/templates/storefront-nextjs-shadcn/app/[locale]/products/loading.tsx +32 -0
  102. package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/page.tsx +6 -3
  103. package/templates/storefront-nextjs-shadcn/app/[locale]/products/products-client.tsx +450 -0
  104. package/templates/storefront-nextjs-shadcn/app/[locale]/search/loading.tsx +18 -0
  105. package/templates/storefront-nextjs-shadcn/app/{wishlist → [locale]/wishlist}/page.tsx +27 -28
  106. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +2 -86
  107. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +2 -124
  108. package/templates/storefront-nextjs-shadcn/app/global-error.tsx +117 -0
  109. package/templates/storefront-nextjs-shadcn/app/globals.css +8 -0
  110. package/templates/storefront-nextjs-shadcn/app/layout.tsx +8 -35
  111. package/templates/storefront-nextjs-shadcn/codegen.ts +48 -31
  112. package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +25 -20
  113. package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +11 -10
  114. package/templates/storefront-nextjs-shadcn/components/account/customer-info.fragment.graphql +36 -0
  115. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +17 -13
  116. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +42 -30
  117. package/templates/storefront-nextjs-shadcn/components/account/order-summary.fragment.graphql +36 -0
  118. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +18 -16
  119. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +37 -58
  120. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +85 -66
  121. package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +1 -1
  122. package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +1 -1
  123. package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +1 -1
  124. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +10 -6
  125. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +9 -6
  126. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +8 -6
  127. package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +53 -0
  128. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +10 -8
  129. package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +8 -5
  130. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +38 -20
  131. package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +15 -25
  132. package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +10 -8
  133. package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +9 -6
  134. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +7 -5
  135. package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +8 -5
  136. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +6 -4
  137. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +10 -9
  138. package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +1 -1
  139. package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +1 -1
  140. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +35 -11
  141. package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +9 -6
  142. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +22 -12
  143. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +18 -15
  144. package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +53 -28
  145. package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +7 -5
  146. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +5 -5
  147. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +19 -15
  148. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +13 -10
  149. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +10 -6
  150. package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +21 -0
  151. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +3 -13
  152. package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +12 -8
  153. package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +13 -8
  154. package/templates/storefront-nextjs-shadcn/components/home/index.ts +0 -1
  155. package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +10 -8
  156. package/templates/storefront-nextjs-shadcn/components/hydrated.tsx +24 -0
  157. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +41 -16
  158. package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +22 -0
  159. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +7 -4
  160. package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +24 -23
  161. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +52 -34
  162. package/templates/storefront-nextjs-shadcn/components/layout/language-switcher.tsx +54 -0
  163. package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +33 -30
  164. package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +27 -24
  165. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +2 -11
  166. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +8 -25
  167. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +32 -42
  168. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +17 -41
  169. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +2 -29
  170. package/templates/storefront-nextjs-shadcn/components/order/index.ts +6 -1
  171. package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +6 -14
  172. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +4 -2
  173. package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +72 -0
  174. package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +87 -0
  175. package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +140 -0
  176. package/templates/storefront-nextjs-shadcn/components/product/index.ts +9 -2
  177. package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +49 -0
  178. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +11 -37
  179. package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +52 -0
  180. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +179 -124
  181. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +3 -5
  182. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +3 -7
  183. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +2 -2
  184. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +5 -4
  185. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +44 -19
  186. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +8 -23
  187. package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +51 -0
  188. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +1 -1
  189. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +26 -34
  190. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +17 -2
  191. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +3 -2
  192. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +1 -1
  193. package/templates/storefront-nextjs-shadcn/components/providers/language-sync-provider.tsx +27 -0
  194. package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +63 -0
  195. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +1 -1
  196. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +2 -2
  197. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +59 -72
  198. package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +7 -4
  199. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +3 -2
  200. package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +12 -9
  201. package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +23 -12
  202. package/templates/storefront-nextjs-shadcn/components/ui/form.tsx +174 -0
  203. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +30 -2
  204. package/templates/storefront-nextjs-shadcn/components/ui/progress.tsx +40 -0
  205. package/templates/storefront-nextjs-shadcn/components/ui/sheet.tsx +107 -0
  206. package/templates/storefront-nextjs-shadcn/components/ui/slider.tsx +33 -0
  207. package/templates/storefront-nextjs-shadcn/components/ui/textarea.tsx +24 -0
  208. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +7 -4
  209. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +4 -2
  210. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +2 -10
  211. package/templates/storefront-nextjs-shadcn/generated/graphql.ts +13387 -0
  212. package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +159 -0
  213. package/templates/storefront-nextjs-shadcn/hooks/index.ts +3 -0
  214. package/templates/storefront-nextjs-shadcn/hooks/use-auth-sync.ts +42 -0
  215. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +17 -295
  216. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +34 -229
  217. package/templates/storefront-nextjs-shadcn/hooks/use-cart-di.ts +67 -0
  218. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +16 -12
  219. package/templates/storefront-nextjs-shadcn/i18n/navigation.ts +12 -0
  220. package/templates/storefront-nextjs-shadcn/i18n/request.ts +17 -0
  221. package/templates/storefront-nextjs-shadcn/i18n/routing.ts +17 -0
  222. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +4 -17
  223. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +22 -99
  224. package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +33 -0
  225. package/templates/storefront-nextjs-shadcn/lib/graphql/fragments.ts +34 -0
  226. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +720 -632
  227. package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +88 -0
  228. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +132 -182
  229. package/templates/storefront-nextjs-shadcn/lib/graphql/types.ts +62 -0
  230. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +0 -17
  231. package/templates/storefront-nextjs-shadcn/messages/en.json +869 -0
  232. package/templates/storefront-nextjs-shadcn/messages/pl.json +869 -0
  233. package/templates/storefront-nextjs-shadcn/next-env.d.ts +6 -0
  234. package/templates/storefront-nextjs-shadcn/next.config.ts +6 -5
  235. package/templates/storefront-nextjs-shadcn/package.dev.json +1 -3
  236. package/templates/storefront-nextjs-shadcn/package.json +14 -14
  237. package/templates/storefront-nextjs-shadcn/package.json.template +6 -7
  238. package/templates/storefront-nextjs-shadcn/proxy.ts +115 -47
  239. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +24 -56
  240. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +64 -75
  241. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +178 -177
  242. package/templates/storefront-nextjs-shadcn/tsconfig.json +23 -5
  243. package/templates/storefront-nextjs-shadcn/wrangler.toml +11 -0
  244. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +0 -282
  245. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +0 -190
  246. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +0 -263
  247. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +0 -135
  248. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +0 -142
  249. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +0 -448
  250. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +0 -307
  251. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +0 -245
  252. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +0 -215
  253. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +0 -128
  254. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +0 -80
  255. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +0 -171
  256. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +0 -78
  257. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +0 -192
  258. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +0 -103
  259. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +0 -168
  260. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +0 -160
  261. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +0 -220
  262. package/templates/storefront-nextjs-shadcn/lib/config.ts +0 -46
  263. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +0 -254
  264. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +0 -464
  265. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +0 -328
  266. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +0 -295
  267. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +0 -27
  268. package/templates/storefront-nextjs-shadcn/lib/format.ts +0 -226
  269. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +0 -30
  270. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +0 -66
  271. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +0 -103
  272. /package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/page.tsx +0 -0
  273. /package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/[slug]/page.tsx +0 -0
  274. /package/templates/storefront-nextjs-shadcn/app/{returns → [locale]/returns}/page.tsx +0 -0
  275. /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/page.tsx +0 -0
  276. /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/search-client.tsx +0 -0
  277. /package/templates/storefront-nextjs-shadcn/app/{shipping → [locale]/shipping}/page.tsx +0 -0
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
 
3
- import Link from "next/link";
4
- import { usePathname } from "next/navigation";
3
+ import { useTranslations } from "next-intl";
4
+ import { Link, usePathname } from "@/i18n/navigation";
5
5
  import { ChevronRight, Home } from "lucide-react";
6
6
  import { cn } from "@/lib/utils";
7
7
 
8
8
  export interface BreadcrumbItem {
9
9
  label: string;
10
- href: string;
10
+ href?: string;
11
11
  }
12
12
 
13
13
  export interface BreadcrumbsProps {
@@ -31,15 +31,33 @@ export interface BreadcrumbsProps {
31
31
  * { label: "Laptops", href: "/products/electronics/laptops" }
32
32
  * ]} />
33
33
  */
34
+ // Known segment keys that exist in nav translations
35
+ const SEGMENT_TRANSLATION_KEYS: Record<string, string> = {
36
+ products: "products",
37
+ collections: "collections",
38
+ categories: "categories",
39
+ about: "about",
40
+ brands: "brands",
41
+ blog: "blog",
42
+ cart: "cart",
43
+ account: "account",
44
+ contact: "contact",
45
+ shipping: "shipping",
46
+ returns: "returns",
47
+ search: "searchBreadcrumb",
48
+ wishlist: "wishlist",
49
+ };
50
+
34
51
  export function Breadcrumbs({
35
52
  items,
36
53
  className,
37
54
  showHome = true,
38
55
  }: BreadcrumbsProps) {
56
+ const t = useTranslations("nav");
39
57
  const pathname = usePathname();
40
58
 
41
59
  // Auto-generate breadcrumbs from pathname if items not provided
42
- const breadcrumbItems = items || generateBreadcrumbs(pathname);
60
+ const breadcrumbItems = items || generateBreadcrumbs(pathname, t);
43
61
 
44
62
  // Don't show breadcrumbs on homepage
45
63
  if (pathname === "/" || breadcrumbItems.length === 0) {
@@ -48,7 +66,7 @@ export function Breadcrumbs({
48
66
 
49
67
  return (
50
68
  <nav
51
- aria-label="Breadcrumb"
69
+ aria-label={t("breadcrumb")}
52
70
  className={cn("flex items-center gap-2 text-sm", className)}
53
71
  >
54
72
  <ol className="flex items-center gap-2">
@@ -57,7 +75,7 @@ export function Breadcrumbs({
57
75
  <Link
58
76
  href="/"
59
77
  className="flex items-center text-muted-foreground hover:text-foreground transition-colors"
60
- aria-label="Home"
78
+ aria-label={t("home")}
61
79
  >
62
80
  <Home className="h-4 w-4" />
63
81
  </Link>
@@ -68,7 +86,7 @@ export function Breadcrumbs({
68
86
  const isLast = index === breadcrumbItems.length - 1;
69
87
 
70
88
  return (
71
- <li key={item.href} className="flex items-center gap-2">
89
+ <li key={item.href || `breadcrumb-${index}`} className="flex items-center gap-2">
72
90
  {(showHome || index > 0) && (
73
91
  <ChevronRight
74
92
  className="h-4 w-4 text-muted-foreground"
@@ -76,10 +94,10 @@ export function Breadcrumbs({
76
94
  />
77
95
  )}
78
96
 
79
- {isLast ? (
97
+ {isLast || !item.href ? (
80
98
  <span
81
99
  className="font-medium text-foreground"
82
- aria-current="page"
100
+ aria-current={isLast ? "page" : undefined}
83
101
  >
84
102
  {item.label}
85
103
  </span>
@@ -101,20 +119,27 @@ export function Breadcrumbs({
101
119
 
102
120
  /**
103
121
  * Generate breadcrumb items from pathname
122
+ * Uses translations for known segments, falls back to capitalized segment name
104
123
  */
105
- function generateBreadcrumbs(pathname: string): BreadcrumbItem[] {
124
+ function generateBreadcrumbs(
125
+ pathname: string,
126
+ t: (key: string) => string,
127
+ ): BreadcrumbItem[] {
106
128
  const segments = pathname.split("/").filter(Boolean);
107
129
  const breadcrumbs: BreadcrumbItem[] = [];
108
130
 
109
131
  let currentPath = "";
110
132
  for (const segment of segments) {
111
133
  currentPath += `/${segment}`;
112
-
113
- // Format label: remove hyphens, capitalize words
114
- const label = segment
115
- .split("-")
116
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
117
- .join(" ");
134
+
135
+ // Use translation for known segments, fallback to capitalized segment
136
+ const translationKey = SEGMENT_TRANSLATION_KEYS[segment];
137
+ const label = translationKey
138
+ ? t(translationKey)
139
+ : segment
140
+ .split("-")
141
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
142
+ .join(" ");
118
143
 
119
144
  breadcrumbs.push({
120
145
  label,
@@ -0,0 +1,22 @@
1
+ # Fragment for CategoryCard / CategoryNav components.
2
+ #
3
+ # Category data for navigation, sidebar filters, breadcrumbs.
4
+ #
5
+ # Usage in components:
6
+ # import type { CategoryNodeFieldsFragment } from '@/generated/graphql';
7
+ # interface Props { category: CategoryNodeFieldsFragment }
8
+
9
+ fragment CategoryNodeFields on Category {
10
+ id
11
+ name
12
+ slug
13
+ description
14
+ productCount
15
+ level
16
+ path
17
+ sortOrder
18
+ image {
19
+ url
20
+ altText
21
+ }
22
+ }
@@ -18,9 +18,10 @@
18
18
  */
19
19
 
20
20
  import { useState, useRef, useEffect } from 'react';
21
- import { useCurrencyStore } from '@/stores/currency-store';
21
+ import { useCurrencyStore } from '@doswiftly/storefront-sdk/react';
22
22
  import { useQueryClient } from '@tanstack/react-query';
23
23
  import { ChevronDown, Check, Globe } from 'lucide-react';
24
+ import { useTranslations } from 'next-intl';
24
25
 
25
26
  // ============================================================================
26
27
  // CURRENCY DATA
@@ -149,12 +150,14 @@ export function CurrencySelector({
149
150
  showIcon = true,
150
151
  variant = 'default',
151
152
  }: CurrencySelectorProps) {
153
+ const t = useTranslations("currency");
154
+
152
155
  // Currency store state
153
156
  const currency = useCurrencyStore((state) => state.currency);
154
157
  const supportedCurrencies = useCurrencyStore((state) => state.supportedCurrencies);
155
158
  const setCurrency = useCurrencyStore((state) => state.setCurrency);
156
159
  const isLoaded = useCurrencyStore((state) => state.isLoaded);
157
-
160
+
158
161
  // React Query client for cache invalidation
159
162
  const queryClient = useQueryClient();
160
163
 
@@ -261,7 +264,7 @@ export function CurrencySelector({
261
264
  `}
262
265
  aria-expanded={isOpen}
263
266
  aria-haspopup="listbox"
264
- aria-label="Select currency"
267
+ aria-label={t("selectCurrency")}
265
268
  >
266
269
  {showIcon && variant !== 'minimal' && (
267
270
  <Globe className="w-4 h-4 text-gray-400" aria-hidden="true" />
@@ -287,7 +290,7 @@ export function CurrencySelector({
287
290
  ${dropdownStyles[variant]}
288
291
  `}
289
292
  role="listbox"
290
- aria-label="Currency options"
293
+ aria-label={t("currencyOptions")}
291
294
  >
292
295
  <div className="py-1 max-h-64 overflow-y-auto">
293
296
  {supportedCurrencies.map((code) => {
@@ -1,8 +1,11 @@
1
- import Link from "next/link";
1
+ import { Link } from "@/i18n/navigation";
2
+ import { getTranslations } from "next-intl/server";
2
3
 
3
- export function Footer() {
4
+ export async function Footer() {
4
5
  const currentYear = new Date().getFullYear();
5
6
  const siteName = process.env.NEXT_PUBLIC_SITE_NAME || "My Store";
7
+ const t = await getTranslations("footer");
8
+ const tc = await getTranslations("common");
6
9
 
7
10
  return (
8
11
  <footer className="border-t border-border bg-muted/50">
@@ -14,33 +17,32 @@ export function Footer() {
14
17
  {siteName}
15
18
  </Link>
16
19
  <p className="mt-4 text-sm text-muted-foreground">
17
- Quality products at affordable prices. Powered by DoSwiftly
18
- Commerce.
20
+ {t("description")}
19
21
  </p>
20
22
  </div>
21
23
 
22
24
  {/* Shop */}
23
25
  <div>
24
- <h3 className="mb-4 font-semibold text-foreground">Shop</h3>
26
+ <h3 className="mb-4 font-semibold text-foreground">{t("shop")}</h3>
25
27
  <ul className="space-y-2 text-sm text-muted-foreground">
26
28
  <li>
27
29
  <Link href="/products" className="hover:text-primary transition-colors">
28
- All Products
30
+ {t("allProducts")}
29
31
  </Link>
30
32
  </li>
31
33
  <li>
32
34
  <Link href="/collections" className="hover:text-primary transition-colors">
33
- Collections
35
+ {t("collections")}
34
36
  </Link>
35
37
  </li>
36
38
  <li>
37
39
  <Link href="/categories" className="hover:text-primary transition-colors">
38
- Categories
40
+ {t("categories")}
39
41
  </Link>
40
42
  </li>
41
43
  <li>
42
44
  <Link href="/search" className="hover:text-primary transition-colors">
43
- Search
45
+ {tc("search")}
44
46
  </Link>
45
47
  </li>
46
48
  </ul>
@@ -48,31 +50,31 @@ export function Footer() {
48
50
 
49
51
  {/* Account */}
50
52
  <div>
51
- <h3 className="mb-4 font-semibold text-foreground">Account</h3>
53
+ <h3 className="mb-4 font-semibold text-foreground">{t("myAccount")}</h3>
52
54
  <ul className="space-y-2 text-sm text-muted-foreground">
53
55
  <li>
54
56
  <Link href="/auth/login" className="hover:text-primary transition-colors">
55
- Sign In
57
+ {t("signIn")}
56
58
  </Link>
57
59
  </li>
58
60
  <li>
59
61
  <Link href="/auth/register" className="hover:text-primary transition-colors">
60
- Create Account
62
+ {t("createAccount")}
61
63
  </Link>
62
64
  </li>
63
65
  <li>
64
66
  <Link href="/account" className="hover:text-primary transition-colors">
65
- My Account
67
+ {t("myAccount")}
66
68
  </Link>
67
69
  </li>
68
70
  <li>
69
71
  <Link href="/account/orders" className="hover:text-primary transition-colors">
70
- Order History
72
+ {t("orderHistory")}
71
73
  </Link>
72
74
  </li>
73
75
  <li>
74
76
  <Link href="/cart" className="hover:text-primary transition-colors">
75
- Shopping Cart
77
+ {t("shoppingCart")}
76
78
  </Link>
77
79
  </li>
78
80
  </ul>
@@ -80,26 +82,26 @@ export function Footer() {
80
82
 
81
83
  {/* Support */}
82
84
  <div>
83
- <h3 className="mb-4 font-semibold text-foreground">Support</h3>
85
+ <h3 className="mb-4 font-semibold text-foreground">{t("support")}</h3>
84
86
  <ul className="space-y-2 text-sm text-muted-foreground">
85
87
  <li>
86
88
  <Link href="/contact" className="hover:text-primary transition-colors">
87
- Contact Us
89
+ {t("contactUs")}
88
90
  </Link>
89
91
  </li>
90
92
  <li>
91
93
  <Link href="/about" className="hover:text-primary transition-colors">
92
- About Us
94
+ {t("aboutUs")}
93
95
  </Link>
94
96
  </li>
95
97
  <li>
96
98
  <Link href="/shipping" className="hover:text-primary transition-colors">
97
- Shipping Info
99
+ {t("shippingInfo")}
98
100
  </Link>
99
101
  </li>
100
102
  <li>
101
103
  <Link href="/returns" className="hover:text-primary transition-colors">
102
- Returns & Refunds
104
+ {t("returnsRefunds")}
103
105
  </Link>
104
106
  </li>
105
107
  </ul>
@@ -108,17 +110,16 @@ export function Footer() {
108
110
 
109
111
  <div className="mt-12 border-t border-border pt-8 text-center text-sm text-muted-foreground">
110
112
  <p>
111
- © {currentYear} {siteName}. All rights reserved.
113
+ © {currentYear} {siteName}. {t("allRightsReserved")}.
112
114
  </p>
113
115
  <p className="mt-2">
114
- Powered by{" "}
115
116
  <a
116
117
  href="https://doswiftly.pl"
117
118
  target="_blank"
118
119
  rel="noopener noreferrer"
119
120
  className="text-primary hover:underline transition-colors"
120
121
  >
121
- DoSwiftly Commerce
122
+ {t("poweredBy")}
122
123
  </a>
123
124
  </p>
124
125
  </div>
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
- import Link from "next/link";
4
3
  import { useState } from "react";
4
+ import { useTranslations } from "next-intl";
5
+ import { Link } from "@/i18n/navigation";
5
6
  import { Menu, X } from "lucide-react";
6
7
  import { CurrencySelector } from "@/components/commerce/currency-selector";
7
8
  import { CartIcon } from "@/components/cart/cart-icon";
@@ -9,32 +10,42 @@ import { SearchInput } from "@/components/commerce/search-input";
9
10
  import { Navigation } from "@/components/layout/navigation";
10
11
  import { AccountMenu } from "@/components/auth/account-menu";
11
12
  import { ThemeSwitcher } from "@/components/layout/theme-switcher";
12
- import { useAuthStore } from "@/stores/auth-store";
13
+ import { LanguageSwitcher } from "@/components/layout/language-switcher";
14
+ import { useAuthStore, useAuthHydrated } from "@doswiftly/storefront-sdk/react";
15
+ import { useHydrated } from "@doswiftly/storefront-sdk/react";
16
+ import { useAuthSync } from "@/hooks/use-auth-sync";
13
17
 
14
18
  export function Header() {
19
+ const t = useTranslations("nav");
15
20
  const [isMenuOpen, setIsMenuOpen] = useState(false);
16
-
17
- // Get authentication state from auth store
21
+
22
+ // Auto-fix cookie/store desync (e.g., localStorage cleared but cookie persists)
23
+ useAuthSync();
24
+
25
+ // Double-guard: DOM must be mounted (useHydrated) AND store must be rehydrated (useAuthHydrated from Zustand persist)
26
+ const hydrated = useHydrated();
18
27
  const { isAuthenticated, customer } = useAuthStore();
28
+ const authHydrated = useAuthHydrated();
29
+ const showAuth = hydrated && authHydrated;
19
30
  const customerName = customer
20
31
  ? `${customer.firstName || ""} ${customer.lastName || ""}`.trim() || customer.email
21
32
  : undefined;
22
33
 
23
34
  const navigationItems = [
24
35
  {
25
- label: "Products",
36
+ label: t("products"),
26
37
  href: "/products",
27
38
  },
28
39
  {
29
- label: "Collections",
40
+ label: t("collections"),
30
41
  href: "/collections",
31
42
  },
32
43
  {
33
- label: "Categories",
44
+ label: t("categories"),
34
45
  href: "/categories",
35
46
  },
36
47
  {
37
- label: "About",
48
+ label: t("about"),
38
49
  href: "/about",
39
50
  },
40
51
  ];
@@ -57,39 +68,46 @@ export function Header() {
57
68
  <div className="flex items-center gap-3">
58
69
  {/* Search */}
59
70
  <div className="hidden w-64 lg:block">
60
- <SearchInput placeholder="Search products..." />
71
+ <SearchInput placeholder={t("search")} />
72
+ </div>
73
+
74
+ {/* Language Switcher */}
75
+ <div className="hidden md:block">
76
+ <LanguageSwitcher />
61
77
  </div>
62
-
78
+
63
79
  {/* Currency Selector */}
64
80
  <div className="hidden md:block">
65
81
  <CurrencySelector variant="compact" />
66
82
  </div>
67
-
83
+
68
84
  {/* Theme Switcher */}
69
85
  <div className="hidden md:block">
70
86
  <ThemeSwitcher />
71
87
  </div>
72
-
73
- {/* Account Menu or Login Link */}
74
- {isAuthenticated ? (
75
- <AccountMenu customerName={customerName} />
76
- ) : (
77
- <Link
78
- href="/auth/login"
79
- className="hidden md:inline-flex items-center rounded-md px-3 py-2 text-sm font-medium text-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
80
- >
81
- Sign In
82
- </Link>
88
+
89
+ {/* Account Menu or Login Link — hidden until DOM + auth store hydrate */}
90
+ {showAuth && (
91
+ isAuthenticated ? (
92
+ <AccountMenu customerName={customerName} />
93
+ ) : (
94
+ <Link
95
+ href="/auth/login"
96
+ className="hidden md:inline-flex items-center rounded-md px-3 py-2 text-sm font-medium text-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
97
+ >
98
+ {t("signIn")}
99
+ </Link>
100
+ )
83
101
  )}
84
-
102
+
85
103
  {/* Cart Icon */}
86
104
  <CartIcon />
87
-
105
+
88
106
  {/* Mobile Menu Toggle */}
89
107
  <button
90
108
  className="p-2 text-foreground hover:text-primary md:hidden"
91
109
  onClick={() => setIsMenuOpen(!isMenuOpen)}
92
- aria-label="Toggle menu"
110
+ aria-label={t("menu")}
93
111
  aria-expanded={isMenuOpen}
94
112
  >
95
113
  {isMenuOpen ? (
@@ -107,15 +125,15 @@ export function Header() {
107
125
  <div className="flex flex-col gap-4">
108
126
  {/* Mobile Search */}
109
127
  <div className="lg:hidden">
110
- <SearchInput placeholder="Search products..." />
128
+ <SearchInput placeholder={t("search")} />
111
129
  </div>
112
-
113
- {/* Mobile Currency Selector */}
130
+
131
+ {/* Mobile Language & Currency */}
114
132
  <div className="flex items-center justify-between">
115
- <span className="text-sm font-medium text-muted-foreground">Currency</span>
133
+ <LanguageSwitcher />
116
134
  <CurrencySelector variant="compact" />
117
135
  </div>
118
-
136
+
119
137
  {/* Mobile Navigation Links */}
120
138
  {navigationItems.map((item) => (
121
139
  <Link
@@ -127,15 +145,15 @@ export function Header() {
127
145
  {item.label}
128
146
  </Link>
129
147
  ))}
130
-
131
- {/* Mobile Account Link */}
132
- {!isAuthenticated && (
148
+
149
+ {/* Mobile Account Link — guarded by showAuth */}
150
+ {showAuth && !isAuthenticated && (
133
151
  <Link
134
152
  href="/auth/login"
135
153
  className="text-foreground hover:text-primary transition-colors font-medium"
136
154
  onClick={() => setIsMenuOpen(false)}
137
155
  >
138
- Sign In
156
+ {t("signIn")}
139
157
  </Link>
140
158
  )}
141
159
  </div>
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import { useLanguageStore } from "@doswiftly/storefront-sdk/react";
4
+ import { useRouter, usePathname } from "@/i18n/navigation";
5
+ import { useLocale, useTranslations } from "next-intl";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue,
12
+ } from "@/components/ui/select";
13
+
14
+ const LANGUAGE_NAMES: Record<string, string> = {
15
+ pl: "Polski",
16
+ en: "English",
17
+ de: "Deutsch",
18
+ fr: "Français",
19
+ es: "Español",
20
+ cs: "Čeština",
21
+ it: "Italiano",
22
+ nl: "Nederlands",
23
+ pt: "Português",
24
+ };
25
+
26
+ export function LanguageSwitcher() {
27
+ const t = useTranslations("language");
28
+ const locale = useLocale();
29
+ const router = useRouter();
30
+ const pathname = usePathname();
31
+ const supportedLanguages = useLanguageStore((s) => s.supportedLanguages);
32
+
33
+ if (supportedLanguages.length < 2) return null;
34
+
35
+ const handleLocaleChange = (newLocale: string) => {
36
+ if (newLocale === locale) return;
37
+ router.replace(pathname, { locale: newLocale });
38
+ };
39
+
40
+ return (
41
+ <Select value={locale} onValueChange={handleLocaleChange}>
42
+ <SelectTrigger className="h-8 w-auto gap-1 border-0 bg-transparent px-2 text-xs font-medium shadow-none" aria-label={t("switchLanguage")}>
43
+ <SelectValue>{locale.toUpperCase()}</SelectValue>
44
+ </SelectTrigger>
45
+ <SelectContent align="end">
46
+ {supportedLanguages.map((lang) => (
47
+ <SelectItem key={lang} value={lang}>
48
+ {lang.toUpperCase()} — {LANGUAGE_NAMES[lang] || lang}
49
+ </SelectItem>
50
+ ))}
51
+ </SelectContent>
52
+ </Select>
53
+ );
54
+ }