@doswiftly/cli 0.1.17 → 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 (213) 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 +43 -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-minimal/wrangler.toml +4 -0
  22. package/templates/storefront-nextjs/README.md +16 -12
  23. package/templates/storefront-nextjs/app/account/orders/page.tsx +2 -2
  24. package/templates/storefront-nextjs/app/account/page.tsx +2 -2
  25. package/templates/storefront-nextjs/app/auth/login/page.tsx +1 -1
  26. package/templates/storefront-nextjs/app/auth/register/page.tsx +1 -1
  27. package/templates/storefront-nextjs/app/cart/page.tsx +1 -1
  28. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +2 -2
  29. package/templates/storefront-nextjs/app/categories/page.tsx +1 -1
  30. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +1 -1
  31. package/templates/storefront-nextjs/app/collections/page.tsx +1 -1
  32. package/templates/storefront-nextjs/app/page.tsx +1 -1
  33. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +1 -1
  34. package/templates/storefront-nextjs/app/products/page.tsx +2 -2
  35. package/templates/storefront-nextjs/app/search/page.tsx +1 -1
  36. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +1 -1
  37. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +1 -1
  38. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +1 -1
  39. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +2 -2
  40. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +1 -1
  41. package/templates/storefront-nextjs/components/commerce/product-price.tsx +1 -1
  42. package/templates/storefront-nextjs/components/commerce/search-input.tsx +1 -1
  43. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +1 -1
  44. package/templates/storefront-nextjs/components/providers.tsx +1 -1
  45. package/templates/storefront-nextjs/lib/currency.tsx +3 -3
  46. package/templates/storefront-nextjs/lib/format.ts +1 -1
  47. package/templates/storefront-nextjs/lib/graphql-queries.ts +3 -3
  48. package/templates/storefront-nextjs/package.dev.json +1 -1
  49. package/templates/storefront-nextjs/package.json +1 -1
  50. package/templates/storefront-nextjs/package.json.template +1 -1
  51. package/templates/storefront-nextjs/wrangler.toml +4 -0
  52. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +47 -0
  53. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +47 -0
  54. package/templates/storefront-nextjs-shadcn/CLAUDE.md +148 -35
  55. package/templates/storefront-nextjs-shadcn/README.md +29 -162
  56. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +98 -91
  57. package/templates/storefront-nextjs-shadcn/app/account/error.tsx +43 -0
  58. package/templates/storefront-nextjs-shadcn/app/account/loading.tsx +19 -0
  59. package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +53 -162
  60. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/loading.tsx +60 -0
  61. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +36 -47
  62. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +46 -29
  63. package/templates/storefront-nextjs-shadcn/app/account/page.tsx +8 -5
  64. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +108 -71
  65. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +2 -86
  66. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +2 -124
  67. package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +10 -5
  68. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/loading.tsx +17 -0
  69. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +43 -2
  70. package/templates/storefront-nextjs-shadcn/app/blog/loading.tsx +19 -0
  71. package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +2 -1
  72. package/templates/storefront-nextjs-shadcn/app/cart/loading.tsx +26 -0
  73. package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +6 -3
  74. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/category-products-client.tsx +56 -0
  75. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/loading.tsx +32 -0
  76. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +76 -59
  77. package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +8 -4
  78. package/templates/storefront-nextjs-shadcn/app/checkout/error.tsx +43 -0
  79. package/templates/storefront-nextjs-shadcn/app/checkout/loading.tsx +31 -0
  80. package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +116 -79
  81. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/loading.tsx +19 -0
  82. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +1 -1
  83. package/templates/storefront-nextjs-shadcn/app/collections/loading.tsx +18 -0
  84. package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +7 -4
  85. package/templates/storefront-nextjs-shadcn/app/global-error.tsx +117 -0
  86. package/templates/storefront-nextjs-shadcn/app/globals.css +8 -0
  87. package/templates/storefront-nextjs-shadcn/app/layout.tsx +46 -11
  88. package/templates/storefront-nextjs-shadcn/app/products/[slug]/error.tsx +43 -0
  89. package/templates/storefront-nextjs-shadcn/app/products/[slug]/loading.tsx +29 -0
  90. package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +6 -6
  91. package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +15 -61
  92. package/templates/storefront-nextjs-shadcn/app/products/loading.tsx +32 -0
  93. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +405 -151
  94. package/templates/storefront-nextjs-shadcn/app/search/loading.tsx +18 -0
  95. package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +8 -5
  96. package/templates/storefront-nextjs-shadcn/codegen.ts +48 -31
  97. package/templates/storefront-nextjs-shadcn/components/account/customer-info.fragment.graphql +36 -0
  98. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +3 -1
  99. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +26 -24
  100. package/templates/storefront-nextjs-shadcn/components/account/order-summary.fragment.graphql +36 -0
  101. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +9 -9
  102. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +11 -37
  103. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +37 -23
  104. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +4 -3
  105. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +8 -5
  106. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +1 -1
  107. package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +53 -0
  108. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +1 -1
  109. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +22 -7
  110. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +2 -2
  111. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +1 -1
  112. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +2 -2
  113. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +35 -11
  114. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +1 -1
  115. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +3 -3
  116. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +5 -5
  117. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +2 -2
  118. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +2 -1
  119. package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +21 -0
  120. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +2 -12
  121. package/templates/storefront-nextjs-shadcn/components/home/index.ts +0 -1
  122. package/templates/storefront-nextjs-shadcn/components/hydrated.tsx +24 -0
  123. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +4 -4
  124. package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +22 -0
  125. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +2 -2
  126. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +33 -23
  127. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +2 -11
  128. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +8 -25
  129. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +10 -19
  130. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +17 -41
  131. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +2 -29
  132. package/templates/storefront-nextjs-shadcn/components/order/index.ts +6 -1
  133. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +3 -1
  134. package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +69 -0
  135. package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +84 -0
  136. package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +138 -0
  137. package/templates/storefront-nextjs-shadcn/components/product/index.ts +9 -2
  138. package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +49 -0
  139. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +3 -31
  140. package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +52 -0
  141. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +176 -123
  142. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +3 -5
  143. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +2 -2
  144. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +2 -2
  145. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +5 -4
  146. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +19 -7
  147. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +8 -23
  148. package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +51 -0
  149. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +1 -1
  150. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +1 -7
  151. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +17 -2
  152. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +3 -2
  153. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +1 -1
  154. package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +30 -0
  155. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +1 -1
  156. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +2 -2
  157. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +3 -2
  158. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +3 -2
  159. package/templates/storefront-nextjs-shadcn/components/ui/form.tsx +174 -0
  160. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +30 -2
  161. package/templates/storefront-nextjs-shadcn/components/ui/progress.tsx +40 -0
  162. package/templates/storefront-nextjs-shadcn/components/ui/sheet.tsx +107 -0
  163. package/templates/storefront-nextjs-shadcn/components/ui/slider.tsx +33 -0
  164. package/templates/storefront-nextjs-shadcn/components/ui/textarea.tsx +24 -0
  165. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +3 -1
  166. package/templates/storefront-nextjs-shadcn/generated/graphql.ts +12779 -0
  167. package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +159 -0
  168. package/templates/storefront-nextjs-shadcn/hooks/index.ts +2 -0
  169. package/templates/storefront-nextjs-shadcn/hooks/use-auth-sync.ts +42 -0
  170. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +17 -295
  171. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +51 -19
  172. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +13 -9
  173. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +4 -17
  174. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +22 -99
  175. package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +32 -0
  176. package/templates/storefront-nextjs-shadcn/lib/graphql/fragments.ts +34 -0
  177. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +687 -632
  178. package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +86 -0
  179. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +131 -182
  180. package/templates/storefront-nextjs-shadcn/lib/graphql/types.ts +62 -0
  181. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +0 -17
  182. package/templates/storefront-nextjs-shadcn/next-env.d.ts +6 -0
  183. package/templates/storefront-nextjs-shadcn/package.dev.json +1 -3
  184. package/templates/storefront-nextjs-shadcn/package.json +12 -13
  185. package/templates/storefront-nextjs-shadcn/package.json.template +6 -7
  186. package/templates/storefront-nextjs-shadcn/proxy.ts +3 -4
  187. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +41 -39
  188. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +64 -75
  189. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +178 -177
  190. package/templates/storefront-nextjs-shadcn/tsconfig.json +23 -5
  191. package/templates/storefront-nextjs-shadcn/wrangler.toml +4 -0
  192. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +0 -282
  193. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +0 -190
  194. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +0 -263
  195. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +0 -135
  196. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +0 -142
  197. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +0 -448
  198. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +0 -307
  199. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +0 -245
  200. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +0 -103
  201. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +0 -168
  202. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +0 -160
  203. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +0 -220
  204. package/templates/storefront-nextjs-shadcn/lib/config.ts +0 -46
  205. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +0 -254
  206. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +0 -464
  207. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +0 -328
  208. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +0 -295
  209. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +0 -27
  210. package/templates/storefront-nextjs-shadcn/lib/format.ts +0 -226
  211. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +0 -30
  212. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +0 -66
  213. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +0 -103
@@ -11,8 +11,9 @@
11
11
  * - Multiple wishlist support
12
12
  */
13
13
 
14
- import { create } from 'zustand';
14
+ import { createStore } from 'zustand/vanilla';
15
15
  import { persist } from 'zustand/middleware';
16
+ import { createStoreContext } from '@doswiftly/storefront-sdk/react';
16
17
 
17
18
  export interface WishlistItem {
18
19
  id: string;
@@ -52,7 +53,6 @@ export interface WishlistState {
52
53
  // State
53
54
  wishlists: Wishlist[];
54
55
  activeWishlistId: string | null;
55
- isHydrated: boolean;
56
56
  isSyncing: boolean;
57
57
 
58
58
  // Actions
@@ -81,211 +81,212 @@ const generateTempId = () => `temp_${Date.now()}_${Math.random().toString(36).su
81
81
  // Default wishlist name
82
82
  const DEFAULT_WISHLIST_NAME = 'My Wishlist';
83
83
 
84
- export const useWishlistStore = create<WishlistState>()(
85
- persist(
86
- (set, get) => ({
87
- wishlists: [],
88
- activeWishlistId: null,
89
- isHydrated: false,
90
- isSyncing: false,
84
+ export function createWishlistStore() {
85
+ return createStore<WishlistState>()(
86
+ persist(
87
+ (set, get) => ({
88
+ wishlists: [],
89
+ activeWishlistId: null,
90
+ isSyncing: false,
91
91
 
92
- setWishlists: (wishlists: Wishlist[]) => {
93
- set({ wishlists });
94
- // Set active wishlist to first one if not set
95
- if (!get().activeWishlistId && wishlists.length > 0) {
96
- set({ activeWishlistId: wishlists[0].id });
97
- }
98
- },
92
+ setWishlists: (wishlists: Wishlist[]) => {
93
+ set({ wishlists });
94
+ // Set active wishlist to first one if not set
95
+ if (!get().activeWishlistId && wishlists.length > 0) {
96
+ set({ activeWishlistId: wishlists[0].id });
97
+ }
98
+ },
99
99
 
100
- setActiveWishlist: (wishlistId: string | null) => {
101
- set({ activeWishlistId: wishlistId });
102
- },
100
+ setActiveWishlist: (wishlistId: string | null) => {
101
+ set({ activeWishlistId: wishlistId });
102
+ },
103
103
 
104
- addWishlist: (wishlist: Wishlist) => {
105
- set((state) => ({
106
- wishlists: [...state.wishlists, wishlist],
107
- activeWishlistId: state.activeWishlistId || wishlist.id,
108
- }));
109
- },
104
+ addWishlist: (wishlist: Wishlist) => {
105
+ set((state) => ({
106
+ wishlists: [...state.wishlists, wishlist],
107
+ activeWishlistId: state.activeWishlistId || wishlist.id,
108
+ }));
109
+ },
110
110
 
111
- removeWishlist: (wishlistId: string) => {
112
- set((state) => {
113
- const remaining = state.wishlists.filter((w) => w.id !== wishlistId);
114
- return {
115
- wishlists: remaining,
116
- activeWishlistId:
117
- state.activeWishlistId === wishlistId
118
- ? remaining[0]?.id || null
119
- : state.activeWishlistId,
120
- };
121
- });
122
- },
111
+ removeWishlist: (wishlistId: string) => {
112
+ set((state) => {
113
+ const remaining = state.wishlists.filter((w) => w.id !== wishlistId);
114
+ return {
115
+ wishlists: remaining,
116
+ activeWishlistId:
117
+ state.activeWishlistId === wishlistId
118
+ ? remaining[0]?.id || null
119
+ : state.activeWishlistId,
120
+ };
121
+ });
122
+ },
123
123
 
124
- addItem: (wishlistId: string, item) => {
125
- set((state) => {
126
- // Find or create default wishlist
127
- let wishlists = [...state.wishlists];
128
- let targetWishlistId = wishlistId;
124
+ addItem: (wishlistId: string, item) => {
125
+ set((state) => {
126
+ // Find or create default wishlist
127
+ let wishlists = [...state.wishlists];
128
+ let targetWishlistId = wishlistId;
129
129
 
130
- // If no wishlist exists, create a default one
131
- if (wishlists.length === 0) {
132
- const newWishlist: Wishlist = {
133
- id: generateTempId(),
134
- name: DEFAULT_WISHLIST_NAME,
135
- isPublic: false,
136
- items: [],
137
- itemCount: 0,
138
- createdAt: new Date(),
139
- updatedAt: new Date(),
140
- };
141
- wishlists = [newWishlist];
142
- targetWishlistId = newWishlist.id;
143
- }
130
+ // If no wishlist exists, create a default one
131
+ if (wishlists.length === 0) {
132
+ const newWishlist: Wishlist = {
133
+ id: generateTempId(),
134
+ name: DEFAULT_WISHLIST_NAME,
135
+ isPublic: false,
136
+ items: [],
137
+ itemCount: 0,
138
+ createdAt: new Date(),
139
+ updatedAt: new Date(),
140
+ };
141
+ wishlists = [newWishlist];
142
+ targetWishlistId = newWishlist.id;
143
+ }
144
+
145
+ return {
146
+ wishlists: wishlists.map((w) => {
147
+ if (w.id === targetWishlistId) {
148
+ // Check if item already exists
149
+ const existingItem = w.items.find(
150
+ (i) =>
151
+ i.productId === item.productId &&
152
+ (item.variantId ? i.variantId === item.variantId : !i.variantId),
153
+ );
144
154
 
145
- return {
146
- wishlists: wishlists.map((w) => {
147
- if (w.id === targetWishlistId) {
148
- // Check if item already exists
149
- const existingItem = w.items.find(
150
- (i) =>
151
- i.productId === item.productId &&
152
- (item.variantId ? i.variantId === item.variantId : !i.variantId)
153
- );
155
+ if (existingItem) {
156
+ // Update existing item
157
+ return {
158
+ ...w,
159
+ items: w.items.map((i) =>
160
+ i.id === existingItem.id ? { ...i, ...item } : i,
161
+ ),
162
+ updatedAt: new Date(),
163
+ };
164
+ }
165
+
166
+ // Add new item
167
+ const newItem: WishlistItem = {
168
+ ...item,
169
+ id: generateTempId(),
170
+ addedAt: new Date(),
171
+ };
154
172
 
155
- if (existingItem) {
156
- // Update existing item
157
173
  return {
158
174
  ...w,
159
- items: w.items.map((i) =>
160
- i.id === existingItem.id ? { ...i, ...item } : i
161
- ),
175
+ items: [...w.items, newItem],
176
+ itemCount: w.itemCount + 1,
162
177
  updatedAt: new Date(),
163
178
  };
164
179
  }
180
+ return w;
181
+ }),
182
+ activeWishlistId: state.activeWishlistId || targetWishlistId,
183
+ };
184
+ });
185
+ },
165
186
 
166
- // Add new item
167
- const newItem: WishlistItem = {
168
- ...item,
169
- id: generateTempId(),
170
- addedAt: new Date(),
187
+ removeItem: (wishlistId: string, itemId: string) => {
188
+ set((state) => ({
189
+ wishlists: state.wishlists.map((w) => {
190
+ if (w.id === wishlistId) {
191
+ return {
192
+ ...w,
193
+ items: w.items.filter((i) => i.id !== itemId),
194
+ itemCount: Math.max(0, w.itemCount - 1),
195
+ updatedAt: new Date(),
171
196
  };
197
+ }
198
+ return w;
199
+ }),
200
+ }));
201
+ },
172
202
 
203
+ updateItem: (wishlistId: string, itemId: string, updates: Partial<WishlistItem>) => {
204
+ set((state) => ({
205
+ wishlists: state.wishlists.map((w) => {
206
+ if (w.id === wishlistId) {
173
207
  return {
174
208
  ...w,
175
- items: [...w.items, newItem],
176
- itemCount: w.itemCount + 1,
209
+ items: w.items.map((i) =>
210
+ i.id === itemId ? { ...i, ...updates } : i,
211
+ ),
177
212
  updatedAt: new Date(),
178
213
  };
179
214
  }
180
215
  return w;
181
216
  }),
182
- activeWishlistId: state.activeWishlistId || targetWishlistId,
183
- };
184
- });
185
- },
186
-
187
- removeItem: (wishlistId: string, itemId: string) => {
188
- set((state) => ({
189
- wishlists: state.wishlists.map((w) => {
190
- if (w.id === wishlistId) {
191
- return {
192
- ...w,
193
- items: w.items.filter((i) => i.id !== itemId),
194
- itemCount: Math.max(0, w.itemCount - 1),
195
- updatedAt: new Date(),
196
- };
197
- }
198
- return w;
199
- }),
200
- }));
201
- },
217
+ }));
218
+ },
202
219
 
203
- updateItem: (wishlistId: string, itemId: string, updates: Partial<WishlistItem>) => {
204
- set((state) => ({
205
- wishlists: state.wishlists.map((w) => {
206
- if (w.id === wishlistId) {
207
- return {
208
- ...w,
209
- items: w.items.map((i) =>
210
- i.id === itemId ? { ...i, ...updates } : i
211
- ),
212
- updatedAt: new Date(),
213
- };
214
- }
215
- return w;
216
- }),
217
- }));
218
- },
219
-
220
- clearWishlist: (wishlistId: string) => {
221
- set((state) => ({
222
- wishlists: state.wishlists.map((w) => {
223
- if (w.id === wishlistId) {
224
- return {
225
- ...w,
226
- items: [],
227
- itemCount: 0,
228
- updatedAt: new Date(),
229
- };
230
- }
231
- return w;
232
- }),
233
- }));
234
- },
220
+ clearWishlist: (wishlistId: string) => {
221
+ set((state) => ({
222
+ wishlists: state.wishlists.map((w) => {
223
+ if (w.id === wishlistId) {
224
+ return {
225
+ ...w,
226
+ items: [],
227
+ itemCount: 0,
228
+ updatedAt: new Date(),
229
+ };
230
+ }
231
+ return w;
232
+ }),
233
+ }));
234
+ },
235
235
 
236
- clearAll: () => {
237
- set({ wishlists: [], activeWishlistId: null });
238
- },
236
+ clearAll: () => {
237
+ set({ wishlists: [], activeWishlistId: null });
238
+ },
239
239
 
240
- setSyncing: (syncing: boolean) => {
241
- set({ isSyncing: syncing });
242
- },
240
+ setSyncing: (syncing: boolean) => {
241
+ set({ isSyncing: syncing });
242
+ },
243
243
 
244
- getActiveWishlist: () => {
245
- const state = get();
246
- return state.wishlists.find((w) => w.id === state.activeWishlistId);
247
- },
244
+ getActiveWishlist: () => {
245
+ const state = get();
246
+ return state.wishlists.find((w) => w.id === state.activeWishlistId);
247
+ },
248
248
 
249
- getWishlistById: (wishlistId: string) => {
250
- return get().wishlists.find((w) => w.id === wishlistId);
251
- },
249
+ getWishlistById: (wishlistId: string) => {
250
+ return get().wishlists.find((w) => w.id === wishlistId);
251
+ },
252
252
 
253
- isInWishlist: (productId: string, variantId?: string) => {
254
- return get().wishlists.some((w) =>
255
- w.items.some(
256
- (i) =>
257
- i.productId === productId &&
258
- (variantId ? i.variantId === variantId : true)
259
- )
260
- );
261
- },
253
+ isInWishlist: (productId: string, variantId?: string) => {
254
+ return get().wishlists.some((w) =>
255
+ w.items.some(
256
+ (i) =>
257
+ i.productId === productId &&
258
+ (variantId ? i.variantId === variantId : true),
259
+ ),
260
+ );
261
+ },
262
262
 
263
- getWishlistForProduct: (productId: string, variantId?: string) => {
264
- return get().wishlists.find((w) =>
265
- w.items.some(
266
- (i) =>
267
- i.productId === productId &&
268
- (variantId ? i.variantId === variantId : true)
269
- )
270
- );
271
- },
263
+ getWishlistForProduct: (productId: string, variantId?: string) => {
264
+ return get().wishlists.find((w) =>
265
+ w.items.some(
266
+ (i) =>
267
+ i.productId === productId &&
268
+ (variantId ? i.variantId === variantId : true),
269
+ ),
270
+ );
271
+ },
272
272
 
273
- getTotalItems: () => {
274
- return get().wishlists.reduce((total, w) => total + w.itemCount, 0);
275
- },
276
- }),
277
- {
278
- name: 'wishlist-storage',
279
- // Persist all wishlists
280
- partialize: (state) => ({
281
- wishlists: state.wishlists,
282
- activeWishlistId: state.activeWishlistId,
273
+ getTotalItems: () => {
274
+ return get().wishlists.reduce((total, w) => total + w.itemCount, 0);
275
+ },
283
276
  }),
284
- onRehydrateStorage: () => (state) => {
285
- if (state) {
286
- state.isHydrated = true;
287
- }
277
+ {
278
+ name: 'wishlist-storage',
279
+ partialize: (state) => ({
280
+ wishlists: state.wishlists,
281
+ activeWishlistId: state.activeWishlistId,
282
+ }),
288
283
  },
289
- }
290
- )
291
- );
284
+ ),
285
+ );
286
+ }
287
+
288
+ export const {
289
+ Provider: WishlistProvider,
290
+ useStore: useWishlistStore,
291
+ useApi: useWishlistStoreApi,
292
+ } = createStoreContext<WishlistState>('WishlistStore');
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2017",
4
- "lib": ["dom", "dom.iterable", "esnext"],
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
5
9
  "allowJs": true,
6
10
  "skipLibCheck": true,
7
11
  "strict": true,
@@ -11,7 +15,7 @@
11
15
  "moduleResolution": "bundler",
12
16
  "resolveJsonModule": true,
13
17
  "isolatedModules": true,
14
- "jsx": "preserve",
18
+ "jsx": "react-jsx",
15
19
  "incremental": true,
16
20
  "plugins": [
17
21
  {
@@ -19,9 +23,23 @@
19
23
  }
20
24
  ],
21
25
  "paths": {
22
- "@/*": ["./*"]
26
+ "@/*": [
27
+ "./*"
28
+ ]
23
29
  }
24
30
  },
25
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
- "exclude": ["node_modules"]
31
+ "include": [
32
+ "next-env.d.ts",
33
+ "**/*.ts",
34
+ "**/*.tsx",
35
+ ".next/types/**/*.ts",
36
+ ".next/dev/types/**/*.ts"
37
+ ],
38
+ "exclude": [
39
+ "node_modules",
40
+ "**/*.test.ts",
41
+ "**/*.test.tsx",
42
+ "**/*.spec.ts",
43
+ "**/*.spec.tsx"
44
+ ]
27
45
  }
@@ -7,3 +7,7 @@ compatibility_flags = ["nodejs_compat"]
7
7
 
8
8
  # Assets directory for static files
9
9
  assets = { directory = ".open-next/assets", binding = "ASSETS" }
10
+
11
+ # Cloudflare Images binding for Next.js /_next/image optimization
12
+ [images]
13
+ binding = "IMAGES"