summaryrefslogtreecommitdiff
path: root/src-migrate/modules/cart/components
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-06-11 14:00:19 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-06-11 14:00:19 +0700
commit65cc2af8ba7bf6ced66572cdec779bef8cace564 (patch)
tree4ca7e0ee59da9b61a2999d116bb8ab28ff675472 /src-migrate/modules/cart/components
parent54636b53685422d495adce95b491f7b10585cb5c (diff)
parent5669295b8cff1a9c9e559dd263599123a2ad6e92 (diff)
Merge branch 'new-release' of https://bitbucket.org/altafixco/next-indoteknik into biteship-merge
Diffstat (limited to 'src-migrate/modules/cart/components')
-rw-r--r--src-migrate/modules/cart/components/ItemAction.tsx65
-rw-r--r--src-migrate/modules/cart/components/ItemSelect.tsx22
-rw-r--r--src-migrate/modules/cart/components/Summary.tsx6
3 files changed, 54 insertions, 39 deletions
diff --git a/src-migrate/modules/cart/components/ItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx
index 4dcebd9e..b06e8e75 100644
--- a/src-migrate/modules/cart/components/ItemAction.tsx
+++ b/src-migrate/modules/cart/components/ItemAction.tsx
@@ -22,11 +22,11 @@ import {
import { toast } from 'react-hot-toast';
-type Props = {
+interface Props {
item: CartItem;
-};
+}
-const CartItemAction = ({ item }: Props) => {
+const CartItemAction: React.FC<Props> = ({ item }) => {
const auth = getAuth();
const { setRefreshCart } = useProductCartContext();
const [isLoadDelete, setIsLoadDelete] = useState<boolean>(false);
@@ -36,9 +36,9 @@ const CartItemAction = ({ item }: Props) => {
const { loadCart, cart, updateCartItem } = useCartStore();
- const limitQty = item.limit_qty?.transaction || 0;
+ const limitQty: number = item.limit_qty?.transaction || 0;
- const handleDelete = async () => {
+ const handleDelete = async (): Promise<void> => {
if (typeof auth !== 'object') return;
setIsLoadDelete(true);
@@ -80,25 +80,29 @@ const CartItemAction = ({ item }: Props) => {
}
};
- const updateQuantityInCookie = (productId, cartId, newQuantity) => {
+ const updateQuantityInCookie = (
+ productId: number,
+ cartId: string | number,
+ newQuantity: number
+ ): boolean => {
try {
- const cartData = getCartDataFromCookie();
+ const cartData = getCartDataFromCookie() as Record<string, any>;
let itemFound = false;
+ const cartIdString = String(cartId);
// Find item by cart_id key or search within objects
- if (cartData[cartId]) {
- cartData[cartId].quantity = newQuantity;
+ if (cartData[cartIdString]) {
+ cartData[cartIdString].quantity = newQuantity;
itemFound = true;
} else {
// Search by product id or cart_id within objects
- for (const key in cartData) {
+ Object.keys(cartData).forEach((key) => {
const item = cartData[key];
- if (item.id === productId || item.cart_id === cartId) {
+ if (item.id === productId || String(item.cart_id) === cartIdString) {
item.quantity = newQuantity;
itemFound = true;
- break;
}
- }
+ });
}
if (itemFound) {
@@ -113,12 +117,12 @@ const CartItemAction = ({ item }: Props) => {
}
};
- const decreaseQty = () => {
- setQuantity((quantity) => (quantity -= 1));
+ const decreaseQty = (): void => {
+ setQuantity((prevQuantity) => prevQuantity - 1);
};
- const increaseQty = () => {
- setQuantity((quantity) => (quantity += 1));
+ const increaseQty = (): void => {
+ setQuantity((prevQuantity) => prevQuantity + 1);
};
const debounceQty = useDebounce(quantity, 1000);
@@ -129,7 +133,7 @@ const CartItemAction = ({ item }: Props) => {
}, [debounceQty, limitQty]);
useEffect(() => {
- const updateCart = async () => {
+ const updateCart = async (): Promise<void> => {
if (typeof auth !== 'object' || isNaN(debounceQty)) return;
if (debounceQty === item.quantity) return;
@@ -167,20 +171,22 @@ const CartItemAction = ({ item }: Props) => {
await loadCart(auth.id);
// Re-update cookie if server reload overwrote it
- const currentCookieData = getCartDataFromCookie();
+ const currentCookieData = getCartDataFromCookie() as Record<
+ string,
+ any
+ >;
let needsReUpdate = false;
- for (const key in currentCookieData) {
+ Object.keys(currentCookieData).forEach((key) => {
const cookieItem = currentCookieData[key];
if (
(cookieItem.id === item.id ||
- cookieItem.cart_id === item.cart_id) &&
+ String(cookieItem.cart_id) === String(item.cart_id)) &&
cookieItem.quantity !== debounceQty
) {
needsReUpdate = true;
- break;
}
- }
+ });
if (needsReUpdate) {
updateQuantityInCookie(item.id, item.cart_id, debounceQty);
@@ -202,6 +208,13 @@ const CartItemAction = ({ item }: Props) => {
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [debounceQty]);
+ const handleQuantityInputChange = (
+ e: React.ChangeEvent<HTMLInputElement>
+ ): void => {
+ const value = parseInt(e.target.value);
+ setQuantity(isNaN(value) ? 1 : value);
+ };
+
return (
<div className={style.actionSection}>
<button
@@ -230,8 +243,8 @@ const CartItemAction = ({ item }: Props) => {
<input
type='number'
- className={style.quantity.toString()}
- onChange={(e) => setQuantity(parseInt(e.target.value))}
+ className={style.quantity}
+ onChange={handleQuantityInputChange}
value={quantity}
/>
@@ -249,4 +262,4 @@ const CartItemAction = ({ item }: Props) => {
);
};
-export default CartItemAction; \ No newline at end of file
+export default CartItemAction;
diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx
index 72ab49aa..f95ee36c 100644
--- a/src-migrate/modules/cart/components/ItemSelect.tsx
+++ b/src-migrate/modules/cart/components/ItemSelect.tsx
@@ -11,11 +11,11 @@ import {
checkboxUpdateState,
} from '~/utils/cart';
-type Props = {
+interface Props {
item: CartItem;
-};
+}
-const CartItemSelect = ({ item }: Props) => {
+const CartItemSelect: React.FC<Props> = ({ item }) => {
const auth = getAuth();
const { updateCartItem, cart, loadCart } = useCartStore();
const [isUpdating, setIsUpdating] = useState<boolean>(false);
@@ -23,7 +23,7 @@ const CartItemSelect = ({ item }: Props) => {
// Subscribe to global checkbox update state
useEffect(() => {
- const handleUpdateStateChange = (isUpdating) => {
+ const handleUpdateStateChange = (isUpdating: boolean): void => {
// This component doesn't need to react to global state changes
// Individual checkboxes are managed independently
};
@@ -36,7 +36,10 @@ const CartItemSelect = ({ item }: Props) => {
useEffect(() => {
if (isUpdating) return;
- const selectedItems = getSelectedItemsFromCookie();
+ const selectedItems = getSelectedItemsFromCookie() as Record<
+ number,
+ boolean
+ >;
const storedState = selectedItems[item.id];
if (storedState !== undefined) {
@@ -62,7 +65,7 @@ const CartItemSelect = ({ item }: Props) => {
}, [item.id, item.selected, localSelected, cart, updateCartItem, isUpdating]);
const handleChange = useCallback(
- async (e: React.ChangeEvent<HTMLInputElement>) => {
+ async (e: React.ChangeEvent<HTMLInputElement>): Promise<void> => {
if (typeof auth !== 'object' || !cart || isUpdating) return;
const newSelectedState = e.target.checked;
@@ -70,7 +73,7 @@ const CartItemSelect = ({ item }: Props) => {
// Update local state immediately
setLocalSelected(newSelectedState);
setIsUpdating(true);
- checkboxUpdateState.startUpdate(item.id);
+ checkboxUpdateState.startUpdate();
try {
// Update cookie immediately for responsive UI
@@ -107,14 +110,13 @@ const CartItemSelect = ({ item }: Props) => {
loadCart(auth.id);
} finally {
setIsUpdating(false);
- checkboxUpdateState.endUpdate(item.id);
+ checkboxUpdateState.endUpdate();
}
},
[auth, cart, item, isUpdating, updateCartItem, loadCart]
);
- const isDisabled =
- isUpdating || checkboxUpdateState.isCheckboxUpdating(item.id);
+ const isDisabled: boolean = isUpdating;
return (
<div className='w-6 my-auto relative'>
diff --git a/src-migrate/modules/cart/components/Summary.tsx b/src-migrate/modules/cart/components/Summary.tsx
index 68db6323..312160fb 100644
--- a/src-migrate/modules/cart/components/Summary.tsx
+++ b/src-migrate/modules/cart/components/Summary.tsx
@@ -197,12 +197,12 @@ const CartSummary = ({
<div className={style.divider} />
- <Skeleton isLoaded={isLoaded}>
+ <Skeleton isLoaded={isLoaded} className={style.line}>
<span className={clsxm(style.label, style.grandTotal)}>
Grand Total
</span>
- <span className={clsxm(style.value, style.grandTotalValue)}>
- Rp {formatCurrency(displayGrandTotal)}
+ <span className={style.value}>
+ Rp {formatCurrency(grandTotal || 0)}
</span>
</Skeleton>
</div>