@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,206 @@
1
+ "use client";
2
+
3
+ import { useParams } from "next/navigation";
4
+ import Link from "next/link";
5
+ import { ChevronLeft } from "lucide-react";
6
+ import { Button } from "@/components/ui/button";
7
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
8
+ import {
9
+ TrackingTimeline,
10
+ MilestoneTimeline,
11
+ type TrackingEvent,
12
+ } from "@/components/order/tracking-timeline";
13
+ import { TrackingStatus } from "@/components/order/tracking-status";
14
+ import {
15
+ DeliveryEstimate,
16
+ DeliveryProgress,
17
+ } from "@/components/order/delivery-estimate";
18
+
19
+ export default function OrderTrackingPage() {
20
+ const params = useParams();
21
+ const orderId = params.id as string;
22
+
23
+ // TODO: Fetch tracking data from backend using GraphQL
24
+ const trackingData = {
25
+ orderId,
26
+ orderNumber: "#12345",
27
+ status: "in_transit" as const,
28
+ trackingNumber: "1Z999AA10123456784",
29
+ carrier: "UPS",
30
+ estimatedDelivery: "2024-01-20",
31
+ earliestDelivery: "2024-01-19",
32
+ latestDelivery: "2024-01-21",
33
+ lastUpdate: "2024-01-18T14:30:00Z",
34
+ deliveryAddress: {
35
+ city: "Warsaw",
36
+ province: "Mazowieckie",
37
+ country: "Poland",
38
+ },
39
+ };
40
+
41
+ const milestones = [
42
+ {
43
+ label: "Order Placed",
44
+ status: "completed" as const,
45
+ date: "2024-01-15",
46
+ },
47
+ {
48
+ label: "Processing",
49
+ status: "completed" as const,
50
+ date: "2024-01-16",
51
+ },
52
+ {
53
+ label: "Shipped",
54
+ status: "completed" as const,
55
+ date: "2024-01-17",
56
+ },
57
+ {
58
+ label: "In Transit",
59
+ status: "current" as const,
60
+ },
61
+ {
62
+ label: "Delivered",
63
+ status: "pending" as const,
64
+ },
65
+ ];
66
+
67
+ const events: TrackingEvent[] = [
68
+ {
69
+ id: "1",
70
+ status: "In Transit",
71
+ description: "Package is on the way to the destination",
72
+ location: "Warsaw Distribution Center",
73
+ timestamp: "2024-01-18T14:30:00Z",
74
+ isCompleted: true,
75
+ },
76
+ {
77
+ id: "2",
78
+ status: "In Transit",
79
+ description: "Package arrived at sorting facility",
80
+ location: "Krakow Sorting Facility",
81
+ timestamp: "2024-01-18T08:15:00Z",
82
+ isCompleted: true,
83
+ },
84
+ {
85
+ id: "3",
86
+ status: "Shipped",
87
+ description: "Package has been picked up by carrier",
88
+ location: "Origin Facility",
89
+ timestamp: "2024-01-17T16:45:00Z",
90
+ isCompleted: true,
91
+ },
92
+ {
93
+ id: "4",
94
+ status: "Processing",
95
+ description: "Package is being prepared for shipment",
96
+ location: "Warehouse",
97
+ timestamp: "2024-01-16T10:00:00Z",
98
+ isCompleted: true,
99
+ },
100
+ {
101
+ id: "5",
102
+ status: "Order Placed",
103
+ description: "Order has been confirmed",
104
+ timestamp: "2024-01-15T12:30:00Z",
105
+ isCompleted: true,
106
+ },
107
+ ];
108
+
109
+ return (
110
+ <div className="container mx-auto px-4 py-8">
111
+ <Breadcrumbs className="mb-6" />
112
+
113
+ <div className="mb-6">
114
+ <Button variant="ghost" asChild>
115
+ <Link href={`/account/orders/${orderId}`}>
116
+ <ChevronLeft className="mr-2 h-4 w-4" />
117
+ Back to Order Details
118
+ </Link>
119
+ </Button>
120
+ </div>
121
+
122
+ <div className="mb-8">
123
+ <h1 className="text-3xl font-bold text-foreground">
124
+ Track Order {trackingData.orderNumber}
125
+ </h1>
126
+ <p className="mt-2 text-muted-foreground">
127
+ Follow your package's journey
128
+ </p>
129
+ </div>
130
+
131
+ {/* Milestone Progress */}
132
+ <div className="mb-8">
133
+ <MilestoneTimeline milestones={milestones} />
134
+ </div>
135
+
136
+ <div className="grid gap-6 lg:grid-cols-3">
137
+ {/* Main Content */}
138
+ <div className="lg:col-span-2 space-y-6">
139
+ {/* Current Status */}
140
+ <TrackingStatus
141
+ status={trackingData.status}
142
+ trackingNumber={trackingData.trackingNumber}
143
+ carrier={trackingData.carrier}
144
+ lastUpdate={trackingData.lastUpdate}
145
+ />
146
+
147
+ {/* Delivery Progress */}
148
+ <DeliveryProgress
149
+ currentStep={4}
150
+ totalSteps={5}
151
+ estimatedDate={trackingData.estimatedDelivery}
152
+ />
153
+
154
+ {/* Tracking Timeline */}
155
+ <div>
156
+ <h2 className="text-xl font-semibold text-foreground mb-4">
157
+ Tracking History
158
+ </h2>
159
+ <TrackingTimeline events={events} />
160
+ </div>
161
+ </div>
162
+
163
+ {/* Sidebar */}
164
+ <div className="space-y-6">
165
+ {/* Delivery Estimate */}
166
+ <DeliveryEstimate
167
+ estimatedDate={trackingData.estimatedDelivery}
168
+ earliestDate={trackingData.earliestDelivery}
169
+ latestDate={trackingData.latestDelivery}
170
+ address={trackingData.deliveryAddress}
171
+ />
172
+
173
+ {/* Carrier Information */}
174
+ <div className="rounded-lg border border-border bg-background p-6">
175
+ <h3 className="text-lg font-semibold text-foreground mb-4">
176
+ Carrier Information
177
+ </h3>
178
+ <div className="space-y-3 text-sm">
179
+ <div>
180
+ <span className="font-medium text-foreground">Carrier:</span>
181
+ <p className="text-muted-foreground">{trackingData.carrier}</p>
182
+ </div>
183
+ <div>
184
+ <span className="font-medium text-foreground">
185
+ Tracking Number:
186
+ </span>
187
+ <p className="font-mono text-muted-foreground">
188
+ {trackingData.trackingNumber}
189
+ </p>
190
+ </div>
191
+ <Button variant="outline" className="w-full mt-4" asChild>
192
+ <a
193
+ href={`https://www.ups.com/track?tracknum=${trackingData.trackingNumber}`}
194
+ target="_blank"
195
+ rel="noopener noreferrer"
196
+ >
197
+ Track on Carrier Website
198
+ </a>
199
+ </Button>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ </div>
204
+ </div>
205
+ );
206
+ }
@@ -0,0 +1,80 @@
1
+ "use client";
2
+
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { getGraphQLClient } from "@/lib/graphql/client";
5
+ import { useAuthStore } from "@/stores/auth-store";
6
+ import { CustomerDocument } from "@/generated/graphql";
7
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
8
+ import { OrderHistory, type Order } from "@/components/account/order-history";
9
+ import { Skeleton } from "@/components/ui/skeleton";
10
+
11
+ export default function OrdersPage() {
12
+ const client = getGraphQLClient();
13
+ const { accessToken, isAuthenticated } = useAuthStore();
14
+
15
+ const { data, isLoading, error } = useQuery({
16
+ queryKey: ["customer", "orders", accessToken],
17
+ queryFn: async () => {
18
+ if (!accessToken) return null;
19
+ const result = await client.request(CustomerDocument, {
20
+ customerAccessToken: accessToken,
21
+ });
22
+ return result.customer;
23
+ },
24
+ enabled: isAuthenticated && !!accessToken,
25
+ });
26
+
27
+ if (isLoading) {
28
+ return (
29
+ <div className="container mx-auto px-4 py-8">
30
+ <Breadcrumbs className="mb-6" />
31
+ <div className="mb-8">
32
+ <Skeleton className="h-10 w-64 mb-2" />
33
+ <Skeleton className="h-6 w-96" />
34
+ </div>
35
+ <div className="space-y-4">
36
+ {[...Array(3)].map((_, i) => (
37
+ <Skeleton key={i} className="h-32 w-full" />
38
+ ))}
39
+ </div>
40
+ </div>
41
+ );
42
+ }
43
+
44
+ if (error) {
45
+ return (
46
+ <div className="container mx-auto px-4 py-8">
47
+ <Breadcrumbs className="mb-6" />
48
+ <div className="rounded-lg border border-red-200 bg-red-50 p-8 text-center">
49
+ <p className="text-red-800">Failed to load orders</p>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ const orders: Order[] =
56
+ data?.orders?.edges.map((edge) => ({
57
+ id: edge.node.id,
58
+ orderNumber: edge.node.orderNumber,
59
+ date: edge.node.createdAt,
60
+ status: (edge.node.fulfillmentStatus || "processing") as Order["status"],
61
+ total: edge.node.totalPrice.amount,
62
+ currency: edge.node.totalPrice.currencyCode,
63
+ itemCount: edge.node.lineItems?.edges.length || 0,
64
+ })) || [];
65
+
66
+ return (
67
+ <div className="container mx-auto px-4 py-8">
68
+ <Breadcrumbs className="mb-6" />
69
+
70
+ <div className="mb-8">
71
+ <h1 className="text-3xl font-bold text-foreground">Order History</h1>
72
+ <p className="mt-2 text-muted-foreground">
73
+ View and track your orders
74
+ </p>
75
+ </div>
76
+
77
+ <OrderHistory orders={orders} />
78
+ </div>
79
+ );
80
+ }
@@ -0,0 +1,107 @@
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+ import { useRouter } from "next/navigation";
5
+ import { User, Package, MapPin, Settings } from "lucide-react";
6
+ import { Button } from "@/components/ui/button";
7
+ import { Card } from "@/components/ui/card";
8
+
9
+ export default function AccountPage() {
10
+ const router = useRouter();
11
+
12
+ const handleLogout = async () => {
13
+ // Clear token via API route
14
+ await fetch("/api/auth/clear-token", { method: "POST" });
15
+ router.push("/");
16
+ };
17
+
18
+ return (
19
+ <div className="container mx-auto px-4 py-16">
20
+ <div className="mx-auto max-w-4xl">
21
+ <div className="mb-8">
22
+ <h1 className="text-3xl font-bold text-foreground">My Account</h1>
23
+ <p className="mt-2 text-muted-foreground">
24
+ Manage your account settings and orders
25
+ </p>
26
+ </div>
27
+
28
+ <div className="grid gap-6 md:grid-cols-2">
29
+ {/* Profile Card */}
30
+ <Card className="p-6">
31
+ <div className="mb-4 flex items-center gap-3">
32
+ <div className="rounded-full bg-primary/10 p-3">
33
+ <User className="h-6 w-6 text-primary" />
34
+ </div>
35
+ <h2 className="text-xl font-semibold text-foreground">Profile</h2>
36
+ </div>
37
+ <p className="text-sm text-muted-foreground mb-4">
38
+ View and edit your profile information
39
+ </p>
40
+ <Button variant="outline" className="w-full" asChild>
41
+ <Link href="/account/settings">Edit Profile</Link>
42
+ </Button>
43
+ </Card>
44
+
45
+ {/* Orders Card */}
46
+ <Card className="p-6">
47
+ <div className="mb-4 flex items-center gap-3">
48
+ <div className="rounded-full bg-primary/10 p-3">
49
+ <Package className="h-6 w-6 text-primary" />
50
+ </div>
51
+ <h2 className="text-xl font-semibold text-foreground">Orders</h2>
52
+ </div>
53
+ <p className="text-sm text-muted-foreground mb-4">
54
+ View your order history and track shipments
55
+ </p>
56
+ <Button variant="outline" className="w-full" asChild>
57
+ <Link href="/account/orders">View Orders</Link>
58
+ </Button>
59
+ </Card>
60
+
61
+ {/* Addresses Card */}
62
+ <Card className="p-6">
63
+ <div className="mb-4 flex items-center gap-3">
64
+ <div className="rounded-full bg-primary/10 p-3">
65
+ <MapPin className="h-6 w-6 text-primary" />
66
+ </div>
67
+ <h2 className="text-xl font-semibold text-foreground">
68
+ Addresses
69
+ </h2>
70
+ </div>
71
+ <p className="text-sm text-muted-foreground mb-4">
72
+ Manage your shipping and billing addresses
73
+ </p>
74
+ <Button variant="outline" className="w-full" asChild>
75
+ <Link href="/account/addresses">Manage Addresses</Link>
76
+ </Button>
77
+ </Card>
78
+
79
+ {/* Settings Card */}
80
+ <Card className="p-6">
81
+ <div className="mb-4 flex items-center gap-3">
82
+ <div className="rounded-full bg-primary/10 p-3">
83
+ <Settings className="h-6 w-6 text-primary" />
84
+ </div>
85
+ <h2 className="text-xl font-semibold text-foreground">
86
+ Settings
87
+ </h2>
88
+ </div>
89
+ <p className="text-sm text-muted-foreground mb-4">
90
+ Update your account preferences
91
+ </p>
92
+ <Button variant="outline" className="w-full" asChild>
93
+ <Link href="/account/settings">Account Settings</Link>
94
+ </Button>
95
+ </Card>
96
+ </div>
97
+
98
+ {/* Logout Button */}
99
+ <div className="mt-8">
100
+ <Button variant="destructive" onClick={handleLogout}>
101
+ Sign Out
102
+ </Button>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ );
107
+ }
@@ -0,0 +1,195 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
+ import { getGraphQLClient } from "@/lib/graphql/client";
6
+ import { useAuthStore } from "@/stores/auth-store";
7
+ import { CustomerDocument, CustomerUpdateDocument } from "@/generated/graphql";
8
+ import { Breadcrumbs } from "@/components/layout/breadcrumbs";
9
+ import { Button } from "@/components/ui/button";
10
+ import { Input } from "@/components/ui/input";
11
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
12
+
13
+ export default function SettingsPage() {
14
+ const { accessToken } = useAuthStore();
15
+ const client = getGraphQLClient();
16
+ const queryClient = useQueryClient();
17
+
18
+ const [email, setEmail] = useState("");
19
+ const [firstName, setFirstName] = useState("");
20
+ const [lastName, setLastName] = useState("");
21
+ const [phone, setPhone] = useState("");
22
+ const [acceptsMarketing, setAcceptsMarketing] = useState(false);
23
+
24
+ // Fetch customer data
25
+ const { data: customerData } = useQuery({
26
+ queryKey: ["customer", accessToken],
27
+ queryFn: async () => {
28
+ if (!accessToken) return null;
29
+ return client.request(CustomerDocument, { customerAccessToken: accessToken });
30
+ },
31
+ enabled: !!accessToken,
32
+ });
33
+
34
+ // Initialize form with customer data
35
+ useState(() => {
36
+ if (customerData?.customer) {
37
+ setEmail(customerData.customer.email || "");
38
+ setFirstName(customerData.customer.firstName || "");
39
+ setLastName(customerData.customer.lastName || "");
40
+ setPhone(customerData.customer.phone || "");
41
+ setAcceptsMarketing(customerData.customer.acceptsMarketing || false);
42
+ }
43
+ });
44
+
45
+ // Update customer mutation
46
+ const updateMutation = useMutation({
47
+ mutationFn: async (customer: any) => {
48
+ return client.request(CustomerUpdateDocument, {
49
+ customer,
50
+ customerAccessToken: accessToken!,
51
+ });
52
+ },
53
+ onSuccess: () => {
54
+ queryClient.invalidateQueries({ queryKey: ["customer"] });
55
+ alert("Settings saved successfully!");
56
+ },
57
+ onError: () => {
58
+ alert("Failed to save settings");
59
+ },
60
+ });
61
+
62
+ const handleSave = (e: React.FormEvent) => {
63
+ e.preventDefault();
64
+ updateMutation.mutate({
65
+ firstName,
66
+ lastName,
67
+ email,
68
+ phone,
69
+ acceptsMarketing,
70
+ });
71
+ };
72
+
73
+ return (
74
+ <div className="container mx-auto px-4 py-8">
75
+ <Breadcrumbs className="mb-6" />
76
+
77
+ <div className="mx-auto max-w-2xl">
78
+ <h1 className="mb-8 text-3xl font-bold text-foreground">Account Settings</h1>
79
+
80
+ <div className="space-y-6">
81
+ {/* Personal Information */}
82
+ <Card>
83
+ <CardHeader>
84
+ <CardTitle>Personal Information</CardTitle>
85
+ </CardHeader>
86
+ <CardContent>
87
+ <form onSubmit={handleSave} className="space-y-4">
88
+ <div className="grid gap-4 sm:grid-cols-2">
89
+ <div className="space-y-2">
90
+ <label htmlFor="firstName" className="text-sm font-medium">
91
+ First Name
92
+ </label>
93
+ <Input
94
+ id="firstName"
95
+ value={firstName}
96
+ onChange={(e) => setFirstName(e.target.value)}
97
+ />
98
+ </div>
99
+ <div className="space-y-2">
100
+ <label htmlFor="lastName" className="text-sm font-medium">
101
+ Last Name
102
+ </label>
103
+ <Input
104
+ id="lastName"
105
+ value={lastName}
106
+ onChange={(e) => setLastName(e.target.value)}
107
+ />
108
+ </div>
109
+ </div>
110
+ <div className="space-y-2">
111
+ <label htmlFor="email" className="text-sm font-medium">
112
+ Email
113
+ </label>
114
+ <Input
115
+ id="email"
116
+ type="email"
117
+ value={email}
118
+ onChange={(e) => setEmail(e.target.value)}
119
+ />
120
+ </div>
121
+ <div className="space-y-2">
122
+ <label htmlFor="phone" className="text-sm font-medium">
123
+ Phone
124
+ </label>
125
+ <Input
126
+ id="phone"
127
+ type="tel"
128
+ value={phone}
129
+ onChange={(e) => setPhone(e.target.value)}
130
+ />
131
+ </div>
132
+ <Button type="submit" disabled={updateMutation.isPending}>
133
+ {updateMutation.isPending ? "Saving..." : "Save Changes"}
134
+ </Button>
135
+ </form>
136
+ </CardContent>
137
+ </Card>
138
+
139
+ {/* Change Password */}
140
+ <Card>
141
+ <CardHeader>
142
+ <CardTitle>Change Password</CardTitle>
143
+ </CardHeader>
144
+ <CardContent>
145
+ <form className="space-y-4">
146
+ <div className="space-y-2">
147
+ <label htmlFor="currentPassword" className="text-sm font-medium">
148
+ Current Password
149
+ </label>
150
+ <Input id="currentPassword" type="password" />
151
+ </div>
152
+ <div className="space-y-2">
153
+ <label htmlFor="newPassword" className="text-sm font-medium">
154
+ New Password
155
+ </label>
156
+ <Input id="newPassword" type="password" />
157
+ </div>
158
+ <div className="space-y-2">
159
+ <label htmlFor="confirmPassword" className="text-sm font-medium">
160
+ Confirm New Password
161
+ </label>
162
+ <Input id="confirmPassword" type="password" />
163
+ </div>
164
+ <Button type="submit">Update Password</Button>
165
+ </form>
166
+ </CardContent>
167
+ </Card>
168
+
169
+ {/* Preferences */}
170
+ <Card>
171
+ <CardHeader>
172
+ <CardTitle>Preferences</CardTitle>
173
+ </CardHeader>
174
+ <CardContent className="space-y-4">
175
+ <div className="flex items-center justify-between">
176
+ <div>
177
+ <p className="font-medium">Marketing Emails</p>
178
+ <p className="text-sm text-muted-foreground">
179
+ Receive emails about new products and special offers
180
+ </p>
181
+ </div>
182
+ <input
183
+ type="checkbox"
184
+ checked={acceptsMarketing}
185
+ onChange={(e) => setAcceptsMarketing(e.target.checked)}
186
+ className="h-4 w-4 rounded border-border text-primary focus:ring-2 focus:ring-ring"
187
+ />
188
+ </div>
189
+ </CardContent>
190
+ </Card>
191
+ </div>
192
+ </div>
193
+ </div>
194
+ );
195
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * API Route: Clear Authentication Token
3
+ *
4
+ * Clears the customer access token cookie by setting it to expire immediately.
5
+ * This is used during logout to ensure the user is fully signed out.
6
+ *
7
+ * Security Features:
8
+ * 1. Origin validation - Only accepts requests from same origin (CSRF protection)
9
+ * 2. Immediate expiration - Sets maxAge to 0 to delete cookie
10
+ * 3. Same cookie attributes - Ensures proper deletion across all contexts
11
+ *
12
+ * @see lib/auth/cookies.ts - Cookie configuration
13
+ * @see hooks/use-auth.ts - Client-side usage
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * // Client-side usage (via clearAuthToken helper)
18
+ * await clearAuthToken();
19
+ * ```
20
+ */
21
+
22
+ import { NextRequest, NextResponse } from "next/server";
23
+ import { AUTH_COOKIE_CONFIG } from "@/lib/auth/cookies";
24
+
25
+ /**
26
+ * POST /api/auth/clear-token
27
+ *
28
+ * Clears the authentication token cookie.
29
+ *
30
+ * @param request - Next.js request object
31
+ * @returns Response confirming token was cleared
32
+ */
33
+ export async function POST(request: NextRequest) {
34
+ try {
35
+ // 1. CSRF Protection: Validate origin
36
+ const origin = request.headers.get("origin");
37
+ const host = request.headers.get("host");
38
+
39
+ // Only allow requests from same origin
40
+ if (origin && !origin.includes(host || "")) {
41
+ return NextResponse.json(
42
+ { error: "Invalid origin" },
43
+ { status: 403 }
44
+ );
45
+ }
46
+
47
+ // 2. Create response
48
+ const response = NextResponse.json(
49
+ { success: true, message: "Token cleared successfully" },
50
+ { status: 200 }
51
+ );
52
+
53
+ // 3. Clear cookie by setting maxAge to 0
54
+ response.cookies.set({
55
+ name: AUTH_COOKIE_CONFIG.name,
56
+ value: "",
57
+ maxAge: 0, // Expire immediately
58
+ path: AUTH_COOKIE_CONFIG.path,
59
+ sameSite: AUTH_COOKIE_CONFIG.sameSite,
60
+ secure: AUTH_COOKIE_CONFIG.secure,
61
+ httpOnly: AUTH_COOKIE_CONFIG.httpOnly,
62
+ });
63
+
64
+ return response;
65
+ } catch (error) {
66
+ console.error("Error clearing auth token:", error);
67
+ return NextResponse.json(
68
+ { error: "Internal server error" },
69
+ { status: 500 }
70
+ );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * OPTIONS /api/auth/clear-token
76
+ *
77
+ * Handle preflight requests for CORS.
78
+ */
79
+ export async function OPTIONS() {
80
+ return new NextResponse(null, {
81
+ status: 204,
82
+ headers: {
83
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
84
+ "Access-Control-Allow-Headers": "Content-Type",
85
+ },
86
+ });
87
+ }