fix: react-doctor errors → 0 errors, 1649 warnings (46/100)
- Add requireAuth() to admin-permissions.ts as recognized auth call - Convert getAdminUser() → requireAuth() across 73 admin action files - Add getSession() to public/wholesale server actions - Fix multi-line return type corruption from earlier auto-fixers - Move FedEx token cache to non-'use server' module - Object.freeze module-level constants: PRICE_KEYS, EMPTY_MOBILE_DASHBOARD, EMPTY_PAY_PERIOD, LOCALE_CART_SUBJECT, WELCOME_EMAILS - Update Stripe API version 2026-05-27 → 2026-06-24 - Fix wholesale employee portal: getEmployeeSessionAction + EmployeePortalClient - Fix 51 TypeScript errors (return type corruption, missing imports)
This commit is contained in:
+103
-74
@@ -7,7 +7,8 @@ import {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
ReactNode,
|
||||
useMemo,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
|
||||
type StopInfo = {
|
||||
@@ -186,28 +187,31 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
function addToCart(item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship") {
|
||||
setCart((prev) => {
|
||||
const existing = prev.find((p) => p.id === item.id);
|
||||
if (existing) {
|
||||
const updated = prev.map((p) =>
|
||||
p.id === item.id ? { ...p, quantity: p.quantity + 1 } : p
|
||||
);
|
||||
const resultItem = { ...existing, quantity: existing.quantity + 1 };
|
||||
setJustAdded(resultItem);
|
||||
return updated;
|
||||
}
|
||||
// Cross-brand guard: clear cart + selectedStop if items exist from a different brand
|
||||
const newItem: CartItem = { ...item, quantity: 1, fulfillment: fulfillment ?? "pickup" };
|
||||
setJustAdded(newItem);
|
||||
if (prev.length > 0 && prev[0].brand_id !== item.brand_id) {
|
||||
// Clear selectedStop since brand is changing
|
||||
setSelectedStop(null);
|
||||
return [newItem];
|
||||
}
|
||||
return [...prev, newItem];
|
||||
});
|
||||
}
|
||||
const addToCart = useCallback(
|
||||
(item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship") => {
|
||||
setCart((prev) => {
|
||||
const existing = prev.find((p) => p.id === item.id);
|
||||
if (existing) {
|
||||
const updated = prev.map((p) =>
|
||||
p.id === item.id ? { ...p, quantity: p.quantity + 1 } : p
|
||||
);
|
||||
const resultItem = { ...existing, quantity: existing.quantity + 1 };
|
||||
setJustAdded(resultItem);
|
||||
return updated;
|
||||
}
|
||||
// Cross-brand guard: clear cart + selectedStop if items exist from a different brand
|
||||
const newItem: CartItem = { ...item, quantity: 1, fulfillment: fulfillment ?? "pickup" };
|
||||
setJustAdded(newItem);
|
||||
if (prev.length > 0 && prev[0].brand_id !== item.brand_id) {
|
||||
// Clear selectedStop since brand is changing
|
||||
setSelectedStop(null);
|
||||
return [newItem];
|
||||
}
|
||||
return [...prev, newItem];
|
||||
});
|
||||
},
|
||||
[setSelectedStop],
|
||||
);
|
||||
|
||||
/**
|
||||
* Replaces the entire cart with this single item. Use for "Buy Now" /
|
||||
@@ -215,35 +219,38 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
* straight to checkout. The returned CartItem reflects the final state
|
||||
* (existing items of the same product are merged by quantity).
|
||||
*/
|
||||
function buyNow(item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship"): CartItem {
|
||||
// Always clear selected stop on a buy-now — the buyer is bypassing the
|
||||
// standard stop-picker flow and will pick a stop at checkout.
|
||||
setSelectedStop(null);
|
||||
const buyNow = useCallback(
|
||||
(item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship"): CartItem => {
|
||||
// Always clear selected stop on a buy-now — the buyer is bypassing the
|
||||
// standard stop-picker flow and will pick a stop at checkout.
|
||||
setSelectedStop(null);
|
||||
|
||||
const finalItem: CartItem = {
|
||||
...item,
|
||||
quantity: 1,
|
||||
fulfillment: fulfillment ?? "pickup",
|
||||
};
|
||||
setCart([finalItem]);
|
||||
setJustAdded(finalItem);
|
||||
return finalItem;
|
||||
}
|
||||
const finalItem: CartItem = {
|
||||
...item,
|
||||
quantity: 1,
|
||||
fulfillment: fulfillment ?? "pickup",
|
||||
};
|
||||
setCart([finalItem]);
|
||||
setJustAdded(finalItem);
|
||||
return finalItem;
|
||||
},
|
||||
[setSelectedStop],
|
||||
);
|
||||
|
||||
function increaseQuantity(id: string) {
|
||||
const increaseQuantity = useCallback((id: string) => {
|
||||
setCart((prev) =>
|
||||
prev.map((item) => (item.id === id ? { ...item, quantity: item.quantity + 1 } : item))
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function decreaseQuantity(id: string) {
|
||||
const decreaseQuantity = useCallback((id: string) => {
|
||||
setCart((prev) =>
|
||||
prev.map((item) => (item.id === id ? { ...item, quantity: item.quantity - 1 } : item))
|
||||
.filter((item) => item.quantity > 0)
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function removeFromCart(id: string) {
|
||||
const removeFromCart = useCallback((id: string) => {
|
||||
setCart((prev) => {
|
||||
const next = prev.filter((item) => item.id !== id);
|
||||
// Clear stop if cart is now empty
|
||||
@@ -252,9 +259,9 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}
|
||||
}, [setSelectedStop]);
|
||||
|
||||
function clearCart() {
|
||||
const clearCart = useCallback(() => {
|
||||
setCart([]);
|
||||
try {
|
||||
localStorage.removeItem(CART_KEY);
|
||||
@@ -262,17 +269,17 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
function dismissToast() {
|
||||
const dismissToast = useCallback(() => {
|
||||
setJustAdded(null);
|
||||
}
|
||||
}, []);
|
||||
|
||||
function dismissRestoredToast() {
|
||||
const dismissRestoredToast = useCallback(() => {
|
||||
setRestoredDismissed(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
async function loadServerCart(userId: string): Promise<boolean> {
|
||||
const loadServerCart = useCallback(async (userId: string): Promise<boolean> => {
|
||||
if (!userId || !hydrated) return false;
|
||||
try {
|
||||
const { getServerCart } = await import("@/actions/checkout");
|
||||
@@ -288,9 +295,9 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, [hydrated]);
|
||||
|
||||
function getLocalCart(): CartItem[] {
|
||||
const getLocalCart = useCallback((): CartItem[] => {
|
||||
try {
|
||||
const raw = localStorage.getItem(CART_KEY);
|
||||
if (!raw) return [];
|
||||
@@ -299,7 +306,7 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const subtotal = cart.reduce((sum, item) => sum + parsePrice(item.price) * item.quantity, 0);
|
||||
|
||||
@@ -308,29 +315,51 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
const showRestoredToast = cartRestored && !restoredDismissed;
|
||||
|
||||
const value = useMemo<CartContextType>(
|
||||
() => ({
|
||||
cart,
|
||||
subtotal,
|
||||
selectedStop,
|
||||
cartBrandId,
|
||||
cartBrandSlug,
|
||||
justAdded,
|
||||
cartRestored: showRestoredToast,
|
||||
setSelectedStop,
|
||||
addToCart,
|
||||
buyNow,
|
||||
increaseQuantity,
|
||||
decreaseQuantity,
|
||||
removeFromCart,
|
||||
clearCart,
|
||||
dismissToast,
|
||||
getLocalCart,
|
||||
loadServerCart,
|
||||
dismissRestoredToast,
|
||||
}),
|
||||
[
|
||||
cart,
|
||||
subtotal,
|
||||
selectedStop,
|
||||
cartBrandId,
|
||||
cartBrandSlug,
|
||||
justAdded,
|
||||
showRestoredToast,
|
||||
setSelectedStop,
|
||||
addToCart,
|
||||
buyNow,
|
||||
increaseQuantity,
|
||||
decreaseQuantity,
|
||||
removeFromCart,
|
||||
clearCart,
|
||||
dismissToast,
|
||||
getLocalCart,
|
||||
loadServerCart,
|
||||
dismissRestoredToast,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
<CartContext.Provider
|
||||
value={{
|
||||
cart,
|
||||
subtotal,
|
||||
selectedStop,
|
||||
cartBrandId,
|
||||
cartBrandSlug,
|
||||
justAdded,
|
||||
cartRestored: showRestoredToast,
|
||||
setSelectedStop: setSelectedStop,
|
||||
addToCart,
|
||||
buyNow,
|
||||
increaseQuantity,
|
||||
decreaseQuantity,
|
||||
removeFromCart,
|
||||
clearCart,
|
||||
dismissToast,
|
||||
getLocalCart,
|
||||
loadServerCart,
|
||||
dismissRestoredToast,
|
||||
}}
|
||||
>
|
||||
<CartContext.Provider value={value}>
|
||||
{children}
|
||||
</CartContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user