This commit is contained in:
Nông Đức Huy
2026-08-13 23:20:23 +07:00
parent 1e356a2578
commit d9f159a8c3
84 changed files with 7992 additions and 180 deletions
@@ -16,6 +16,9 @@ interface CartState {
addLine: (variantId: string, quantity?: number) => Promise<boolean>;
setQuantity: (variantId: string, quantity: number) => Promise<void>;
removeLine: (variantId: string) => Promise<void>;
/** Resolves to the updated cart, or null if the request itself failed. */
applyCode: (code: string) => Promise<Cart | null>;
removeCode: (code: string) => Promise<void>;
refresh: () => Promise<void>;
}
@@ -55,6 +58,28 @@ export function CartProvider({ locale, children }: { locale: Locale; children: R
}, []);
/** Re-reads the bag after something outside this provider changed it. */
/**
* Like `run`, but hands the caller the cart it produced.
*
* A discount code needs this: the request succeeding and the code *applying*
* are different outcomes, and only the returned cart can tell them apart.
*/
const runReturning = useCallback(async (operation: () => Promise<Cart>): Promise<Cart | null> => {
setPending(true);
setError(null);
try {
const result = await operation();
setCart(result);
return result;
} catch (caught) {
setError(isApiClientError(caught) ? caught.message : 'Something went wrong.');
return null;
} finally {
setPending(false);
}
}, []);
const refresh = useCallback(async () => {
try {
setCart(await browserApi.commerce.getCart(locale));
@@ -103,9 +128,13 @@ export function CartProvider({ locale, children }: { locale: Locale; children: R
removeLine: async (variantId) => {
await run(() => browserApi.commerce.removeCartLine(locale, variantId));
},
applyCode: (code) => runReturning(() => browserApi.commerce.applyDiscountCode(locale, code)),
removeCode: async (code) => {
await run(() => browserApi.commerce.removeDiscountCode(locale, code));
},
refresh,
}),
[cart, loading, pending, error, locale, run, refresh],
[cart, loading, pending, error, locale, run, runReturning, refresh],
);
return <CartContext.Provider value={value}>{children}</CartContext.Provider>;