Files
WooNooW/customer-spa/src/lib/cart/api.ts
Dwindi Ramadhana 0f542ad452 feat: Multiple fixes and features
1. Add allow_custom_avatar toggle to Customer Settings
2. Implement coupon apply/remove in Cart and Checkout pages
3. Update Cart interface with coupons array and discount_total
4. Implement Downloads page to fetch from /account/downloads API
2026-01-04 20:03:33 +07:00

166 lines
3.8 KiB
TypeScript

import { Cart } from './store';
const getApiConfig = () => {
const apiRoot = (window as any).woonoowCustomer?.apiRoot || '/wp-json/woonoow/v1';
const nonce = (window as any).woonoowCustomer?.nonce || '';
return { apiRoot, nonce };
};
/**
* Update cart item quantity via API
*/
export async function updateCartItemQuantity(
cartItemKey: string,
quantity: number
): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
credentials: 'include',
body: JSON.stringify({
cart_item_key: cartItemKey,
quantity,
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || 'Failed to update cart');
}
const data = await response.json();
return data.cart;
}
/**
* Remove item from cart via API
*/
export async function removeCartItem(cartItemKey: string): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart/remove`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
credentials: 'include',
body: JSON.stringify({
cart_item_key: cartItemKey,
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || 'Failed to remove item');
}
const data = await response.json();
return data.cart;
}
/**
* Clear entire cart via API
*/
export async function clearCartAPI(): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart/clear`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
credentials: 'include',
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || 'Failed to clear cart');
}
const data = await response.json();
return data.cart;
}
/**
* Fetch current cart from API
*/
export async function fetchCart(): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart`, {
method: 'GET',
headers: {
'X-WP-Nonce': nonce,
},
credentials: 'include',
});
if (!response.ok) {
throw new Error('Failed to fetch cart');
}
const data = await response.json();
return data;
}
/**
* Apply coupon to cart via API
*/
export async function applyCoupon(couponCode: string): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart/apply-coupon`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
credentials: 'include',
body: JSON.stringify({
coupon_code: couponCode,
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || 'Failed to apply coupon');
}
const data = await response.json();
return data.cart;
}
/**
* Remove coupon from cart via API
*/
export async function removeCoupon(couponCode: string): Promise<Cart> {
const { apiRoot, nonce } = getApiConfig();
const response = await fetch(`${apiRoot}/cart/remove-coupon`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
credentials: 'include',
body: JSON.stringify({
coupon_code: couponCode,
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || 'Failed to remove coupon');
}
const data = await response.json();
return data.cart;
}