create-brainerce-store 1.18.0 → 1.20.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 (67) hide show
  1. package/LICENSE +0 -0
  2. package/dist/index.js +31 -9
  3. package/messages/en.json +366 -362
  4. package/messages/he.json +366 -362
  5. package/package.json +8 -8
  6. package/templates/nextjs/base/next.config.ts +31 -31
  7. package/templates/nextjs/base/scripts/fetch-store-info.mjs +81 -81
  8. package/templates/nextjs/base/src/app/.well-known/apple-developer-merchantid-domain-association/route.ts +26 -26
  9. package/templates/nextjs/base/src/app/account/layout.tsx +9 -9
  10. package/templates/nextjs/base/src/app/account/page.tsx +122 -122
  11. package/templates/nextjs/base/src/app/api/auth/logout/route.ts +14 -14
  12. package/templates/nextjs/base/src/app/api/auth/me/route.ts +56 -56
  13. package/templates/nextjs/base/src/app/api/auth/oauth-callback/route.ts +59 -59
  14. package/templates/nextjs/base/src/app/api/auth/reset-callback/route.ts +41 -41
  15. package/templates/nextjs/base/src/app/api/auth/reset-password/route.ts +77 -77
  16. package/templates/nextjs/base/src/app/api/store/[...path]/route.ts +198 -198
  17. package/templates/nextjs/base/src/app/auth/callback/page.tsx +92 -92
  18. package/templates/nextjs/base/src/app/cart/layout.tsx +9 -9
  19. package/templates/nextjs/base/src/app/cart/page.tsx +204 -204
  20. package/templates/nextjs/base/src/app/checkout/layout.tsx +9 -9
  21. package/templates/nextjs/base/src/app/checkout/page.tsx +860 -860
  22. package/templates/nextjs/base/src/app/forgot-password/page.tsx +112 -112
  23. package/templates/nextjs/base/src/app/layout.tsx.ejs +75 -0
  24. package/templates/nextjs/base/src/app/login/layout.tsx +9 -9
  25. package/templates/nextjs/base/src/app/login/page.tsx +59 -59
  26. package/templates/nextjs/base/src/app/order-confirmation/layout.tsx +9 -9
  27. package/templates/nextjs/base/src/app/order-confirmation/page.tsx +17 -0
  28. package/templates/nextjs/base/src/app/payment-complete/page.tsx +59 -0
  29. package/templates/nextjs/base/src/app/products/[slug]/page.tsx +67 -67
  30. package/templates/nextjs/base/src/app/products/[slug]/product-client-section.tsx +486 -486
  31. package/templates/nextjs/base/src/app/products/layout.tsx +18 -18
  32. package/templates/nextjs/base/src/app/products/page.tsx +431 -431
  33. package/templates/nextjs/base/src/app/register/layout.tsx +9 -9
  34. package/templates/nextjs/base/src/app/register/page.tsx +65 -65
  35. package/templates/nextjs/base/src/app/reset-password/page.tsx +132 -132
  36. package/templates/nextjs/base/src/app/robots.ts +14 -14
  37. package/templates/nextjs/base/src/app/sitemap.ts +25 -25
  38. package/templates/nextjs/base/src/app/verify-email/page.tsx +258 -258
  39. package/templates/nextjs/base/src/components/account/address-book.tsx +432 -432
  40. package/templates/nextjs/base/src/components/account/order-history.tsx +350 -350
  41. package/templates/nextjs/base/src/components/auth/oauth-buttons.tsx +137 -137
  42. package/templates/nextjs/base/src/components/auth/register-form.tsx +232 -232
  43. package/templates/nextjs/base/src/components/cart/cart-bundle-offer.tsx +247 -111
  44. package/templates/nextjs/base/src/components/cart/cart-item.tsx +153 -153
  45. package/templates/nextjs/base/src/components/cart/cart-upgrade-banner.tsx +142 -142
  46. package/templates/nextjs/base/src/components/cart/free-shipping-bar.tsx +59 -59
  47. package/templates/nextjs/base/src/components/checkout/checkout-form.tsx +415 -415
  48. package/templates/nextjs/base/src/components/checkout/order-bump-card.tsx +243 -83
  49. package/templates/nextjs/base/src/components/checkout/payment-step.tsx +49 -3
  50. package/templates/nextjs/base/src/components/layout/footer.tsx +41 -41
  51. package/templates/nextjs/base/src/components/layout/header.tsx +336 -336
  52. package/templates/nextjs/base/src/components/layout/language-switcher.tsx.ejs +63 -0
  53. package/templates/nextjs/base/src/components/products/discount-badge.tsx +22 -22
  54. package/templates/nextjs/base/src/components/products/frequently-bought-together.tsx +202 -202
  55. package/templates/nextjs/base/src/components/products/product-card.tsx +218 -218
  56. package/templates/nextjs/base/src/components/products/recommendation-section.tsx +107 -107
  57. package/templates/nextjs/base/src/components/products/stock-badge.tsx +63 -63
  58. package/templates/nextjs/base/src/components/products/variant-selector.tsx +292 -292
  59. package/templates/nextjs/base/src/components/seo/product-json-ld.tsx +72 -72
  60. package/templates/nextjs/base/src/i18n.ts.ejs +21 -0
  61. package/templates/nextjs/base/src/lib/auth.ts +149 -149
  62. package/templates/nextjs/base/src/lib/brainerce.ts.ejs +9 -0
  63. package/templates/nextjs/base/src/lib/translations.ts.ejs +31 -0
  64. package/templates/nextjs/base/src/middleware.ts.ejs +81 -0
  65. package/templates/nextjs/base/src/providers/store-provider.tsx.ejs +41 -0
  66. package/templates/nextjs/base/src/lib/translations.ts +0 -11
  67. package/templates/nextjs/base/src/middleware.ts +0 -25
@@ -1,59 +1,59 @@
1
- 'use client';
2
-
3
- import { formatPrice } from 'brainerce';
4
- import { useStoreInfo, useCart } from '@/providers/store-provider';
5
- import { useTranslations } from '@/lib/translations';
6
- import { cn } from '@/lib/utils';
7
-
8
- interface FreeShippingBarProps {
9
- className?: string;
10
- }
11
-
12
- export function FreeShippingBar({ className }: FreeShippingBarProps) {
13
- const t = useTranslations('cart');
14
- const { storeInfo } = useStoreInfo();
15
- const { totals } = useCart();
16
-
17
- const upsell = storeInfo?.upsell;
18
- const threshold = upsell?.freeShippingThreshold;
19
- const enabled = upsell?.freeShippingBarEnabled !== false;
20
-
21
- // Don't render if disabled or no threshold configured
22
- if (!enabled || !threshold || threshold <= 0) return null;
23
-
24
- const subtotal = totals.subtotal;
25
- const remaining = Math.max(0, threshold - subtotal);
26
- const progress = Math.min(100, (subtotal / threshold) * 100);
27
- const qualified = remaining <= 0;
28
- const currency = storeInfo?.currency || 'USD';
29
-
30
- // Don't show if already qualified
31
- if (qualified) {
32
- return (
33
- <div className={cn('rounded-lg border border-green-200 bg-green-50 p-3', className)}>
34
- <div className="flex items-center gap-2 text-sm font-medium text-green-700">
35
- <svg className="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
36
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
37
- </svg>
38
- {t('freeShippingQualified')}
39
- </div>
40
- </div>
41
- );
42
- }
43
-
44
- return (
45
- <div className={cn('rounded-lg border border-amber-200 bg-amber-50 p-3', className)}>
46
- <p className="mb-2 text-sm text-amber-800">
47
- {t('freeShippingRemaining', {
48
- amount: formatPrice(remaining, { currency }) as string,
49
- })}
50
- </p>
51
- <div className="h-2 w-full overflow-hidden rounded-full bg-amber-200">
52
- <div
53
- className="h-full rounded-full bg-amber-500 transition-all duration-500 ease-out"
54
- style={{ width: `${progress}%` }}
55
- />
56
- </div>
57
- </div>
58
- );
59
- }
1
+ 'use client';
2
+
3
+ import { formatPrice } from 'brainerce';
4
+ import { useStoreInfo, useCart } from '@/providers/store-provider';
5
+ import { useTranslations } from '@/lib/translations';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ interface FreeShippingBarProps {
9
+ className?: string;
10
+ }
11
+
12
+ export function FreeShippingBar({ className }: FreeShippingBarProps) {
13
+ const t = useTranslations('cart');
14
+ const { storeInfo } = useStoreInfo();
15
+ const { totals } = useCart();
16
+
17
+ const upsell = storeInfo?.upsell;
18
+ const threshold = upsell?.freeShippingThreshold;
19
+ const enabled = upsell?.freeShippingBarEnabled !== false;
20
+
21
+ // Don't render if disabled or no threshold configured
22
+ if (!enabled || !threshold || threshold <= 0) return null;
23
+
24
+ const subtotal = totals.subtotal;
25
+ const remaining = Math.max(0, threshold - subtotal);
26
+ const progress = Math.min(100, (subtotal / threshold) * 100);
27
+ const qualified = remaining <= 0;
28
+ const currency = storeInfo?.currency || 'USD';
29
+
30
+ // Don't show if already qualified
31
+ if (qualified) {
32
+ return (
33
+ <div className={cn('rounded-lg border border-green-200 bg-green-50 p-3', className)}>
34
+ <div className="flex items-center gap-2 text-sm font-medium text-green-700">
35
+ <svg className="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
36
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
37
+ </svg>
38
+ {t('freeShippingQualified')}
39
+ </div>
40
+ </div>
41
+ );
42
+ }
43
+
44
+ return (
45
+ <div className={cn('rounded-lg border border-amber-200 bg-amber-50 p-3', className)}>
46
+ <p className="mb-2 text-sm text-amber-800">
47
+ {t('freeShippingRemaining', {
48
+ amount: formatPrice(remaining, { currency }) as string,
49
+ })}
50
+ </p>
51
+ <div className="h-2 w-full overflow-hidden rounded-full bg-amber-200">
52
+ <div
53
+ className="h-full rounded-full bg-amber-500 transition-all duration-500 ease-out"
54
+ style={{ width: `${progress}%` }}
55
+ />
56
+ </div>
57
+ </div>
58
+ );
59
+ }