create-brainerce-store 1.72.0 → 1.74.0

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 (88) hide show
  1. package/dist/index.js +37 -4
  2. package/messages/en.json +30 -1
  3. package/messages/he.json +30 -1
  4. package/package.json +1 -1
  5. package/templates/nextjs/base/AGENTS.md.ejs +63 -16
  6. package/templates/nextjs/base/AI-GUIDE.md +17 -4
  7. package/templates/nextjs/base/CLAUDE.md.ejs +67 -20
  8. package/templates/nextjs/base/TRANSLATIONS.md +207 -207
  9. package/templates/nextjs/base/src/app/account/page.tsx +168 -122
  10. package/templates/nextjs/base/src/app/category/[slug]/page.tsx +10 -1
  11. package/templates/nextjs/base/src/app/checkout/page.tsx +1179 -1074
  12. package/templates/nextjs/base/src/app/layout.tsx.ejs +48 -4
  13. package/templates/nextjs/base/src/app/order-confirmation/page.tsx +98 -3
  14. package/templates/nextjs/base/src/app/products/[slug]/page.tsx +14 -2
  15. package/templates/nextjs/base/src/components/account/loyalty-panel.tsx +226 -0
  16. package/templates/nextjs/base/src/components/account/order-history.tsx +422 -371
  17. package/templates/nextjs/base/src/components/account/order-status-timeline.tsx +85 -85
  18. package/templates/nextjs/base/src/components/account/saved-payment-methods.tsx +104 -0
  19. package/templates/nextjs/base/src/components/checkout/checkout-form.tsx +618 -612
  20. package/templates/nextjs/base/src/components/checkout/custom-fields-step.tsx +354 -306
  21. package/templates/nextjs/base/src/components/checkout/tax-display.tsx +141 -74
  22. package/templates/nextjs/base/src/core/hooks/use-cart-page.ts +218 -127
  23. package/templates/nextjs/base/src/core/hooks/use-home-data.ts +63 -51
  24. package/templates/nextjs/base/src/core/hooks/use-product-listing.ts +379 -295
  25. package/templates/nextjs/base/src/core/hooks/use-product-page.ts +33 -1
  26. package/templates/nextjs/base/src/core/lib/capabilities.ts +65 -0
  27. package/templates/nextjs/base/src/core/lib/display-price.ts +139 -0
  28. package/templates/nextjs/base/src/core/lib/region.server.ts +112 -0
  29. package/templates/nextjs/base/src/core/lib/region.ts +112 -0
  30. package/templates/nextjs/base/src/core/lib/store-info.ts +19 -0
  31. package/templates/nextjs/base/src/core/providers/store-provider.tsx.ejs +423 -243
  32. package/templates/nextjs/base/src/ui/cart/cart-item.tsx +174 -164
  33. package/templates/nextjs/base/src/ui/cart/cart-summary.tsx +109 -110
  34. package/templates/nextjs/base/src/ui/cart/cart-view.tsx +219 -176
  35. package/templates/nextjs/base/src/ui/cart/gift-card-input.tsx +191 -0
  36. package/templates/nextjs/base/src/ui/cart/reservation-countdown.tsx +137 -137
  37. package/templates/nextjs/base/src/ui/cart/tax-estimate-line.tsx +108 -0
  38. package/templates/nextjs/base/src/ui/home/home-client.tsx +27 -29
  39. package/templates/nextjs/base/src/ui/layout/header-search.tsx +249 -0
  40. package/templates/nextjs/base/src/ui/layout/region-switcher.tsx +59 -0
  41. package/templates/nextjs/base/src/ui/layout/site-header.tsx.ejs +171 -152
  42. package/templates/nextjs/base/src/ui/product/frequently-bought-together.tsx +197 -191
  43. package/templates/nextjs/base/src/ui/product/product-card.tsx +25 -52
  44. package/templates/nextjs/base/src/ui/product/product-client-section.tsx +12 -3
  45. package/templates/nextjs/base/src/ui/product/product-listing.tsx +460 -446
  46. package/templates/nextjs/base/src/ui/product/recommendation-section.tsx +108 -102
  47. package/templates/nextjs/base/src/ui/product/review-form.tsx +33 -11
  48. package/templates/nextjs/base/src/ui/product/stock-badge.tsx +15 -3
  49. package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +48 -4
  50. package/templates/nextjs/designs/atelier/messages-patch/en.json +21 -25
  51. package/templates/nextjs/designs/atelier/messages-patch/he.json +21 -25
  52. package/templates/nextjs/designs/atelier/ui/cart/cart-drawer.tsx +177 -181
  53. package/templates/nextjs/designs/atelier/ui/cart/cart-item.tsx +168 -158
  54. package/templates/nextjs/designs/atelier/ui/cart/cart-summary.tsx +106 -107
  55. package/templates/nextjs/designs/atelier/ui/cart/cart-view.tsx +229 -184
  56. package/templates/nextjs/designs/atelier/ui/cart/reservation-countdown.tsx +131 -131
  57. package/templates/nextjs/designs/atelier/ui/cart/tax-estimate-line.tsx +108 -0
  58. package/templates/nextjs/designs/atelier/ui/home/benefits-band.tsx +10 -1
  59. package/templates/nextjs/designs/atelier/ui/home/hero-section.tsx +178 -174
  60. package/templates/nextjs/designs/atelier/ui/home/home-client.tsx +4 -6
  61. package/templates/nextjs/designs/atelier/ui/home/newsletter-section.tsx +150 -78
  62. package/templates/nextjs/designs/atelier/ui/home/testimonials-band.tsx +79 -46
  63. package/templates/nextjs/designs/atelier/ui/layout/header-search.tsx +264 -0
  64. package/templates/nextjs/designs/atelier/ui/layout/region-switcher.tsx +44 -0
  65. package/templates/nextjs/designs/atelier/ui/layout/site-header.tsx.ejs +5 -0
  66. package/templates/nextjs/designs/atelier/ui/product/frequently-bought-together.tsx +202 -196
  67. package/templates/nextjs/designs/atelier/ui/product/product-card.tsx +27 -52
  68. package/templates/nextjs/designs/atelier/ui/product/product-client-section.tsx +12 -3
  69. package/templates/nextjs/designs/atelier/ui/product/product-listing.tsx +332 -260
  70. package/templates/nextjs/designs/atelier/ui/product/recommendation-section.tsx +101 -95
  71. package/templates/nextjs/designs/atelier/ui/product/review-form.tsx +30 -10
  72. package/templates/nextjs/designs/atelier/ui/product/stock-badge.tsx +17 -2
  73. package/templates/nextjs/designs/atelier/ui/shared/icons.tsx +9 -0
  74. package/templates/nextjs/ui-canvas/cart/cart-item.tsx +137 -137
  75. package/templates/nextjs/ui-canvas/cart/cart-summary.tsx +98 -99
  76. package/templates/nextjs/ui-canvas/cart/cart-view.tsx +140 -140
  77. package/templates/nextjs/ui-canvas/cart/gift-card-input.tsx +142 -0
  78. package/templates/nextjs/ui-canvas/cart/reservation-countdown.tsx +124 -124
  79. package/templates/nextjs/ui-canvas/cart/tax-estimate-line.tsx +104 -0
  80. package/templates/nextjs/ui-canvas/home/home-client.tsx +24 -26
  81. package/templates/nextjs/ui-canvas/layout/region-switcher.tsx +51 -0
  82. package/templates/nextjs/ui-canvas/layout/site-header.tsx.ejs +3 -0
  83. package/templates/nextjs/ui-canvas/product/frequently-bought-together.tsx +174 -168
  84. package/templates/nextjs/ui-canvas/product/product-card.tsx +9 -51
  85. package/templates/nextjs/ui-canvas/product/product-client-section.tsx +5 -3
  86. package/templates/nextjs/ui-canvas/product/recommendation-section.tsx +105 -99
  87. package/templates/nextjs/ui-canvas/product/review-form.tsx +9 -1
  88. package/templates/nextjs/ui-canvas/product/stock-badge.tsx +17 -2
@@ -1,51 +1,63 @@
1
- 'use client';
2
-
3
- import { useEffect, useState } from 'react';
4
- import type { Product, DiscountBanner } from 'brainerce';
5
- import { getClient } from '@/core/lib/brainerce';
6
-
7
- export interface UseHomeDataResult {
8
- /** Newest products for the featured grid (max 8). */
9
- products: Product[];
10
- /** Active store-wide discount banners. */
11
- banners: DiscountBanner[];
12
- /** True while the initial fetch is in flight. */
13
- loading: boolean;
14
- }
15
-
16
- /**
17
- * Homepage data: featured products + discount banners.
18
- * Pure data/behavior rendering lives in `ui/home/`.
19
- */
20
- export function useHomeData(): UseHomeDataResult {
21
- const [products, setProducts] = useState<Product[]>([]);
22
- const [banners, setBanners] = useState<DiscountBanner[]>([]);
23
- const [loading, setLoading] = useState(true);
24
-
25
- useEffect(() => {
26
- async function load() {
27
- try {
28
- const client = getClient();
29
- const [productsRes, bannersRes] = await Promise.allSettled([
30
- client.getProducts({ limit: 8, sortBy: 'createdAt', sortOrder: 'desc' }),
31
- client.getDiscountBanners(),
32
- ]);
33
-
34
- if (productsRes.status === 'fulfilled') {
35
- setProducts(productsRes.value.data);
36
- }
37
- if (bannersRes.status === 'fulfilled') {
38
- setBanners(bannersRes.value);
39
- }
40
- } catch (err) {
41
- console.error('Failed to load home page data:', err);
42
- } finally {
43
- setLoading(false);
44
- }
45
- }
46
-
47
- load();
48
- }, []);
49
-
50
- return { products, banners, loading };
51
- }
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import type { Product } from 'brainerce';
5
+ import { getClient } from '@/core/lib/brainerce';
6
+ import { useRegion } from '@/core/providers/store-provider';
7
+
8
+ export interface UseHomeDataResult {
9
+ /** Newest products for the featured grid (max 8). */
10
+ products: Product[];
11
+ /** True while the initial fetch is in flight. */
12
+ loading: boolean;
13
+ }
14
+
15
+ /**
16
+ * Homepage data: the featured product grid.
17
+ *
18
+ * Discount banners are deliberately NOT fetched here. They render below the
19
+ * header on every page, so the root layout fetches them server-side and hands
20
+ * them to `<DiscountBannerStrip>`. Fetching them again on the home page would
21
+ * be a duplicate request and a second, later-arriving copy of the same strip.
22
+ *
23
+ * Pure data/behavior — rendering lives in `ui/home/`.
24
+ */
25
+ export function useHomeData(): UseHomeDataResult {
26
+ const [products, setProducts] = useState<Product[]>([]);
27
+ const [loading, setLoading] = useState(true);
28
+ // Every product read carries the region, or the featured grid quotes the
29
+ // default region's currency to a shopper the product page then prices
30
+ // differently. `undefined` on a store with no regions, and the SDK omits
31
+ // the param, so a single-region store behaves exactly as before.
32
+ const { regionId } = useRegion();
33
+
34
+ useEffect(() => {
35
+ async function load() {
36
+ try {
37
+ const client = getClient();
38
+ const [productsRes] = await Promise.allSettled([
39
+ client.getProducts({
40
+ limit: 8,
41
+ sortBy: 'createdAt',
42
+ sortOrder: 'desc',
43
+ ...(regionId ? { regionId } : {}),
44
+ }),
45
+ ]);
46
+
47
+ if (productsRes.status === 'fulfilled') {
48
+ setProducts(productsRes.value.data);
49
+ }
50
+ } catch (err) {
51
+ console.error('Failed to load home page data:', err);
52
+ } finally {
53
+ setLoading(false);
54
+ }
55
+ }
56
+
57
+ load();
58
+ // Re-runs when the shopper switches region, so the grid re-prices instead
59
+ // of keeping the currency it was first rendered with.
60
+ }, [regionId]);
61
+
62
+ return { products, loading };
63
+ }