create-brainerce-store 1.0.0 → 1.1.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.
- package/dist/index.js +2 -2
- package/package.json +44 -44
- package/templates/nextjs/base/src/app/auth/callback/page.tsx +13 -24
- package/templates/nextjs/base/src/app/cart/page.tsx +16 -170
- package/templates/nextjs/base/src/app/checkout/page.tsx +477 -463
- package/templates/nextjs/base/src/components/auth/oauth-buttons.tsx +1 -1
- package/templates/nextjs/base/src/components/checkout/checkout-form.tsx +302 -273
- package/templates/nextjs/base/src/providers/store-provider.tsx.ejs +8 -30
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';
|
|
4
|
-
import type { StoreInfo, Cart
|
|
4
|
+
import type { StoreInfo, Cart } from 'brainerce';
|
|
5
5
|
import { getCartTotals } from 'brainerce';
|
|
6
6
|
import { getClient, initClient, getStoredToken, setStoredToken, setStoredCartId } from '@/lib/brainerce';
|
|
7
7
|
|
|
@@ -41,12 +41,11 @@ export function useAuth() {
|
|
|
41
41
|
|
|
42
42
|
// ---- Cart Context ----
|
|
43
43
|
interface CartContextValue {
|
|
44
|
-
cart: Cart |
|
|
44
|
+
cart: Cart | null;
|
|
45
45
|
cartLoading: boolean;
|
|
46
46
|
refreshCart: () => Promise<void>;
|
|
47
47
|
itemCount: number;
|
|
48
48
|
totals: { subtotal: number; discount: number; shipping: number; total: number };
|
|
49
|
-
isServerCart: (c: Cart | LocalCart | null) => c is Cart;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
const CartContext = createContext<CartContextValue>({
|
|
@@ -55,7 +54,6 @@ const CartContext = createContext<CartContextValue>({
|
|
|
55
54
|
refreshCart: async () => {},
|
|
56
55
|
itemCount: 0,
|
|
57
56
|
totals: { subtotal: 0, discount: 0, shipping: 0, total: 0 },
|
|
58
|
-
isServerCart: (_c): _c is Cart => false,
|
|
59
57
|
});
|
|
60
58
|
|
|
61
59
|
export function useCart() {
|
|
@@ -67,7 +65,7 @@ export function StoreProvider({ children }: { children: React.ReactNode }) {
|
|
|
67
65
|
const [storeInfo, setStoreInfo] = useState<StoreInfo | null>(null);
|
|
68
66
|
const [storeLoading, setStoreLoading] = useState(true);
|
|
69
67
|
const [token, setToken] = useState<string | null>(null);
|
|
70
|
-
const [cart, setCart] = useState<Cart |
|
|
68
|
+
const [cart, setCart] = useState<Cart | null>(null);
|
|
71
69
|
const [cartLoading, setCartLoading] = useState(true);
|
|
72
70
|
|
|
73
71
|
// Initialize client and auth
|
|
@@ -94,7 +92,7 @@ export function StoreProvider({ children }: { children: React.ReactNode }) {
|
|
|
94
92
|
setCart(c);
|
|
95
93
|
|
|
96
94
|
// Persist server cart ID
|
|
97
|
-
if (c &&
|
|
95
|
+
if (c && c.id) {
|
|
98
96
|
setStoredCartId(c.id);
|
|
99
97
|
}
|
|
100
98
|
} catch (err) {
|
|
@@ -114,51 +112,31 @@ export function StoreProvider({ children }: { children: React.ReactNode }) {
|
|
|
114
112
|
setStoredToken(newToken);
|
|
115
113
|
setToken(newToken);
|
|
116
114
|
|
|
117
|
-
//
|
|
115
|
+
// Merge guest session cart into customer cart
|
|
118
116
|
client.syncCartOnLogin().catch(console.error);
|
|
119
117
|
}, []);
|
|
120
118
|
|
|
121
119
|
const logout = useCallback(() => {
|
|
122
120
|
const client = getClient();
|
|
123
121
|
client.clearCustomerToken();
|
|
122
|
+
client.onLogout();
|
|
124
123
|
setStoredToken(null);
|
|
125
124
|
setToken(null);
|
|
126
125
|
setCart(null);
|
|
127
126
|
refreshCart();
|
|
128
127
|
}, [refreshCart]);
|
|
129
128
|
|
|
130
|
-
const isServerCart = (c: Cart | LocalCart | null): c is Cart => {
|
|
131
|
-
return c !== null && 'id' in c;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
129
|
const itemCount = cart
|
|
135
130
|
? cart.items.reduce((sum, item) => sum + item.quantity, 0)
|
|
136
131
|
: 0;
|
|
137
132
|
|
|
138
|
-
const totals =
|
|
139
|
-
? getCartTotals(cart)
|
|
140
|
-
: {
|
|
141
|
-
subtotal: cart
|
|
142
|
-
? cart.items.reduce(
|
|
143
|
-
(sum, item) => sum + parseFloat(String(item.price || '0')) * item.quantity,
|
|
144
|
-
0
|
|
145
|
-
)
|
|
146
|
-
: 0,
|
|
147
|
-
discount: 0,
|
|
148
|
-
shipping: 0,
|
|
149
|
-
total: cart
|
|
150
|
-
? cart.items.reduce(
|
|
151
|
-
(sum, item) => sum + parseFloat(String(item.price || '0')) * item.quantity,
|
|
152
|
-
0
|
|
153
|
-
)
|
|
154
|
-
: 0,
|
|
155
|
-
};
|
|
133
|
+
const totals = cart ? getCartTotals(cart) : { subtotal: 0, discount: 0, shipping: 0, total: 0 };
|
|
156
134
|
|
|
157
135
|
return (
|
|
158
136
|
<StoreInfoContext.Provider value={{ storeInfo, loading: storeLoading }}>
|
|
159
137
|
<AuthContext.Provider value={{ isLoggedIn: !!token, token, login, logout }}>
|
|
160
138
|
<CartContext.Provider
|
|
161
|
-
value={{ cart, cartLoading, refreshCart, itemCount, totals
|
|
139
|
+
value={{ cart, cartLoading, refreshCart, itemCount, totals }}
|
|
162
140
|
>
|
|
163
141
|
{children}
|
|
164
142
|
</CartContext.Provider>
|