@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,8 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  import { useState, useEffect } from "react";
4
- import Link from "next/link";
5
- import { usePathname } from "next/navigation";
4
+ import { useTranslations } from "next-intl";
5
+ import { Link, usePathname } from "@/i18n/navigation";
6
6
  import { Menu, X, ChevronDown, ChevronRight } from "lucide-react";
7
7
  import { cn } from "@/lib/utils";
8
8
 
@@ -17,26 +17,29 @@ export interface MobileMenuProps {
17
17
  className?: string;
18
18
  }
19
19
 
20
- const defaultItems: MobileMenuItem[] = [
21
- {
22
- label: "Products",
23
- href: "/products",
24
- },
25
- {
26
- label: "Collections",
27
- href: "/collections",
28
- },
29
- {
30
- label: "Categories",
31
- href: "/categories",
32
- },
33
- {
34
- label: "About",
35
- href: "/about",
36
- },
37
- ];
38
-
39
- export function MobileMenu({ items = defaultItems, className }: MobileMenuProps) {
20
+ export function MobileMenu({ items, className }: MobileMenuProps) {
21
+ const t = useTranslations("nav");
22
+
23
+ const defaultItems: MobileMenuItem[] = [
24
+ {
25
+ label: t("products"),
26
+ href: "/products",
27
+ },
28
+ {
29
+ label: t("collections"),
30
+ href: "/collections",
31
+ },
32
+ {
33
+ label: t("categories"),
34
+ href: "/categories",
35
+ },
36
+ {
37
+ label: t("about"),
38
+ href: "/about",
39
+ },
40
+ ];
41
+
42
+ const resolvedItems = items ?? defaultItems;
40
43
  const [isOpen, setIsOpen] = useState(false);
41
44
  const [expandedItems, setExpandedItems] = useState<Set<string>>(new Set());
42
45
  const pathname = usePathname();
@@ -108,7 +111,7 @@ export function MobileMenu({ items = defaultItems, className }: MobileMenuProps)
108
111
  toggleExpanded(item.href);
109
112
  }}
110
113
  className="p-3 text-muted-foreground hover:text-foreground"
111
- aria-label={`Toggle ${item.label} submenu`}
114
+ aria-label={t("toggleSubmenu", { label: item.label })}
112
115
  aria-expanded={isExpanded}
113
116
  >
114
117
  {isExpanded ? (
@@ -140,7 +143,7 @@ export function MobileMenu({ items = defaultItems, className }: MobileMenuProps)
140
143
  "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
141
144
  className
142
145
  )}
143
- aria-label="Toggle mobile menu"
146
+ aria-label={t("toggleMobileMenu")}
144
147
  aria-expanded={isOpen}
145
148
  aria-controls="mobile-menu"
146
149
  >
@@ -163,16 +166,16 @@ export function MobileMenu({ items = defaultItems, className }: MobileMenuProps)
163
166
  className="fixed inset-y-0 left-0 z-50 w-full max-w-sm bg-background shadow-xl"
164
167
  role="dialog"
165
168
  aria-modal="true"
166
- aria-label="Mobile navigation"
169
+ aria-label={t("mobileNavigation")}
167
170
  >
168
171
  <div className="flex h-full flex-col">
169
172
  {/* Header */}
170
173
  <div className="flex items-center justify-between border-b border-border p-4">
171
- <h2 className="text-lg font-semibold">Menu</h2>
174
+ <h2 className="text-lg font-semibold">{t("menu")}</h2>
172
175
  <button
173
176
  onClick={() => setIsOpen(false)}
174
177
  className="rounded-md p-2 text-muted-foreground hover:bg-accent hover:text-accent-foreground"
175
- aria-label="Close mobile menu"
178
+ aria-label={t("closeMobileMenu")}
176
179
  >
177
180
  <X className="h-5 w-5" />
178
181
  </button>
@@ -181,7 +184,7 @@ export function MobileMenu({ items = defaultItems, className }: MobileMenuProps)
181
184
  {/* Menu Items */}
182
185
  <nav className="flex-1 overflow-y-auto p-4">
183
186
  <div className="space-y-1">
184
- {items.map((item) => renderMenuItem(item))}
187
+ {resolvedItems.map((item) => renderMenuItem(item))}
185
188
  </div>
186
189
  </nav>
187
190
 
@@ -192,13 +195,13 @@ export function MobileMenu({ items = defaultItems, className }: MobileMenuProps)
192
195
  href="/account"
193
196
  className="rounded-md bg-primary px-4 py-2 text-center text-sm font-medium text-primary-foreground hover:bg-primary/90"
194
197
  >
195
- My Account
198
+ {t("account")}
196
199
  </Link>
197
200
  <Link
198
201
  href="/cart"
199
202
  className="rounded-md border border-border px-4 py-2 text-center text-sm font-medium hover:bg-accent"
200
203
  >
201
- View Cart
204
+ {t("viewCart")}
202
205
  </Link>
203
206
  </div>
204
207
  </div>
@@ -1,7 +1,7 @@
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 { cn } from "@/lib/utils";
6
6
 
7
7
  export interface NavigationItem {
@@ -15,28 +15,31 @@ export interface NavigationProps {
15
15
  className?: string;
16
16
  }
17
17
 
18
- const defaultItems: NavigationItem[] = [
19
- {
20
- label: "Products",
21
- href: "/products",
22
- },
23
- {
24
- label: "Collections",
25
- href: "/collections",
26
- },
27
- {
28
- label: "Categories",
29
- href: "/categories",
30
- },
31
- {
32
- label: "About",
33
- href: "/about",
34
- },
35
- ];
36
-
37
- export function Navigation({ items = defaultItems, className }: NavigationProps) {
18
+ export function Navigation({ items, className }: NavigationProps) {
19
+ const t = useTranslations("nav");
38
20
  const pathname = usePathname();
39
21
 
22
+ const defaultItems: NavigationItem[] = [
23
+ {
24
+ label: t("products"),
25
+ href: "/products",
26
+ },
27
+ {
28
+ label: t("collections"),
29
+ href: "/collections",
30
+ },
31
+ {
32
+ label: t("categories"),
33
+ href: "/categories",
34
+ },
35
+ {
36
+ label: t("about"),
37
+ href: "/about",
38
+ },
39
+ ];
40
+
41
+ const resolvedItems = items ?? defaultItems;
42
+
40
43
  const isActive = (href: string) => {
41
44
  if (href === "/") {
42
45
  return pathname === "/";
@@ -48,9 +51,9 @@ export function Navigation({ items = defaultItems, className }: NavigationProps)
48
51
  <nav
49
52
  className={cn("flex items-center gap-6", className)}
50
53
  role="navigation"
51
- aria-label="Main navigation"
54
+ aria-label={t("mainNavigation")}
52
55
  >
53
- {items.map((item) => (
56
+ {resolvedItems.map((item) => (
54
57
  <div key={item.href} className="relative group">
55
58
  <Link
56
59
  href={item.href}
@@ -10,19 +10,10 @@ import { Coins, AlertTriangle } from 'lucide-react';
10
10
  import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
11
11
  import { Badge } from '@/components/ui/badge';
12
12
  import { cn } from '@/lib/utils';
13
-
14
- interface PointsSummary {
15
- totalPoints: number;
16
- currentPoints: number;
17
- pendingPoints: number;
18
- redeemedPoints: number;
19
- expiredPoints: number;
20
- expiringPoints?: number;
21
- nextExpiryDate?: string;
22
- }
13
+ import type { LoyaltyPointsSummary } from '@/lib/graphql/fragments';
23
14
 
24
15
  interface PointsBalanceProps {
25
- points: PointsSummary;
16
+ points: LoyaltyPointsSummary;
26
17
  variant?: 'default' | 'compact';
27
18
  className?: string;
28
19
  }
@@ -10,35 +10,14 @@ import { ArrowUpCircle, ArrowDownCircle, Clock, Gift, ShoppingCart, UserPlus, St
10
10
  import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
11
11
  import { Badge } from '@/components/ui/badge';
12
12
  import { cn } from '@/lib/utils';
13
-
14
- type TransactionType =
15
- | 'EARN_PURCHASE'
16
- | 'EARN_SIGNUP'
17
- | 'EARN_REFERRAL'
18
- | 'EARN_REVIEW'
19
- | 'EARN_BIRTHDAY'
20
- | 'EARN_BONUS'
21
- | 'REDEEM'
22
- | 'EXPIRE'
23
- | 'ADJUST';
24
-
25
- interface Transaction {
26
- id: string;
27
- type: TransactionType;
28
- points: number;
29
- balanceAfter: number;
30
- orderId?: string;
31
- description?: string;
32
- expiresAt?: string;
33
- createdAt: string;
34
- }
13
+ import type { LoyaltyTransaction } from '@/lib/graphql/fragments';
35
14
 
36
15
  interface PointsHistoryProps {
37
- transactions: Transaction[];
16
+ transactions: LoyaltyTransaction[];
38
17
  className?: string;
39
18
  }
40
19
 
41
- const transactionConfig: Record<TransactionType, {
20
+ const transactionConfig: Record<string, {
42
21
  label: string;
43
22
  icon: typeof ArrowUpCircle;
44
23
  color: string;
@@ -127,7 +106,11 @@ export function PointsHistory({ transactions, className }: PointsHistoryProps) {
127
106
  <CardContent>
128
107
  <div className="space-y-4">
129
108
  {transactions.map((transaction) => {
130
- const config = transactionConfig[transaction.type];
109
+ const config = transactionConfig[transaction.type] ?? {
110
+ label: transaction.type,
111
+ icon: AlertCircle,
112
+ color: 'text-muted-foreground',
113
+ };
131
114
  const Icon = config.icon;
132
115
  const isEarning = transaction.points > 0;
133
116
 
@@ -12,6 +12,7 @@
12
12
  */
13
13
 
14
14
  import { useState } from 'react';
15
+ import { useTranslations } from 'next-intl';
15
16
  import { Users, Copy, Check, Share2, Gift, UserPlus, Clock, Award } from 'lucide-react';
16
17
  import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
17
18
  import { Button } from '@/components/ui/button';
@@ -19,18 +20,10 @@ import { Input } from '@/components/ui/input';
19
20
  import { Badge } from '@/components/ui/badge';
20
21
  import { cn } from '@/lib/utils';
21
22
  import { toast } from 'sonner';
22
-
23
- interface ReferralStats {
24
- totalReferred: number;
25
- completedReferrals: number;
26
- pendingReferrals: number;
27
- totalPointsEarned: number;
28
- }
23
+ import type { ReferralStats } from '@/lib/graphql/fragments';
29
24
 
30
25
  interface ReferralSectionProps {
31
- referralCode: string;
32
- shareUrl: string;
33
- stats: ReferralStats;
26
+ referralStats: ReferralStats;
34
27
  pointsName?: string;
35
28
  referralPoints?: number;
36
29
  bonusPoints?: number;
@@ -38,14 +31,14 @@ interface ReferralSectionProps {
38
31
  }
39
32
 
40
33
  export function ReferralSection({
41
- referralCode,
42
- shareUrl,
43
- stats,
34
+ referralStats,
44
35
  pointsName = 'punktów',
45
36
  referralPoints = 0,
46
37
  bonusPoints = 0,
47
38
  className,
48
39
  }: ReferralSectionProps) {
40
+ const t = useTranslations("loyalty.referral");
41
+ const { referralCode, shareUrl } = referralStats;
49
42
  const [copied, setCopied] = useState<'code' | 'url' | null>(null);
50
43
 
51
44
  const formatNumber = (num: number) => {
@@ -56,10 +49,10 @@ export function ReferralSection({
56
49
  try {
57
50
  await navigator.clipboard.writeText(text);
58
51
  setCopied(type);
59
- toast.success(type === 'code' ? 'Kod skopiowany!' : 'Link skopiowany!');
52
+ toast.success(type === 'code' ? t('codeCopied') : t('linkCopied'));
60
53
  setTimeout(() => setCopied(null), 2000);
61
54
  } catch {
62
- toast.error('Nie udało się skopiować');
55
+ toast.error(t('copyFailed'));
63
56
  }
64
57
  };
65
58
 
@@ -67,14 +60,14 @@ export function ReferralSection({
67
60
  if (navigator.share) {
68
61
  try {
69
62
  await navigator.share({
70
- title: 'Dołącz do programu lojalnościowego',
71
- text: `Zarejestruj się używając mojego kodu ${referralCode} i otrzymaj ${formatNumber(bonusPoints)} ${pointsName}!`,
63
+ title: t('shareFriends'),
64
+ text: t('shareText', { code: referralCode }),
72
65
  url: shareUrl,
73
66
  });
74
67
  } catch (err) {
75
68
  // User cancelled or error
76
69
  if ((err as Error).name !== 'AbortError') {
77
- toast.error('Nie udało się udostępnić');
70
+ toast.error(t('shareFailed'));
78
71
  }
79
72
  }
80
73
  } else {
@@ -90,11 +83,10 @@ export function ReferralSection({
90
83
  <CardHeader>
91
84
  <CardTitle className="flex items-center gap-2">
92
85
  <Users className="h-5 w-5" />
93
- Twój kod polecający
86
+ {t('yourCode')}
94
87
  </CardTitle>
95
88
  <CardDescription>
96
- Podziel się tym kodem ze znajomymi. Gdy dokonają pierwszego zakupu, oboje
97
- otrzymacie punkty!
89
+ {t('shareDescription')}
98
90
  </CardDescription>
99
91
  </CardHeader>
100
92
  <CardContent className="space-y-4">
@@ -141,7 +133,7 @@ export function ReferralSection({
141
133
  {/* Share Button */}
142
134
  <Button onClick={handleShare} className="w-full">
143
135
  <Share2 className="h-4 w-4 mr-2" />
144
- Udostępnij znajomym
136
+ {t('shareFriends')}
145
137
  </Button>
146
138
  </CardContent>
147
139
  </Card>
@@ -149,7 +141,7 @@ export function ReferralSection({
149
141
  {/* How it Works */}
150
142
  <Card>
151
143
  <CardHeader>
152
- <CardTitle className="text-lg">Jak to działa?</CardTitle>
144
+ <CardTitle className="text-lg">{t('howItWorks')}</CardTitle>
153
145
  </CardHeader>
154
146
  <CardContent>
155
147
  <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
@@ -157,9 +149,9 @@ export function ReferralSection({
157
149
  <div className="p-3 bg-primary/10 rounded-full mb-3">
158
150
  <Share2 className="h-6 w-6 text-primary" />
159
151
  </div>
160
- <h4 className="font-medium mb-1">1. Udostępnij kod</h4>
152
+ <h4 className="font-medium mb-1">{t('step1Title')}</h4>
161
153
  <p className="text-sm text-muted-foreground">
162
- Podziel się swoim kodem lub linkiem ze znajomymi
154
+ {t('step1Desc')}
163
155
  </p>
164
156
  </div>
165
157
 
@@ -167,9 +159,9 @@ export function ReferralSection({
167
159
  <div className="p-3 bg-primary/10 rounded-full mb-3">
168
160
  <UserPlus className="h-6 w-6 text-primary" />
169
161
  </div>
170
- <h4 className="font-medium mb-1">2. Znajomy się rejestruje</h4>
162
+ <h4 className="font-medium mb-1">{t('step2Title')}</h4>
171
163
  <p className="text-sm text-muted-foreground">
172
- Znajomy używa Twojego kodu przy rejestracji i dokonuje zakupu
164
+ {t('step2Desc')}
173
165
  </p>
174
166
  </div>
175
167
 
@@ -177,10 +169,9 @@ export function ReferralSection({
177
169
  <div className="p-3 bg-primary/10 rounded-full mb-3">
178
170
  <Gift className="h-6 w-6 text-primary" />
179
171
  </div>
180
- <h4 className="font-medium mb-1">3. Oboje zyskujecie</h4>
172
+ <h4 className="font-medium mb-1">{t('step3Title')}</h4>
181
173
  <p className="text-sm text-muted-foreground">
182
- Ty otrzymujesz {formatNumber(referralPoints)} {pointsName}, a znajomy{' '}
183
- {formatNumber(bonusPoints)} {pointsName}
174
+ {t('step3Desc', { points: formatNumber(referralPoints), name: pointsName })}
184
175
  </p>
185
176
  </div>
186
177
  </div>
@@ -192,54 +183,53 @@ export function ReferralSection({
192
183
  <CardHeader>
193
184
  <CardTitle className="text-lg flex items-center gap-2">
194
185
  <Award className="h-5 w-5" />
195
- Twoje statystyki poleceń
186
+ {t('yourStats')}
196
187
  </CardTitle>
197
188
  </CardHeader>
198
189
  <CardContent>
199
190
  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
200
191
  <div className="p-4 bg-muted/50 rounded-lg text-center">
201
192
  <div className="text-2xl font-bold text-primary">
202
- {formatNumber(stats.totalReferred)}
193
+ {formatNumber(referralStats.totalReferred)}
203
194
  </div>
204
- <div className="text-sm text-muted-foreground">Zaproszonych</div>
195
+ <div className="text-sm text-muted-foreground">{t('invited')}</div>
205
196
  </div>
206
197
 
207
198
  <div className="p-4 bg-muted/50 rounded-lg text-center">
208
199
  <div className="flex items-center justify-center gap-1">
209
200
  <div className="text-2xl font-bold text-green-600">
210
- {formatNumber(stats.completedReferrals)}
201
+ {formatNumber(referralStats.completedReferrals)}
211
202
  </div>
212
203
  <Check className="h-5 w-5 text-green-600" />
213
204
  </div>
214
- <div className="text-sm text-muted-foreground">Zrealizowanych</div>
205
+ <div className="text-sm text-muted-foreground">{t('completed')}</div>
215
206
  </div>
216
207
 
217
208
  <div className="p-4 bg-muted/50 rounded-lg text-center">
218
209
  <div className="flex items-center justify-center gap-1">
219
210
  <div className="text-2xl font-bold text-amber-600">
220
- {formatNumber(stats.pendingReferrals)}
211
+ {formatNumber(referralStats.pendingReferrals)}
221
212
  </div>
222
213
  <Clock className="h-5 w-5 text-amber-600" />
223
214
  </div>
224
- <div className="text-sm text-muted-foreground">Oczekujących</div>
215
+ <div className="text-sm text-muted-foreground">{t('pending')}</div>
225
216
  </div>
226
217
 
227
218
  <div className="p-4 bg-muted/50 rounded-lg text-center">
228
219
  <div className="text-2xl font-bold text-primary">
229
- {formatNumber(stats.totalPointsEarned)}
220
+ {formatNumber(referralStats.totalPointsEarned)}
230
221
  </div>
231
222
  <div className="text-sm text-muted-foreground">
232
- Zdobytych {pointsName}
223
+ {t('earned', { name: pointsName })}
233
224
  </div>
234
225
  </div>
235
226
  </div>
236
227
 
237
- {stats.pendingReferrals > 0 && (
228
+ {referralStats.pendingReferrals > 0 && (
238
229
  <div className="mt-4 p-3 bg-amber-50 dark:bg-amber-950/30 rounded-lg border border-amber-200 dark:border-amber-800">
239
230
  <p className="text-sm text-amber-800 dark:text-amber-200">
240
231
  <Clock className="h-4 w-4 inline mr-1" />
241
- Masz {stats.pendingReferrals} oczekujących poleceń. Punkty zostaną
242
- przyznane po dokonaniu pierwszego zakupu przez poleconą osobę.
232
+ {t('pendingReferrals', { count: referralStats.pendingReferrals })}
243
233
  </p>
244
234
  </div>
245
235
  )}
@@ -15,41 +15,17 @@ import { Badge } from '@/components/ui/badge';
15
15
  import { cn } from '@/lib/utils';
16
16
  import { TierBadge } from './tier-badge';
17
17
  import { toast } from 'sonner';
18
-
19
- type TierType = 'BRONZE' | 'SILVER' | 'GOLD' | 'PLATINUM' | 'DIAMOND';
20
-
21
- interface Reward {
22
- id: string;
23
- name: string;
24
- slug: string;
25
- type: string;
26
- pointsCost: number;
27
- discountPercent?: number;
28
- discountAmount?: {
29
- amount: string;
30
- currencyCode: string;
31
- };
32
- description?: string;
33
- image?: {
34
- url: string;
35
- altText?: string | null;
36
- } | null;
37
- available: boolean;
38
- tierRequired?: TierType | null;
39
- remainingRedemptions?: number;
40
- }
41
-
42
- interface RedeemResult {
43
- discountCode?: string | null;
44
- productDiscountCode?: string | null;
45
- giftCardCode?: string | null;
46
- }
18
+ import type { LoyaltyReward, LoyaltyTier } from '@/lib/graphql/fragments';
47
19
 
48
20
  interface RewardsCatalogProps {
49
- rewards: Reward[];
21
+ rewards: LoyaltyReward[];
50
22
  currentPoints: number;
51
- currentTier?: TierType | null;
52
- onRedeem?: (rewardId: string) => Promise<RedeemResult>;
23
+ currentTier?: LoyaltyTier['type'] | null;
24
+ onRedeem?: (rewardId: string) => Promise<{
25
+ discountCode?: string | null;
26
+ productDiscountCode?: string | null;
27
+ giftCardCode?: string | null;
28
+ }>;
53
29
  className?: string;
54
30
  }
55
31
 
@@ -73,13 +49,13 @@ export function RewardsCatalog({
73
49
  }).format(parseFloat(amount));
74
50
  };
75
51
 
76
- const tierOrder: TierType[] = ['BRONZE', 'SILVER', 'GOLD', 'PLATINUM', 'DIAMOND'];
77
- const canAccessTier = (requiredTier?: TierType | null) => {
78
- if (!requiredTier || !currentTier) return true;
79
- return tierOrder.indexOf(currentTier) >= tierOrder.indexOf(requiredTier);
52
+ const tierOrder: string[] = ['BRONZE', 'SILVER', 'GOLD', 'PLATINUM', 'DIAMOND'];
53
+ const canAccessTier = (requiredTierType?: string | null) => {
54
+ if (!requiredTierType || !currentTier) return true;
55
+ return tierOrder.indexOf(currentTier) >= tierOrder.indexOf(requiredTierType);
80
56
  };
81
57
 
82
- const handleRedeem = async (reward: Reward) => {
58
+ const handleRedeem = async (reward: LoyaltyReward) => {
83
59
  if (!onRedeem) return;
84
60
 
85
61
  setRedeemingId(reward.id);
@@ -125,7 +101,7 @@ export function RewardsCatalog({
125
101
  <div className={cn('grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4', className)}>
126
102
  {rewards.map((reward) => {
127
103
  const canAfford = currentPoints >= reward.pointsCost;
128
- const hasTierAccess = canAccessTier(reward.tierRequired);
104
+ const hasTierAccess = canAccessTier(reward.tierRequired?.type);
129
105
  const canRedeem = reward.available && canAfford && hasTierAccess;
130
106
 
131
107
  return (
@@ -144,8 +120,8 @@ export function RewardsCatalog({
144
120
  <CardContent className="p-4">
145
121
  <div className="flex items-start justify-between gap-2 mb-2">
146
122
  <h3 className="font-semibold">{reward.name}</h3>
147
- {reward.tierRequired && (
148
- <TierBadge tier={reward.tierRequired} size="sm" />
123
+ {reward.tierRequired?.type && (
124
+ <TierBadge tier={reward.tierRequired.type} size="sm" />
149
125
  )}
150
126
  </div>
151
127
 
@@ -183,7 +159,7 @@ export function RewardsCatalog({
183
159
  {!hasTierAccess ? (
184
160
  <Button variant="outline" className="w-full" disabled>
185
161
  <Lock className="h-4 w-4 mr-2" />
186
- Wymaga {reward.tierRequired}
162
+ Wymaga {reward.tierRequired?.name ?? reward.tierRequired?.type}
187
163
  </Button>
188
164
  ) : !canAfford ? (
189
165
  <Button variant="outline" className="w-full" disabled>
@@ -11,37 +11,10 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
11
11
  import { Progress } from '@/components/ui/progress';
12
12
  import { TierBadge } from './tier-badge';
13
13
  import { cn } from '@/lib/utils';
14
-
15
- type TierType = 'BRONZE' | 'SILVER' | 'GOLD' | 'PLATINUM' | 'DIAMOND';
16
-
17
- interface CustomBenefit {
18
- name: string;
19
- description?: string | null;
20
- icon?: string | null;
21
- }
22
-
23
- interface Tier {
24
- id: string;
25
- name: string;
26
- type?: TierType | null;
27
- minPoints: number;
28
- pointsMultiplier: number;
29
- customBenefits?: CustomBenefit[];
30
- }
31
-
32
- interface TierProgressData {
33
- currentTier: Tier;
34
- nextTier?: Tier;
35
- pointsToNextTier: number;
36
- progressPercent: number;
37
- spendToNextTier?: {
38
- amount: string;
39
- currencyCode: string;
40
- };
41
- }
14
+ import type { TierProgress as TierProgressType } from '@/lib/graphql/fragments';
42
15
 
43
16
  interface TierProgressProps {
44
- progress: TierProgressData;
17
+ progress: TierProgressType;
45
18
  className?: string;
46
19
  }
47
20
 
@@ -7,5 +7,10 @@
7
7
  export * from "./order-tracking";
8
8
  export * from "./shipment-card";
9
9
  export * from "./tracking-timeline";
10
- export * from "./tracking-status";
10
+ export {
11
+ TrackingStatus,
12
+ CompactTrackingStatus,
13
+ type TrackingStatusProps,
14
+ type CompactTrackingStatusProps,
15
+ } from "./tracking-status";
11
16
  export * from "./delivery-estimate";