@doswiftly/cli 0.1.18 → 0.1.19

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 (210) 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.map +1 -1
  5. package/dist/commands/deploy.js +39 -20
  6. package/dist/commands/deploy.js.map +1 -1
  7. package/dist/commands/doctor.js +3 -3
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/init.js +4 -4
  10. package/dist/commands/sdk.js +5 -5
  11. package/dist/commands/sdk.js.map +1 -1
  12. package/dist/commands/template.js +4 -4
  13. package/dist/commands/template.js.map +1 -1
  14. package/dist/commands/types.js +5 -5
  15. package/dist/commands/types.js.map +1 -1
  16. package/dist/commands/verify.js +2 -2
  17. package/dist/commands/verify.js.map +1 -1
  18. package/dist/lib/package-manager.d.ts +1 -1
  19. package/dist/lib/package-manager.js +1 -1
  20. package/package.json +1 -1
  21. package/templates/storefront-nextjs/README.md +16 -12
  22. package/templates/storefront-nextjs/app/account/orders/page.tsx +2 -2
  23. package/templates/storefront-nextjs/app/account/page.tsx +2 -2
  24. package/templates/storefront-nextjs/app/auth/login/page.tsx +1 -1
  25. package/templates/storefront-nextjs/app/auth/register/page.tsx +1 -1
  26. package/templates/storefront-nextjs/app/cart/page.tsx +1 -1
  27. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +2 -2
  28. package/templates/storefront-nextjs/app/categories/page.tsx +1 -1
  29. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +1 -1
  30. package/templates/storefront-nextjs/app/collections/page.tsx +1 -1
  31. package/templates/storefront-nextjs/app/page.tsx +1 -1
  32. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +1 -1
  33. package/templates/storefront-nextjs/app/products/page.tsx +2 -2
  34. package/templates/storefront-nextjs/app/search/page.tsx +1 -1
  35. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +1 -1
  36. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +1 -1
  37. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +1 -1
  38. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +2 -2
  39. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +1 -1
  40. package/templates/storefront-nextjs/components/commerce/product-price.tsx +1 -1
  41. package/templates/storefront-nextjs/components/commerce/search-input.tsx +1 -1
  42. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +1 -1
  43. package/templates/storefront-nextjs/components/providers.tsx +1 -1
  44. package/templates/storefront-nextjs/lib/currency.tsx +3 -3
  45. package/templates/storefront-nextjs/lib/format.ts +1 -1
  46. package/templates/storefront-nextjs/lib/graphql-queries.ts +3 -3
  47. package/templates/storefront-nextjs/package.dev.json +1 -1
  48. package/templates/storefront-nextjs/package.json +1 -1
  49. package/templates/storefront-nextjs/package.json.template +1 -1
  50. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +47 -0
  51. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +47 -0
  52. package/templates/storefront-nextjs-shadcn/CLAUDE.md +148 -35
  53. package/templates/storefront-nextjs-shadcn/README.md +29 -162
  54. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +98 -91
  55. package/templates/storefront-nextjs-shadcn/app/account/error.tsx +43 -0
  56. package/templates/storefront-nextjs-shadcn/app/account/loading.tsx +19 -0
  57. package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +53 -162
  58. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/loading.tsx +60 -0
  59. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +36 -47
  60. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +46 -29
  61. package/templates/storefront-nextjs-shadcn/app/account/page.tsx +8 -5
  62. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +108 -71
  63. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +2 -86
  64. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +2 -124
  65. package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +10 -5
  66. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/loading.tsx +17 -0
  67. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +43 -2
  68. package/templates/storefront-nextjs-shadcn/app/blog/loading.tsx +19 -0
  69. package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +2 -1
  70. package/templates/storefront-nextjs-shadcn/app/cart/loading.tsx +26 -0
  71. package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +6 -3
  72. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/category-products-client.tsx +56 -0
  73. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/loading.tsx +32 -0
  74. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +76 -59
  75. package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +8 -4
  76. package/templates/storefront-nextjs-shadcn/app/checkout/error.tsx +43 -0
  77. package/templates/storefront-nextjs-shadcn/app/checkout/loading.tsx +31 -0
  78. package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +116 -79
  79. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/loading.tsx +19 -0
  80. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +1 -1
  81. package/templates/storefront-nextjs-shadcn/app/collections/loading.tsx +18 -0
  82. package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +7 -4
  83. package/templates/storefront-nextjs-shadcn/app/global-error.tsx +117 -0
  84. package/templates/storefront-nextjs-shadcn/app/globals.css +8 -0
  85. package/templates/storefront-nextjs-shadcn/app/layout.tsx +46 -11
  86. package/templates/storefront-nextjs-shadcn/app/products/[slug]/error.tsx +43 -0
  87. package/templates/storefront-nextjs-shadcn/app/products/[slug]/loading.tsx +29 -0
  88. package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +6 -6
  89. package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +15 -61
  90. package/templates/storefront-nextjs-shadcn/app/products/loading.tsx +32 -0
  91. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +405 -151
  92. package/templates/storefront-nextjs-shadcn/app/search/loading.tsx +18 -0
  93. package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +8 -5
  94. package/templates/storefront-nextjs-shadcn/codegen.ts +48 -31
  95. package/templates/storefront-nextjs-shadcn/components/account/customer-info.fragment.graphql +36 -0
  96. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +3 -1
  97. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +26 -24
  98. package/templates/storefront-nextjs-shadcn/components/account/order-summary.fragment.graphql +36 -0
  99. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +9 -9
  100. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +11 -37
  101. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +37 -23
  102. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +4 -3
  103. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +8 -5
  104. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +1 -1
  105. package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +53 -0
  106. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +1 -1
  107. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +22 -7
  108. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +2 -2
  109. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +1 -1
  110. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +2 -2
  111. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +35 -11
  112. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +1 -1
  113. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +3 -3
  114. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +5 -5
  115. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +2 -2
  116. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +2 -1
  117. package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +21 -0
  118. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +2 -12
  119. package/templates/storefront-nextjs-shadcn/components/home/index.ts +0 -1
  120. package/templates/storefront-nextjs-shadcn/components/hydrated.tsx +24 -0
  121. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +4 -4
  122. package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +22 -0
  123. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +2 -2
  124. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +33 -23
  125. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +2 -11
  126. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +8 -25
  127. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +10 -19
  128. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +17 -41
  129. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +2 -29
  130. package/templates/storefront-nextjs-shadcn/components/order/index.ts +6 -1
  131. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +3 -1
  132. package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +69 -0
  133. package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +84 -0
  134. package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +138 -0
  135. package/templates/storefront-nextjs-shadcn/components/product/index.ts +9 -2
  136. package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +49 -0
  137. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +3 -31
  138. package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +52 -0
  139. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +176 -123
  140. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +3 -5
  141. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +2 -2
  142. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +2 -2
  143. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +5 -4
  144. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +19 -7
  145. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +8 -23
  146. package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +51 -0
  147. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +1 -1
  148. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +1 -7
  149. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +17 -2
  150. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +3 -2
  151. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +1 -1
  152. package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +30 -0
  153. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +1 -1
  154. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +2 -2
  155. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +3 -2
  156. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +3 -2
  157. package/templates/storefront-nextjs-shadcn/components/ui/form.tsx +174 -0
  158. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +30 -2
  159. package/templates/storefront-nextjs-shadcn/components/ui/progress.tsx +40 -0
  160. package/templates/storefront-nextjs-shadcn/components/ui/sheet.tsx +107 -0
  161. package/templates/storefront-nextjs-shadcn/components/ui/slider.tsx +33 -0
  162. package/templates/storefront-nextjs-shadcn/components/ui/textarea.tsx +24 -0
  163. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +3 -1
  164. package/templates/storefront-nextjs-shadcn/generated/graphql.ts +12779 -0
  165. package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +159 -0
  166. package/templates/storefront-nextjs-shadcn/hooks/index.ts +2 -0
  167. package/templates/storefront-nextjs-shadcn/hooks/use-auth-sync.ts +42 -0
  168. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +17 -295
  169. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +51 -19
  170. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +13 -9
  171. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +4 -17
  172. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +22 -99
  173. package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +32 -0
  174. package/templates/storefront-nextjs-shadcn/lib/graphql/fragments.ts +34 -0
  175. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +687 -632
  176. package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +86 -0
  177. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +131 -182
  178. package/templates/storefront-nextjs-shadcn/lib/graphql/types.ts +62 -0
  179. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +0 -17
  180. package/templates/storefront-nextjs-shadcn/next-env.d.ts +6 -0
  181. package/templates/storefront-nextjs-shadcn/package.dev.json +1 -3
  182. package/templates/storefront-nextjs-shadcn/package.json +12 -13
  183. package/templates/storefront-nextjs-shadcn/package.json.template +6 -7
  184. package/templates/storefront-nextjs-shadcn/proxy.ts +3 -4
  185. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +41 -39
  186. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +64 -75
  187. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +178 -177
  188. package/templates/storefront-nextjs-shadcn/tsconfig.json +23 -5
  189. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +0 -282
  190. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +0 -190
  191. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +0 -263
  192. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +0 -135
  193. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +0 -142
  194. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +0 -448
  195. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +0 -307
  196. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +0 -245
  197. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +0 -103
  198. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +0 -168
  199. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +0 -160
  200. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +0 -220
  201. package/templates/storefront-nextjs-shadcn/lib/config.ts +0 -46
  202. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +0 -254
  203. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +0 -464
  204. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +0 -328
  205. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +0 -295
  206. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +0 -27
  207. package/templates/storefront-nextjs-shadcn/lib/format.ts +0 -226
  208. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +0 -30
  209. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +0 -66
  210. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +0 -103
@@ -1,226 +0,0 @@
1
- /**
2
- * Formatting Utilities
3
- *
4
- * Common formatting functions for prices, dates, etc.
5
- */
6
-
7
- // ============================================================================
8
- // TYPES
9
- // ============================================================================
10
-
11
- export interface PriceMoney {
12
- amount: string;
13
- currencyCode: string;
14
- }
15
-
16
- export type Money = PriceMoney;
17
-
18
- // ============================================================================
19
- // CONSTANTS
20
- // ============================================================================
21
-
22
- /** Currency symbols mapping */
23
- export const CURRENCY_SYMBOLS: Record<string, string> = {
24
- PLN: "zł",
25
- EUR: "€",
26
- USD: "$",
27
- GBP: "£",
28
- CHF: "CHF",
29
- CZK: "Kč",
30
- SEK: "kr",
31
- NOK: "kr",
32
- DKK: "kr",
33
- JPY: "¥",
34
- CNY: "¥",
35
- AUD: "A$",
36
- CAD: "C$",
37
- };
38
-
39
- /** Currency locale mapping for proper formatting */
40
- export const CURRENCY_LOCALES: Record<string, string> = {
41
- PLN: "pl-PL",
42
- EUR: "de-DE",
43
- USD: "en-US",
44
- GBP: "en-GB",
45
- CHF: "de-CH",
46
- CZK: "cs-CZ",
47
- SEK: "sv-SE",
48
- NOK: "nb-NO",
49
- DKK: "da-DK",
50
- JPY: "ja-JP",
51
- CNY: "zh-CN",
52
- AUD: "en-AU",
53
- CAD: "en-CA",
54
- };
55
-
56
- // ============================================================================
57
- // UTILITY FUNCTIONS
58
- // ============================================================================
59
-
60
- /**
61
- * Get currency symbol
62
- */
63
- export function getCurrencySymbol(code: string): string {
64
- return CURRENCY_SYMBOLS[code] || code;
65
- }
66
-
67
-
68
- // ============================================================================
69
- // PRICE FORMATTING
70
- // ============================================================================
71
-
72
- /**
73
- * Format price with currency symbol
74
- *
75
- * @example
76
- * ```typescript
77
- * formatPrice({ amount: "99.99", currencyCode: "USD" })
78
- * // => "$99.99"
79
- * ```
80
- */
81
- export function formatPrice(price: PriceMoney | Money | null | undefined): string {
82
- if (!price) return "";
83
-
84
- const amount = parseFloat(price.amount);
85
- const code = price.currencyCode;
86
- const locale = CURRENCY_LOCALES[code] || "en-US";
87
-
88
- try {
89
- return new Intl.NumberFormat(locale, {
90
- style: "currency",
91
- currency: code,
92
- minimumFractionDigits: 2,
93
- maximumFractionDigits: 2,
94
- }).format(amount);
95
- } catch {
96
- // Fallback formatting
97
- const symbol = CURRENCY_SYMBOLS[code] || code;
98
- return `${amount.toFixed(2)} ${symbol}`;
99
- }
100
- }
101
-
102
- /**
103
- * Format price range
104
- *
105
- * @example
106
- * ```typescript
107
- * formatPriceRange(
108
- * { amount: "10.00", currencyCode: "USD" },
109
- * { amount: "50.00", currencyCode: "USD" }
110
- * )
111
- * // => "$10.00 - $50.00"
112
- * ```
113
- */
114
- export function formatPriceRange(
115
- minPrice: PriceMoney | Money,
116
- maxPrice: PriceMoney | Money
117
- ): string {
118
- if (minPrice.amount === maxPrice.amount) {
119
- return formatPrice(minPrice);
120
- }
121
-
122
- return `${formatPrice(minPrice)} - ${formatPrice(maxPrice)}`;
123
- }
124
-
125
- /**
126
- * Format amount with currency
127
- *
128
- * @example
129
- * ```tsx
130
- * const formatted = formatAmount("115.20", "EUR");
131
- * // => "115,20 €"
132
- * ```
133
- */
134
- export function formatAmount(
135
- amount: string | number,
136
- currencyCode: string
137
- ): string {
138
- const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
139
- const locale = CURRENCY_LOCALES[currencyCode] || "en-US";
140
-
141
- try {
142
- return new Intl.NumberFormat(locale, {
143
- style: "currency",
144
- currency: currencyCode,
145
- minimumFractionDigits: 2,
146
- maximumFractionDigits: 2,
147
- }).format(numAmount);
148
- } catch {
149
- const symbol = CURRENCY_SYMBOLS[currencyCode] || currencyCode;
150
- return `${numAmount.toFixed(2)} ${symbol}`;
151
- }
152
- }
153
-
154
- // ============================================================================
155
- // DATE FORMATTING
156
- // ============================================================================
157
-
158
- /**
159
- * Format date to locale string
160
- *
161
- * @example
162
- * ```typescript
163
- * formatDate(new Date())
164
- * // => "Dec 9, 2025"
165
- * ```
166
- */
167
- export function formatDate(date: Date | string): string {
168
- const d = typeof date === "string" ? new Date(date) : date;
169
-
170
- return new Intl.DateTimeFormat("en-US", {
171
- year: "numeric",
172
- month: "short",
173
- day: "numeric",
174
- }).format(d);
175
- }
176
-
177
- /**
178
- * Format date with time
179
- *
180
- * @example
181
- * ```typescript
182
- * formatDateTime(new Date())
183
- * // => "Dec 9, 2025, 10:30 PM"
184
- * ```
185
- */
186
- export function formatDateTime(date: Date | string): string {
187
- const d = typeof date === "string" ? new Date(date) : date;
188
-
189
- return new Intl.DateTimeFormat("en-US", {
190
- year: "numeric",
191
- month: "short",
192
- day: "numeric",
193
- hour: "numeric",
194
- minute: "2-digit",
195
- }).format(d);
196
- }
197
-
198
- // ============================================================================
199
- // NUMBER FORMATTING
200
- // ============================================================================
201
-
202
- /**
203
- * Format number with thousands separator
204
- *
205
- * @example
206
- * ```typescript
207
- * formatNumber(1234567)
208
- * // => "1,234,567"
209
- * ```
210
- */
211
- export function formatNumber(num: number): string {
212
- return new Intl.NumberFormat("en-US").format(num);
213
- }
214
-
215
- /**
216
- * Format percentage
217
- *
218
- * @example
219
- * ```typescript
220
- * formatPercentage(0.15)
221
- * // => "15%"
222
- * ```
223
- */
224
- export function formatPercentage(value: number): string {
225
- return `${Math.round(value * 100)}%`;
226
- }
@@ -1,30 +0,0 @@
1
- import { useState, useEffect } from "react";
2
-
3
- /**
4
- * useDebouncedValue - Debounce a value
5
- *
6
- * @param value - Value to debounce
7
- * @param delay - Delay in ms (default: 300)
8
- * @returns Debounced value
9
- *
10
- * @example
11
- * ```tsx
12
- * const [query, setQuery] = useState("");
13
- * const debouncedQuery = useDebouncedValue(query, 300);
14
- *
15
- * // debouncedQuery updates 300ms after query stops changing
16
- * ```
17
- */
18
- export function useDebouncedValue<T>(value: T, delay = 300): T {
19
- const [debouncedValue, setDebouncedValue] = useState(value);
20
-
21
- useEffect(() => {
22
- const timer = setTimeout(() => {
23
- setDebouncedValue(value);
24
- }, delay);
25
-
26
- return () => clearTimeout(timer);
27
- }, [value, delay]);
28
-
29
- return debouncedValue;
30
- }
@@ -1,66 +0,0 @@
1
- import { create } from "zustand";
2
- import { persist } from "zustand/middleware";
3
-
4
- export interface Customer {
5
- id: string;
6
- email: string;
7
- firstName?: string;
8
- lastName?: string;
9
- phone?: string;
10
- }
11
-
12
- interface AuthStore {
13
- // State
14
- customer: Customer | null;
15
- accessToken: string | null;
16
- isAuthenticated: boolean;
17
- isLoading: boolean;
18
-
19
- // Actions
20
- setAuth: (customer: Customer, accessToken: string) => void;
21
- clearAuth: () => void;
22
- updateCustomer: (customer: Partial<Customer>) => void;
23
- setLoading: (isLoading: boolean) => void;
24
- }
25
-
26
- export const useAuthStore = create<AuthStore>()(
27
- persist(
28
- (set) => ({
29
- customer: null,
30
- accessToken: null,
31
- isAuthenticated: false,
32
- isLoading: false,
33
-
34
- setAuth: (customer, accessToken) =>
35
- set({
36
- customer,
37
- accessToken,
38
- isAuthenticated: true,
39
- }),
40
-
41
- clearAuth: () =>
42
- set({
43
- customer: null,
44
- accessToken: null,
45
- isAuthenticated: false,
46
- }),
47
-
48
- updateCustomer: (updates) =>
49
- set((state) => ({
50
- customer: state.customer
51
- ? { ...state.customer, ...updates }
52
- : null,
53
- })),
54
-
55
- setLoading: (isLoading) => set({ isLoading }),
56
- }),
57
- {
58
- name: "auth-storage",
59
- partialize: (state) => ({
60
- customer: state.customer,
61
- accessToken: state.accessToken,
62
- isAuthenticated: state.isAuthenticated,
63
- }),
64
- }
65
- )
66
- );
@@ -1,103 +0,0 @@
1
- import { create } from 'zustand';
2
- import { getCookieManager } from '@/lib/currency/';
3
-
4
- export interface ShopCurrencyData {
5
- currencyCode: string;
6
- supportedCurrencies: string[];
7
- localeToCurrencyMap?: Array<{
8
- locale: string;
9
- currency: string;
10
- }>;
11
- }
12
-
13
- interface CurrencyStore {
14
- // State
15
- baseCurrency: string | null;
16
- supportedCurrencies: string[];
17
- currency: string | null;
18
- isLoaded: boolean;
19
- isHydrated: boolean; // Alias for isLoaded (for compatibility)
20
-
21
- // Actions
22
- initialize: (shopData: ShopCurrencyData) => void;
23
- setCurrency: (currency: string) => void;
24
-
25
- // Internal
26
- _syncFromCookie: () => void;
27
- }
28
-
29
- export const useCurrencyStore = create<CurrencyStore>()((set, get) => ({
30
- baseCurrency: null,
31
- supportedCurrencies: [],
32
- currency: null,
33
- isLoaded: false,
34
- isHydrated: false,
35
-
36
- initialize: (shopData: ShopCurrencyData) => {
37
- const cookieManager = getCookieManager();
38
-
39
- // 1. Try to get saved currency from cookie (SSR-safe)
40
- const saved = cookieManager.getCurrency();
41
-
42
- // 2. Try to detect from browser locale (if localeToCurrencyMap is available)
43
- let detected: { locale: string; currency: string } | undefined;
44
- if (shopData.localeToCurrencyMap && typeof navigator !== 'undefined') {
45
- const browserLocale = navigator.language;
46
- detected = shopData.localeToCurrencyMap.find(
47
- (m) => m.locale === browserLocale
48
- );
49
- }
50
-
51
- // 3. Determine final currency (priority: saved > detected > base)
52
- const finalCurrency =
53
- saved && shopData.supportedCurrencies.includes(saved)
54
- ? saved
55
- : detected && shopData.supportedCurrencies.includes(detected.currency)
56
- ? detected.currency
57
- : shopData.currencyCode;
58
-
59
- set({
60
- baseCurrency: shopData.currencyCode,
61
- supportedCurrencies: shopData.supportedCurrencies,
62
- currency: finalCurrency,
63
- isLoaded: true,
64
- isHydrated: true,
65
- });
66
-
67
- // Ensure cookie is set if we determined a currency
68
- if (finalCurrency && !saved) {
69
- cookieManager.setCurrency(finalCurrency);
70
- }
71
- },
72
-
73
- setCurrency: (currency: string) => {
74
- const { supportedCurrencies } = get();
75
-
76
- // Validate currency
77
- if (!supportedCurrencies.includes(currency)) {
78
- console.warn(`[CurrencyStore] Currency ${currency} not supported`);
79
- return;
80
- }
81
-
82
- // Update Zustand state
83
- set({ currency });
84
-
85
- // Persist to cookie (single source of truth)
86
- const cookieManager = getCookieManager();
87
- cookieManager.setCurrency(currency);
88
- },
89
-
90
- _syncFromCookie: () => {
91
- const cookieManager = getCookieManager();
92
- const cookieCurrency = cookieManager.getCurrency();
93
-
94
- if (cookieCurrency) {
95
- const { supportedCurrencies } = get();
96
-
97
- // Only sync if the cookie currency is supported
98
- if (supportedCurrencies.includes(cookieCurrency)) {
99
- set({ currency: cookieCurrency });
100
- }
101
- }
102
- },
103
- }));